diff --git a/index.js b/index.js index 0543ec8..b023949 100644 --- a/index.js +++ b/index.js @@ -2,6 +2,7 @@ var RawSource = require('webpack-sources/lib/RawSource'); var evaluate = require('eval'); var path = require('path'); var Promise = require('bluebird'); +var vm = require('vm'); function StaticSiteGeneratorWebpackPlugin(renderSrc, outputPaths, locals, scope) { this.renderSrc = renderSrc; @@ -27,11 +28,12 @@ StaticSiteGeneratorWebpackPlugin.prototype.apply = function(compiler) { throw new Error('Source file not found: "' + self.renderSrc + '"'); } + var scope = loadChunkAssetsToScope(self.scope, compilation, webpackStatsJson); + var assets = getAssetsFromCompilation(compilation, webpackStatsJson); var source = asset.source(); - var render = evaluate(source, /* filename: */ self.renderSrc, /* scope: */ self.scope, /* includeGlobals: */ true); - + var render = evaluate(source, /* filename: */ self.renderSrc, /* scope: */ scope, /* includeGlobals: */ true); if (render.hasOwnProperty('default')) { render = render['default']; } @@ -81,6 +83,50 @@ StaticSiteGeneratorWebpackPlugin.prototype.apply = function(compiler) { }); }; +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 manifest = findAsset('manifest', compilation, webpackStatsJson); + var vendor = findAsset('vendor', compilation, webpackStatsJson); + + if (!manifest || !vendor) { + return scope; + } + + if(!scope) { + scope = {}; + } + + if (!scope.window) { + scope.window = {}; + } + + var sandbox = {}; + merge(sandbox, scope); + + var manifestScript = new vm.Script(manifest.source()); + manifestScript.runInNewContext(sandbox, {}); + + merge(sandbox, sandbox.window) + + var vendorScript = new vm.Script(vendor.source()); + vendorScript.runInNewContext(sandbox, {}); + + return sandbox.window; +} + var findAsset = function(src, compilation, webpackStatsJson) { var asset = compilation.assets[src]; 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..1eb4505 --- /dev/null +++ b/test/success-cases/commonschunk/webpack.config.js @@ -0,0 +1,35 @@ +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('index.js', paths, { template: template }), + new StatsWriterPlugin() // Causes the asset's `size` method to be called + ] +};