Improved compilation for the browser and webpack compatibility

This commit is contained in:
Patrick Steele-Idem 2016-12-28 15:07:39 -07:00
parent b0d77b8cb0
commit 59559b211a
12 changed files with 172 additions and 6 deletions

View File

@ -510,9 +510,17 @@ class CompileContext extends EventEmitter {
var builder = this.builder;
varName = varName || removeExt(path.basename(relativePath)) + '_template';
var requireResolveTemplate = requireResolve(builder, builder.literal(relativePath));
var loadFunctionCall = builder.functionCall(this.helper('loadTemplate'), [ requireResolveTemplate ]);
var templateVar = this.addStaticVar(varName, loadFunctionCall);
var templateVar;
if (this.options.browser) {
// When compiling a Marko template for the browser we just use `require('./template.marko')`
templateVar = this.addStaticVar(varName, builder.require(builder.literal(relativePath)));
} else {
// When compiling a Marko template for the server we just use `loadTemplate(require.resolve('./template.marko'))`
let loadTemplateArg = requireResolve(builder, builder.literal(relativePath));
let loadFunctionCall = builder.functionCall(this.helper('loadTemplate'), [ loadTemplateArg ]);
templateVar = this.addStaticVar(varName, loadFunctionCall);
}
this.pushMeta('tags', builder.literal(relativePath), true);

View File

@ -106,7 +106,7 @@ function compileForBrowser(src, filename, options, callback) {
options = null;
}
options = extend({output: 'vdom'}, options);
options = extend({output: 'vdom', browser: true}, options);
return compile(src, filename, options, callback);
}
@ -139,7 +139,7 @@ function compileFileForBrowser(filename, options, callback) {
options = null;
}
options = extend({output: 'vdom'}, options);
options = extend({output: 'vdom', browser: true}, options);
return compileFile(filename, options, callback);
}

View File

@ -0,0 +1,14 @@
var marko_template = module.exports = require("marko/vdom").t(__filename),
include_target_template = require("./include-target.marko"),
marko_helpers = require("marko/runtime/vdom/helpers"),
marko_loadTag = marko_helpers.t,
include_tag = marko_loadTag(require("marko/taglibs/core/include-tag"));
function render(data, out) {
include_tag({
_target: include_target_template,
foo: "bar"
}, out);
}
marko_template._ = render;

View File

@ -0,0 +1 @@
<include('./include-target.marko') foo="bar"/>

View File

@ -0,0 +1,44 @@
var marko_template = module.exports = require("marko/vdom").t(__filename),
marko_helpers = require("marko/runtime/vdom/helpers"),
marko_forEach = marko_helpers.f,
marko_createElement = marko_helpers.e,
marko_const = marko_helpers.const,
marko_const_nextId = marko_const("6597f2"),
marko_node0 = marko_createElement("div", null, 1, marko_const_nextId())
.t("No colors!");
function render(data, out) {
out.t("Hello ");
out.t(data.name);
out.t("! ");
if (data.colors.length) {
out.be("ul");
marko_forEach(data.colors, function(color) {
out.e("li", null, 1)
.t(color);
});
out.ee();
} else {
out.n(marko_node0);
}
if (data.colors.length) {
out.be("ul");
marko_forEach(data.colors, function(color) {
out.e("li", null, 1)
.t(color);
});
out.ee();
} else {
out.n(marko_node0);
}
}
marko_template._ = render;

View File

@ -0,0 +1,27 @@
---
Hello ${data.name}!
<ul if(data.colors.length)>
<li for(color in data.colors)>
${color}
</li>
</ul>
<div else>
No colors!
</div>
<if(data.colors.length)>
<ul>
<for(color in data.colors)>
<li>
${color}
</li>
</for>
</ul>
</if>
<else>
<div>
No colors!
</div>
</else>
---

View File

@ -0,0 +1,52 @@
'use strict';
require('./util/patch-module');
var chai = require('chai');
chai.config.includeStack = true;
var path = require('path');
var compiler = require('../compiler');
var autotest = require('./autotest');
var fs = require('fs');
require('marko/node-require').install();
describe('compiler (browser target)', function() {
var autoTestDir = path.join(__dirname, 'autotests/compiler-browser');
autotest.scanDir(autoTestDir, function run(dir, helpers, done) {
var templatePath = path.join(dir, 'template.marko');
var mainPath = path.join(dir, 'test.js');
var main;
if (fs.existsSync(mainPath)) {
main = require(mainPath);
}
if (main && main.checkError) {
var e;
try {
compiler.compileFileForBrowser(templatePath);
} catch(_e) {
e = _e;
}
if (!e) {
throw new Error('Error expected');
}
main.checkError(e);
done();
} else if (main && main.checkTemplate) {
var template = require('marko').load(templatePath, main.compilerOptions);
main.checkTemplate(template);
done();
} else {
var compiledSrc = compiler.compileFileForBrowser(templatePath, main && main.compilerOptions);
helpers.compare(compiledSrc, '.js');
done();
}
});
});

View File

@ -6,5 +6,11 @@
"run": true,
"if": "!flags.contains('marko-widgets/no-client-init')"
}
],
"requireRemap": [
{
"from": "./loadWidget.js",
"to": "./loadWidget-dynamic.js"
}
]
}

View File

@ -0,0 +1,8 @@
'use strict';
module.exports = function load(typeName) {
// We make the assumption that the widget type name is a path to a
// fully resolved module path and that the module exists
// as a CommonJS module
return require(typeName);
};

4
widgets/loadWidget.js Normal file
View File

@ -0,0 +1,4 @@
'use strict';
module.exports = function load(typeName) {
throw new Error('Unable to load: ' + typeName);
};

View File

@ -1,3 +1,5 @@
var loadWidget = require('./loadWidget');
var registered = {};
var loaded = {};
var widgetTypes = {};
@ -27,7 +29,7 @@ function load(typeName) {
target = target();
}
if (!target) {
target = require(typeName); // Assume the typeName has been fully resolved already
target = loadWidget(typeName); // Assume the typeName has been fully resolved already
}
loaded[typeName] = target || null;
}