UNPKG

webpack

Version:

Packs CommonJs/AMD modules for the browser. Allows to split your codebase into multiple bundles, which can be loaded on demand. Support loaders to preprocess files, i.e. json, jsx, es7, css, less, ... and your custom stuff.

136 lines (117 loc) 3.38 kB
/* MIT License http://www.opensource.org/licenses/mit-license.php Author Joel Denning @joeldenning */ "use strict"; const { ConcatSource } = require("webpack-sources"); const Template = require("./Template"); /** @typedef {import("./Compilation")} Compilation */ /** * @typedef {Object} SystemMainTemplatePluginOptions * @param {string=} name the library name */ class SystemMainTemplatePlugin { /** * @param {SystemMainTemplatePluginOptions} options the plugin options */ constructor(options) { this.name = options.name; } /** * @param {Compilation} compilation the compilation instance * @returns {void} */ apply(compilation) { const { mainTemplate, chunkTemplate } = compilation; const onRenderWithEntry = (source, chunk, hash) => { const externals = chunk.getModules().filter(m => m.external); // The name this bundle should be registered as with System const name = this.name ? `${JSON.stringify( mainTemplate.getAssetPath(this.name, { hash, chunk }) )}, ` : ""; // The array of dependencies that are external to webpack and will be provided by System const systemDependencies = JSON.stringify( externals.map(m => typeof m.request === "object" ? m.request.amd : m.request ) ); // The name of the variable provided by System for exporting const dynamicExport = "__WEBPACK_DYNAMIC_EXPORT__"; // An array of the internal variable names for the webpack externals const externalWebpackNames = externals.map( m => `__WEBPACK_EXTERNAL_MODULE_${Template.toIdentifier(`${m.id}`)}__` ); // Declaring variables for the internal variable names for the webpack externals const externalVarDeclarations = externalWebpackNames.length > 0 ? `var ${externalWebpackNames.join(", ")};` : ""; // The system.register format requires an array of setter functions for externals. const setters = externalWebpackNames.length === 0 ? "" : Template.asString([ "setters: [", Template.indent( externalWebpackNames .map(external => Template.asString([ "function(module) {", Template.indent(`${external} = module;`), "}" ]) ) .join(",\n") ), "]," ]); return new ConcatSource( Template.asString([ `System.register(${name}${systemDependencies}, function(${dynamicExport}) {`, Template.indent([ externalVarDeclarations, "return {", Template.indent([ setters, "execute: function() {", Template.indent(`${dynamicExport}(`) ]) ]) ]) + "\n", source, "\n" + Template.asString([ Template.indent([ Template.indent([Template.indent([");"]), "}"]), "};" ]), "})" ]) ); }; for (const template of [mainTemplate, chunkTemplate]) { template.hooks.renderWithEntry.tap( "SystemMainTemplatePlugin", onRenderWithEntry ); } mainTemplate.hooks.globalHashPaths.tap( "SystemMainTemplatePlugin", paths => { if (this.name) { paths.push(this.name); } return paths; } ); mainTemplate.hooks.hash.tap("SystemMainTemplatePlugin", hash => { hash.update("exports system"); if (this.name) { hash.update(this.name); } }); } } module.exports = SystemMainTemplatePlugin;