UNPKG

3.38 kBJavaScriptView Raw
1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Joel Denning @joeldenning
4 */
5
6"use strict";
7
8const { ConcatSource } = require("webpack-sources");
9const Template = require("./Template");
10
11/** @typedef {import("./Compilation")} Compilation */
12
13/**
14 * @typedef {Object} SystemMainTemplatePluginOptions
15 * @param {string=} name the library name
16 */
17
18class SystemMainTemplatePlugin {
19 /**
20 * @param {SystemMainTemplatePluginOptions} options the plugin options
21 */
22 constructor(options) {
23 this.name = options.name;
24 }
25
26 /**
27 * @param {Compilation} compilation the compilation instance
28 * @returns {void}
29 */
30 apply(compilation) {
31 const { mainTemplate, chunkTemplate } = compilation;
32
33 const onRenderWithEntry = (source, chunk, hash) => {
34 const externals = chunk.getModules().filter(m => m.external);
35
36 // The name this bundle should be registered as with System
37 const name = this.name
38 ? `${JSON.stringify(
39 mainTemplate.getAssetPath(this.name, { hash, chunk })
40 )}, `
41 : "";
42
43 // The array of dependencies that are external to webpack and will be provided by System
44 const systemDependencies = JSON.stringify(
45 externals.map(m =>
46 typeof m.request === "object" ? m.request.amd : m.request
47 )
48 );
49
50 // The name of the variable provided by System for exporting
51 const dynamicExport = "__WEBPACK_DYNAMIC_EXPORT__";
52
53 // An array of the internal variable names for the webpack externals
54 const externalWebpackNames = externals.map(
55 m => `__WEBPACK_EXTERNAL_MODULE_${Template.toIdentifier(`${m.id}`)}__`
56 );
57
58 // Declaring variables for the internal variable names for the webpack externals
59 const externalVarDeclarations =
60 externalWebpackNames.length > 0
61 ? `var ${externalWebpackNames.join(", ")};`
62 : "";
63
64 // The system.register format requires an array of setter functions for externals.
65 const setters =
66 externalWebpackNames.length === 0
67 ? ""
68 : Template.asString([
69 "setters: [",
70 Template.indent(
71 externalWebpackNames
72 .map(external =>
73 Template.asString([
74 "function(module) {",
75 Template.indent(`${external} = module;`),
76 "}"
77 ])
78 )
79 .join(",\n")
80 ),
81 "],"
82 ]);
83
84 return new ConcatSource(
85 Template.asString([
86 `System.register(${name}${systemDependencies}, function(${dynamicExport}) {`,
87 Template.indent([
88 externalVarDeclarations,
89 "return {",
90 Template.indent([
91 setters,
92 "execute: function() {",
93 Template.indent(`${dynamicExport}(`)
94 ])
95 ])
96 ]) + "\n",
97 source,
98 "\n" +
99 Template.asString([
100 Template.indent([
101 Template.indent([Template.indent([");"]), "}"]),
102 "};"
103 ]),
104 "})"
105 ])
106 );
107 };
108
109 for (const template of [mainTemplate, chunkTemplate]) {
110 template.hooks.renderWithEntry.tap(
111 "SystemMainTemplatePlugin",
112 onRenderWithEntry
113 );
114 }
115
116 mainTemplate.hooks.globalHashPaths.tap(
117 "SystemMainTemplatePlugin",
118 paths => {
119 if (this.name) {
120 paths.push(this.name);
121 }
122 return paths;
123 }
124 );
125
126 mainTemplate.hooks.hash.tap("SystemMainTemplatePlugin", hash => {
127 hash.update("exports system");
128 if (this.name) {
129 hash.update(this.name);
130 }
131 });
132 }
133}
134
135module.exports = SystemMainTemplatePlugin;