UNPKG

marko

Version:

UI Components + streaming, async, high performance, HTML templating for Node.js and the browser.

178 lines (143 loc) 4.39 kB
var nodePath = require("path"); var defaultResolveFrom = require("resolve-from"); var env = process.env.NODE_ENV; var production = !env || env !== "development"; function getRootDeps(template, context) { if (production && template.___depsArray) { return template.___depsArray; } attachDepsAndComponentsToTemplate(template, context); var deps = (template.___depsArray = Object.keys(template.___deps).map( (key) => template.___deps[key], )); var initModule = getInitModule(template.path, template.___components); if (initModule) deps.push(initModule); // these dependencies should be last deps.concat = function () { var result = []; result = result.concat.apply(result, arguments); result.push.apply(result, this); return result; }; return deps; } function attachDepsAndComponentsToTemplate(target, context) { var template; if (!target.meta && target.template) { template = target.template; } else { template = target; } if (typeof template.createOut !== "function") return; if (production && target.___deps) return; var deps = (target.___deps = {}); var components = (target.___components = {}); if (!template.meta) { console.warn("Metadata not set for template at ", template.path); return; } var meta = template.meta; var root = nodePath.dirname(template.path); if (meta.deps) { meta.deps.forEach((dep) => { dep = resolveDep(dep, root, context); deps[dep.virtualPath || dep.path] = dep; }); } if (meta.id && meta.component) { var resolveFrom = (context && context.resolveFrom) || defaultResolveFrom; components[meta.id] = { id: meta.id, path: resolveFrom(root, meta.component), }; } if (meta.tags) { meta.tags.forEach((tagPath) => { var resolveFrom = context.resolveFrom || defaultResolveFrom; var tag = resolveFrom(root, tagPath); var ext = nodePath.extname(tag); var req = context.require || require; try { tag = req.resolve(tag.slice(0, 0 - ext.length) + ".js"); } catch (e) { /* ignore error */ } tag = req(tag); attachDepsAndComponentsToTemplate(tag, context); if (tag.___deps) Object.assign(deps, tag.___deps); if (tag.___components) Object.assign(components, tag.___components); }); } } function getInitModule(path, components) { var module = null; if (components) { components = Object.keys(components).map((key) => components[key]); if (components.length) { var root = nodePath.dirname(path); var virtualPath = path + ".init.js"; var registrations = components.map( (component) => `components.register('${component.id}', require('.${ nodePath.sep }${nodePath.relative(root, component.path)}'));`, ); var code = ` var components = require('marko/components'); ${registrations.join("\n")} `; module = { type: "require", run: true, virtualModule: { path: virtualPath, read: function (_, callback) { // TODO: Check if read can just return string in lasso 2 if (callback) { callback(null, code); } else { return code; } }, }, }; } } return module; } function resolveDep(dep, root, context) { if (typeof dep === "string") { dep = parseDependencyString(dep); } if (dep.path) { var resolveFrom = (context && context.resolveFrom) || defaultResolveFrom; dep.path = resolveFrom(root, dep.path); if (dep.path && !dep.type) { dep.type = dep.path.slice(dep.path.lastIndexOf(".") + 1); } } if (dep.virtualPath) { dep.virtualPath = nodePath.resolve(root, dep.virtualPath); } if (dep.type === "js") { dep.type = "require"; dep.run = true; } return dep; } function parseDependencyString(string) { var match = /^(?:([\w-]+)(?::\s*|\s+))?(.*?(?:\.(\w+))?)$/.exec(string); return { type: match[1] || match[3], path: match[2], }; } function patch(Template) { Template.prototype.getDependencies = function (context) { context = context || {}; return getRootDeps(this, context); }; } exports.getDeps = getRootDeps; exports.resolveDep = resolveDep; exports.patch = patch;