Compare commits

...

1 Commits

Author SHA1 Message Date
Jan Nicklas 7e1af7b89c Add `__entry` and `__entryPath` to the global template variables 2016-09-09 15:05:38 +02:00
5 changed files with 87 additions and 27 deletions

View File

@ -204,6 +204,14 @@ HtmlWebpackPlugin.prototype.apply = function (compiler) {
}); });
}; };
/**
* Resolves a request to a real file path
*/
HtmlWebpackPlugin.prototype.getResolvedFilename = function (request, compiler) {
var requestWithoutLoaders = this.options.template.replace(/^.+!/, '').replace(/\?.+$/, '');
return Promise.promisify(compiler.resolvers.normal.resolve)(compiler.context, requestWithoutLoaders);
};
/** /**
* Evaluates the child compilation result * Evaluates the child compilation result
* Returns a promise * Returns a promise
@ -212,23 +220,32 @@ HtmlWebpackPlugin.prototype.evaluateCompilationResult = function (compilation, s
if (!source) { if (!source) {
return Promise.reject('The child compilation didn\'t provide a result'); return Promise.reject('The child compilation didn\'t provide a result');
} }
return this.getResolvedFilename(this.options.template, compilation.compiler)
.then(function (templatePath) {
// The LibraryTemplatePlugin stores the template result in a local variable.
// To extract the result during the evaluation this part has to be removed.
source = source.replace('var HTML_WEBPACK_PLUGIN_RESULT =', '');
// The LibraryTemplatePlugin stores the template result in a local variable. var vmContext = vm.createContext(_.extend({
// To extract the result during the evaluation this part has to be removed. HTML_WEBPACK_PLUGIN: true,
source = source.replace('var HTML_WEBPACK_PLUGIN_RESULT =', ''); require: require,
var template = this.options.template.replace(/^.+!/, '').replace(/\?.+$/, ''); __entry: templatePath,
var vmContext = vm.createContext(_.extend({HTML_WEBPACK_PLUGIN: true, require: require}, global)); __entryPath: path.dirname(templatePath)
var vmScript = new vm.Script(source, {filename: template}); }, global));
// Evaluate code and cast to string
var newSource; var vmScript = new vm.Script(source, {filename: path.basename(templatePath)});
try { // Evaluate code and cast to string
newSource = vmScript.runInContext(vmContext); var newSource;
} catch (e) { try {
return Promise.reject(e); newSource = vmScript.runInContext(vmContext);
} } catch (templateEvaluationError) {
return typeof newSource === 'string' || typeof newSource === 'function' return Promise.reject(templateEvaluationError);
? Promise.resolve(newSource) }
: Promise.reject('The loader "' + this.options.template + '" didn\'t return html.'); // Verify that the template result is a template function or a template string
return typeof newSource === 'string' || typeof newSource === 'function'
? Promise.resolve(newSource)
: Promise.reject('The loader "' + this.options.template + '" didn\'t return html.');
});
}; };
/** /**

View File

@ -13,6 +13,7 @@ var NodeTargetPlugin = require('webpack/lib/node/NodeTargetPlugin');
var LoaderTargetPlugin = require('webpack/lib/LoaderTargetPlugin'); var LoaderTargetPlugin = require('webpack/lib/LoaderTargetPlugin');
var LibraryTemplatePlugin = require('webpack/lib/LibraryTemplatePlugin'); var LibraryTemplatePlugin = require('webpack/lib/LibraryTemplatePlugin');
var SingleEntryPlugin = require('webpack/lib/SingleEntryPlugin'); var SingleEntryPlugin = require('webpack/lib/SingleEntryPlugin');
var NodeStuffPlugin = require('webpack/lib/NodeStuffPlugin');
/** /**
* Compiles the template into a nodejs factory, adds its to the compilation.assets * Compiles the template into a nodejs factory, adds its to the compilation.assets
@ -46,11 +47,15 @@ module.exports.compileTemplate = function compileTemplate (template, context, ou
var childCompiler = compilation.createChildCompiler(compilerName, outputOptions); var childCompiler = compilation.createChildCompiler(compilerName, outputOptions);
childCompiler.context = context; childCompiler.context = context;
childCompiler.apply( childCompiler.apply(
new NodeTemplatePlugin(outputOptions),
new NodeTargetPlugin(),
new LibraryTemplatePlugin('HTML_WEBPACK_PLUGIN_RESULT', 'var'), new LibraryTemplatePlugin('HTML_WEBPACK_PLUGIN_RESULT', 'var'),
new SingleEntryPlugin(this.context, template), new SingleEntryPlugin(this.context, template),
new LoaderTargetPlugin('node') new NodeTemplatePlugin(outputOptions),
new NodeTargetPlugin(),
new LoaderTargetPlugin('node'),
new NodeStuffPlugin({
__dirname: false,
__filename: false
})
); );
// Fix for "Uncaught TypeError: __webpack_require__(...) is not a function" // Fix for "Uncaught TypeError: __webpack_require__(...) is not a function"

View File

@ -12,7 +12,7 @@
"prepublish": "npm run test", "prepublish": "npm run test",
"pretest": "semistandard", "pretest": "semistandard",
"build-examples": "node examples/build-examples.js", "build-examples": "node examples/build-examples.js",
"test": "jasmine" "test": "jasmine --verbose --captureExceptions"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
@ -37,28 +37,29 @@
}, },
"devDependencies": { "devDependencies": {
"appcache-webpack-plugin": "^1.3.0", "appcache-webpack-plugin": "^1.3.0",
"css-loader": "^0.23.1", "css-loader": "^0.25.0",
"dir-compare": "1.0.1", "dir-compare": "1.1.0",
"es6-promise": "^3.2.1", "es6-promise": "^3.2.1",
"extract-text-webpack-plugin": "^1.0.1", "extract-text-webpack-plugin": "^1.0.1",
"file-loader": "^0.9.0", "file-loader": "^0.9.0",
"html-loader": "^0.4.3", "html-loader": "^0.4.3",
"jade": "^1.11.0", "jade": "^1.11.0",
"jade-loader": "^0.8.0", "jade-loader": "^0.8.0",
"jasmine": "^2.4.1", "jasmine": "^2.5.1",
"jasmine-console-reporter": "^1.2.7",
"rimraf": "^2.5.4", "rimraf": "^2.5.4",
"semistandard": "^8.0.0", "semistandard": "^8.0.0",
"style-loader": "^0.13.1", "style-loader": "^0.13.1",
"underscore-template-loader": "^0.7.3", "underscore-template-loader": "^0.7.3",
"url-loader": "^0.5.7", "url-loader": "^0.5.7",
"webpack": "^1.13.1", "webpack": "^1.13.2",
"webpack-recompilation-simulator": "^1.3.0" "webpack-recompilation-simulator": "^1.3.0"
}, },
"dependencies": { "dependencies": {
"bluebird": "^3.4.1", "bluebird": "^3.4.6",
"html-minifier": "^3.0.2", "html-minifier": "^3.0.2",
"loader-utils": "^0.2.15", "loader-utils": "^0.2.15",
"lodash": "^4.14.2", "lodash": "^4.15.0",
"pretty-error": "^2.0.0", "pretty-error": "^2.0.0",
"toposort": "^1.0.0" "toposort": "^1.0.0"
}, },

View File

@ -21,6 +21,14 @@ var HtmlWebpackPlugin = require('../index.js');
var OUTPUT_DIR = path.join(__dirname, '../dist'); var OUTPUT_DIR = path.join(__dirname, '../dist');
jasmine.getEnv().defaultTimeoutInterval = 30000; jasmine.getEnv().defaultTimeoutInterval = 30000;
var JasmineConsoleReporter = require('jasmine-console-reporter');
jasmine.getEnv().addReporter(new JasmineConsoleReporter({
colors: 1,
cleanStack: 1,
verbosity: 4,
listStyle: 'indent',
activity: false
}));
function testHtmlPlugin (webpackConfig, expectedResults, outputFile, done, expectErrors, expectWarnings) { function testHtmlPlugin (webpackConfig, expectedResults, outputFile, done, expectErrors, expectWarnings) {
outputFile = outputFile || 'index.html'; outputFile = outputFile || 'index.html';
@ -1114,7 +1122,7 @@ describe('HtmlWebpackPlugin', function () {
template: path.join(__dirname, 'fixtures/non-existing-template.html') template: path.join(__dirname, 'fixtures/non-existing-template.html')
}) })
] ]
}, ['Child compilation failed:\n Entry module not found:'], null, done, true); }, ['Error: Cannot resolve'], null, done, true);
}); });
it('should sort the chunks in auto mode', function (done) { it('should sort the chunks in auto mode', function (done) {
@ -1240,6 +1248,28 @@ describe('HtmlWebpackPlugin', function () {
}, ['templateParams.compilation exists: true'], null, done); }, ['templateParams.compilation exists: true'], null, done);
}); });
it('should provide globals to the template compilation', function (done) {
var template = path.resolve(__dirname, 'fixtures/templateGlobals.js');
var templatePath = path.dirname(template);
testHtmlPlugin({
entry: path.join(__dirname, 'fixtures/index.js'),
output: {
path: OUTPUT_DIR,
filename: 'index_bundle.js'
},
plugins: [
new HtmlWebpackPlugin({
template: template,
inject: false
})
]
}, [
'"__entry":"' + template + '"',
'"__entryPath":"' + templatePath + '"',
'"HTML_WEBPACK_PLUGIN":true'
], null, done);
});
it('should not treat templateContent set to an empty string as missing', function (done) { it('should not treat templateContent set to an empty string as missing', function (done) {
testHtmlPlugin({ testHtmlPlugin({
entry: {app: path.join(__dirname, 'fixtures/index.js')}, entry: {app: path.join(__dirname, 'fixtures/index.js')},

7
spec/fixtures/templateGlobals.js vendored Normal file
View File

@ -0,0 +1,7 @@
module.exports = function (templateParams) {
return JSON.stringify({
__entry: global.__entry,
__entryPath: global.__entryPath,
HTML_WEBPACK_PLUGIN: global.HTML_WEBPACK_PLUGIN
});
};