diff --git a/index.js b/index.js index 64eb468..03dc406 100644 --- a/index.js +++ b/index.js @@ -4,6 +4,7 @@ var path = require('path'); var cheerio = require('cheerio'); var url = require('url'); var Promise = require('bluebird'); +var vm = require('vm'); function StaticSiteGeneratorWebpackPlugin(options) { if (arguments.length > 1) { @@ -36,11 +37,12 @@ StaticSiteGeneratorWebpackPlugin.prototype.apply = function(compiler) { throw new Error('Source file not found: "' + self.entry + '"'); } + var scope = loadChunkAssetsToScope(self.globals, compilation, webpackStatsJson); + var assets = getAssetsFromCompilation(compilation, webpackStatsJson); var source = asset.source(); - var render = evaluate(source, /* filename: */ self.entry, /* scope: */ self.globals, /* includeGlobals: */ true); - + var render = evaluate(source, /* filename: */ self.entry, /* scope: */ scope, /* includeGlobals: */ true); if (render.hasOwnProperty('default')) { render = render['default']; } @@ -111,6 +113,47 @@ function renderPaths(crawl, userLocals, paths, render, assets, webpackStats, com return Promise.all(renderPromises); } +function merge (a, b) { + if (!a || !b) return a + var keys = Object.keys(b) + for (var k, i = 0, n = keys.length; i < n; i++) { + k = keys[i] + a[k] = b[k] + } + return a +} + +/* + * Function to handle commonschunk plugin. Currently only supports a manifest file and single external + * library file name vendor. + */ +var loadChunkAssetsToScope = function(scope, compilation, webpackStatsJson) { + var chunkNames = Object.keys(webpackStatsJson.assetsByChunkName) + var chunkValues = chunkNames.map(function(chunk) { + return findAsset(chunk, compilation, webpackStatsJson); + }); + + if(!scope) { + scope = {}; + } + + if (!scope.window) { + scope.window = {}; + } + + var sandbox = {}; + merge(sandbox, scope); + + // CommonChunksPlugin will place webpackJsonP manifest loading in last bundle + chunkValues.reverse().map(function(chunk) { + var script = new vm.Script(chunk.source()); + script.runInNewContext(sandbox, {}); + merge(sandbox, sandbox.window); + }); + + return sandbox; +} + var findAsset = function(src, compilation, webpackStatsJson) { if (!src) { var chunkNames = Object.keys(webpackStatsJson.assetsByChunkName); diff --git a/test/success-cases/commonschunk/expected-output/foo/bar/index.html b/test/success-cases/commonschunk/expected-output/foo/bar/index.html new file mode 100644 index 0000000..3f8345f --- /dev/null +++ b/test/success-cases/commonschunk/expected-output/foo/bar/index.html @@ -0,0 +1,5 @@ + + +

/foo/bar

+ + diff --git a/test/success-cases/commonschunk/expected-output/foo/index.html b/test/success-cases/commonschunk/expected-output/foo/index.html new file mode 100644 index 0000000..20d49db --- /dev/null +++ b/test/success-cases/commonschunk/expected-output/foo/index.html @@ -0,0 +1,5 @@ + + +

/foo

+ + diff --git a/test/success-cases/commonschunk/expected-output/index.html b/test/success-cases/commonschunk/expected-output/index.html new file mode 100644 index 0000000..21ba737 --- /dev/null +++ b/test/success-cases/commonschunk/expected-output/index.html @@ -0,0 +1,5 @@ + + +

/

+ + diff --git a/test/success-cases/commonschunk/index.js b/test/success-cases/commonschunk/index.js new file mode 100644 index 0000000..bba73ea --- /dev/null +++ b/test/success-cases/commonschunk/index.js @@ -0,0 +1,5 @@ +module.exports = function(locals, callback) { + setTimeout(function() { + callback(null, locals.template({ html: '

' + locals.path + '

' })); + }, 10); +}; diff --git a/test/success-cases/commonschunk/template.ejs b/test/success-cases/commonschunk/template.ejs new file mode 100644 index 0000000..d549dbf --- /dev/null +++ b/test/success-cases/commonschunk/template.ejs @@ -0,0 +1,5 @@ + + + <%- html %> + + diff --git a/test/success-cases/commonschunk/webpack.config.js b/test/success-cases/commonschunk/webpack.config.js new file mode 100644 index 0000000..98f8bad --- /dev/null +++ b/test/success-cases/commonschunk/webpack.config.js @@ -0,0 +1,41 @@ +var StaticSiteGeneratorPlugin = require('../../../'); +var StatsWriterPlugin = require("webpack-stats-plugin").StatsWriterPlugin; +var webpack = require('webpack'); +var ejs = require('ejs'); +var fs = require('fs'); + +var template = ejs.compile(fs.readFileSync(__dirname + '/template.ejs', 'utf-8')) + +var paths = [ + '/', + '/foo', + '/foo/bar' +]; + +module.exports = { + entry: { + index: __dirname + '/index.js', + vendor: 'bluebird' + }, + + output: { + filename: '[name].js', + path: __dirname + '/actual-output', + libraryTarget: 'umd' + }, + + plugins: [ + new webpack.optimize.CommonsChunkPlugin({ + names: ['vendor', 'manifest'], + minChunks: Infinity + }), + new StaticSiteGeneratorPlugin({ + entry: 'index', + paths: paths, + locals: { + template: template + } + }), + new StatsWriterPlugin() // Causes the asset's `size` method to be called + ] +};