Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #8864 from joeldenning/issue-8833
Adding support for output.libraryTarget "system"
- Loading branch information
Showing
19 changed files
with
387 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
/* | ||
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(this.name)}, ` : ""; | ||
|
||
// 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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -986,7 +986,8 @@ | |
"amd-require", | ||
"umd", | ||
"umd2", | ||
"jsonp" | ||
"jsonp", | ||
"system" | ||
] | ||
}, | ||
"path": { | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
/* This test verifies that webpack externals are properly indicated as dependencies to System. | ||
* Also that when System provides the external variables to webpack that the variables get plumbed | ||
* through correctly and are usable by the webpack bundle. | ||
*/ | ||
it("should get an external from System", function() { | ||
const external1 = require("external1"); | ||
expect(external1).toBe("the external1 value"); | ||
|
||
const external2 = require("external2"); | ||
expect(external2).toBe("the external2 value"); | ||
}); |
16 changes: 16 additions & 0 deletions
16
test/configCases/externals/externals-system/test.config.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
const System = require("../../../helpers/fakeSystem"); | ||
|
||
module.exports = { | ||
beforeExecute: () => { | ||
System.init({ | ||
external1: "the external1 value", | ||
external2: "the external2 value" | ||
}); | ||
}, | ||
moduleScope(scope) { | ||
scope.System = System; | ||
}, | ||
afterExecute: () => { | ||
System.execute("(anonym)"); | ||
} | ||
}; |
9 changes: 9 additions & 0 deletions
9
test/configCases/externals/externals-system/webpack.config.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
module.exports = { | ||
output: { | ||
libraryTarget: "system" | ||
}, | ||
externals: { | ||
external1: "external1", | ||
external2: "external2" | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// This test verifies that values exported by a webpack bundle are consumable by systemjs. | ||
|
||
export const namedThing = { | ||
hello: "there" | ||
}; | ||
|
||
export default "the default export"; | ||
|
||
it("should successfully export values to System", function() { | ||
const exports = eval("System").registry["(anonym)"].exports; | ||
expect(exports["default"]).toBe("the default export"); | ||
expect(exports.namedThing).toBe(namedThing); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
const System = require("../../../helpers/fakeSystem"); | ||
|
||
module.exports = { | ||
beforeExecute: () => { | ||
System.init(); | ||
}, | ||
moduleScope(scope) { | ||
scope.System = System; | ||
}, | ||
afterExecute: () => { | ||
System.execute("(anonym)"); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
module.exports = { | ||
output: { | ||
libraryTarget: "system" | ||
}, | ||
node: { | ||
__dirname: false, | ||
__filename: false | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
/* This test verifies that when output.library is specified that the compiled bundle provides | ||
* the library name to System during the System.register | ||
*/ | ||
|
||
it("should call System.register with a name", function() {}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
const System = require("../../../helpers/fakeSystem"); | ||
|
||
module.exports = { | ||
beforeExecute: () => { | ||
System.init(); | ||
}, | ||
moduleScope(scope) { | ||
scope.System = System; | ||
}, | ||
afterExecute: () => { | ||
System.execute("named-system-module"); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
module.exports = { | ||
output: { | ||
library: "named-system-module", | ||
libraryTarget: "system" | ||
}, | ||
node: { | ||
__dirname: false, | ||
__filename: false | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
/* This test verifies that when there is no output.library specified that the call to | ||
* System.register does not include a name argument. | ||
*/ | ||
|
||
it("should call System.register without a name", function() {}); |
Oops, something went wrong.