mirror of https://github.com/webpack/webpack.git
commit
518104b3fb
|
@ -1100,6 +1100,7 @@ export interface OutputOptions {
|
|||
| "commonjs2"
|
||||
| "commonjs-module"
|
||||
| "amd"
|
||||
| "amd-require"
|
||||
| "umd"
|
||||
| "umd2"
|
||||
| "jsonp";
|
||||
|
|
|
@ -78,6 +78,7 @@ export type DllReferencePluginOptionsSourceType =
|
|||
| "commonjs2"
|
||||
| "commonjs-module"
|
||||
| "amd"
|
||||
| "amd-require"
|
||||
| "umd"
|
||||
| "umd2"
|
||||
| "jsonp";
|
||||
|
|
|
@ -11,13 +11,24 @@ const Template = require("./Template");
|
|||
|
||||
/** @typedef {import("./Compilation")} Compilation */
|
||||
|
||||
/**
|
||||
* @typedef {Object} AmdMainTemplatePluginOptions
|
||||
* @param {string=} name the library name
|
||||
* @property {boolean=} requireAsWrapper
|
||||
*/
|
||||
|
||||
class AmdMainTemplatePlugin {
|
||||
/**
|
||||
* @param {string=} name the library name
|
||||
* @param {AmdMainTemplatePluginOptions} options the plugin options
|
||||
*/
|
||||
constructor(name) {
|
||||
/** @type {string=} */
|
||||
this.name = name;
|
||||
constructor(options) {
|
||||
if (!options || typeof options === "string") {
|
||||
this.name = options;
|
||||
this.requireAsWrapper = false;
|
||||
} else {
|
||||
this.name = options.name;
|
||||
this.requireAsWrapper = options.requireAsWrapper;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -50,7 +61,13 @@ class AmdMainTemplatePlugin {
|
|||
)
|
||||
.join(", ");
|
||||
|
||||
if (this.name) {
|
||||
if (this.requireAsWrapper) {
|
||||
return new ConcatSource(
|
||||
`require(${externalsDepsArray}, function(${externalsArguments}) { return `,
|
||||
source,
|
||||
"});"
|
||||
);
|
||||
} else if (this.name) {
|
||||
const name = mainTemplate.getAssetPath(this.name, {
|
||||
hash,
|
||||
chunk
|
||||
|
|
|
@ -94,6 +94,7 @@ const { arrayToSetDeprecation } = require("./util/deprecation");
|
|||
* @typedef {Object} AvailableModulesChunkGroupMapping
|
||||
* @property {ChunkGroup} chunkGroup
|
||||
* @property {Set<Module>} availableModules
|
||||
* @property {boolean} needCopy
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -1344,7 +1345,7 @@ class Compilation {
|
|||
|
||||
const moduleGraph = this.moduleGraph;
|
||||
|
||||
/** @typedef {{block: AsyncDependenciesBlock, chunkGroup: ChunkGroup}} ChunkGroupDep */
|
||||
/** @typedef {{block: AsyncDependenciesBlock, chunkGroup: ChunkGroup, couldBeFiltered: boolean}} ChunkGroupDep */
|
||||
|
||||
/** @type {Map<ChunkGroup, ChunkGroupDep[]>} */
|
||||
const chunkDependencies = new Map();
|
||||
|
@ -1530,7 +1531,8 @@ class Compilation {
|
|||
if (!deps) chunkDependencies.set(chunkGroup, (deps = []));
|
||||
deps.push({
|
||||
block: b,
|
||||
chunkGroup: c
|
||||
chunkGroup: c,
|
||||
couldBeFiltered: true
|
||||
});
|
||||
|
||||
// 3. We enqueue the DependenciesBlock for traversal
|
||||
|
@ -1652,12 +1654,14 @@ class Compilation {
|
|||
// PART TWO
|
||||
/** @type {Set<Module>} */
|
||||
let availableModules;
|
||||
/** @type {Set<Module>} */
|
||||
let newAvailableModules;
|
||||
/** @type {Queue<AvailableModulesChunkGroupMapping>} */
|
||||
const queue2 = new Queue(
|
||||
inputChunkGroups.map(chunkGroup => ({
|
||||
chunkGroup,
|
||||
availableModules: new Set()
|
||||
availableModules: new Set(),
|
||||
needCopy: true
|
||||
}))
|
||||
);
|
||||
|
||||
|
@ -1685,8 +1689,12 @@ class Compilation {
|
|||
*/
|
||||
const filterFn = dep => {
|
||||
const depChunkGroup = dep.chunkGroup;
|
||||
if (!dep.couldBeFiltered) return true;
|
||||
if (blocksWithNestedBlocks.has(dep.block)) return true;
|
||||
if (areModulesAvailable(depChunkGroup, newAvailableModules)) return false; // break all modules are already available
|
||||
if (areModulesAvailable(depChunkGroup, newAvailableModules)) {
|
||||
return false; // break all modules are already available
|
||||
}
|
||||
dep.couldBeFiltered = false;
|
||||
return true;
|
||||
};
|
||||
|
||||
|
@ -1705,7 +1713,10 @@ class Compilation {
|
|||
// the list didn't shrink.
|
||||
let minAvailableModules = minAvailableModulesMap.get(chunkGroup);
|
||||
if (minAvailableModules === undefined) {
|
||||
minAvailableModulesMap.set(chunkGroup, new Set(availableModules));
|
||||
minAvailableModulesMap.set(
|
||||
chunkGroup,
|
||||
queueItem.needCopy ? new Set(availableModules) : availableModules
|
||||
);
|
||||
} else {
|
||||
let deletedModules = false;
|
||||
for (const m of minAvailableModules) {
|
||||
|
@ -1731,30 +1742,33 @@ class Compilation {
|
|||
}
|
||||
}
|
||||
|
||||
// 4. Filter edges with available modules
|
||||
const filteredDeps = deps.filter(filterFn);
|
||||
|
||||
// 5. Foreach remaining edge
|
||||
// 4. Foreach remaining edge
|
||||
const nextChunkGroups = new Set();
|
||||
for (let i = 0; i < filteredDeps.length; i++) {
|
||||
const dep = filteredDeps[i];
|
||||
for (let i = 0; i < deps.length; i++) {
|
||||
const dep = deps[i];
|
||||
|
||||
// Filter inline, rather than creating a new array from `.filter()`
|
||||
if (!filterFn(dep)) {
|
||||
continue;
|
||||
}
|
||||
const depChunkGroup = dep.chunkGroup;
|
||||
const depBlock = dep.block;
|
||||
|
||||
// 6. Connect block with chunk
|
||||
// 5. Connect block with chunk
|
||||
chunkGraph.connectBlockAndChunkGroup(depBlock, depChunkGroup);
|
||||
|
||||
// 7. Connect chunk with parent
|
||||
// 6. Connect chunk with parent
|
||||
connectChunkGroupParentAndChild(chunkGroup, depChunkGroup);
|
||||
|
||||
nextChunkGroups.add(depChunkGroup);
|
||||
}
|
||||
|
||||
// 8. Enqueue further traversal
|
||||
// 7. Enqueue further traversal
|
||||
for (const nextChunkGroup of nextChunkGroups) {
|
||||
queue2.enqueue({
|
||||
chunkGroup: nextChunkGroup,
|
||||
availableModules: newAvailableModules
|
||||
availableModules: newAvailableModules,
|
||||
needCopy: nextChunkGroup.size !== 1
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -199,13 +199,14 @@ class ExternalModule extends Module {
|
|||
return getSourceForGlobalVariableExternal(request, this.externalType);
|
||||
case "global":
|
||||
return getSourceForGlobalVariableExternal(
|
||||
runtimeTemplate.outputOptions.globalObject,
|
||||
this.externalType
|
||||
request,
|
||||
runtimeTemplate.outputOptions.globalObject
|
||||
);
|
||||
case "commonjs":
|
||||
case "commonjs2":
|
||||
return getSourceForCommonJsExternal(request);
|
||||
case "amd":
|
||||
case "amd-require":
|
||||
case "umd":
|
||||
case "umd2":
|
||||
return getSourceForAmdOrUmdExternal(
|
||||
|
|
|
@ -27,7 +27,9 @@ const accessorToObjectAccess = accessor => {
|
|||
*/
|
||||
const accessorAccess = (base, accessor, umdProperty, joinWith = "; ") => {
|
||||
const normalizedAccessor =
|
||||
typeof accessor === "object" ? accessor[umdProperty] : accessor;
|
||||
typeof accessor === "object" && !Array.isArray(accessor)
|
||||
? accessor[umdProperty]
|
||||
: accessor;
|
||||
const accessors = Array.isArray(normalizedAccessor)
|
||||
? normalizedAccessor
|
||||
: [normalizedAccessor];
|
||||
|
@ -139,15 +141,16 @@ class LibraryTemplatePlugin {
|
|||
compilation
|
||||
);
|
||||
break;
|
||||
case "amd": {
|
||||
case "amd":
|
||||
case "amd-require": {
|
||||
const AmdMainTemplatePlugin = require("./AmdMainTemplatePlugin");
|
||||
if (this.name) {
|
||||
if (typeof this.name !== "string")
|
||||
if (this.name && typeof this.name !== "string") {
|
||||
throw new Error("library name must be a string for amd target");
|
||||
new AmdMainTemplatePlugin(this.name).apply(compilation);
|
||||
} else {
|
||||
new AmdMainTemplatePlugin().apply(compilation);
|
||||
}
|
||||
new AmdMainTemplatePlugin({
|
||||
name: this.name,
|
||||
requireAsWrapper: this.target === "amd-require"
|
||||
}).apply(compilation);
|
||||
break;
|
||||
}
|
||||
case "umd":
|
||||
|
|
|
@ -249,7 +249,7 @@ module.exports = class MainTemplate {
|
|||
this.hooks.requireExtensions.tap(
|
||||
"MainTemplate",
|
||||
(source, renderContext) => {
|
||||
const { chunk, hash } = renderContext;
|
||||
const { chunk, hash, chunkGraph } = renderContext;
|
||||
const buf = [];
|
||||
const chunkMaps = chunk.getChunkMaps();
|
||||
// Check if there are non initial chunks which need to be imported using require-ensure
|
||||
|
@ -265,6 +265,22 @@ module.exports = class MainTemplate {
|
|||
);
|
||||
buf.push(Template.indent("return Promise.all(promises);"));
|
||||
buf.push("};");
|
||||
} else if (
|
||||
chunkGraph.hasModuleInGraph(chunk, m =>
|
||||
m.blocks.some(b => {
|
||||
const chunkGroup = chunkGraph.getBlockChunkGroup(b);
|
||||
return chunkGroup && chunkGroup.chunks.length > 0;
|
||||
})
|
||||
)
|
||||
) {
|
||||
// There async blocks in the graph, so we need to add an empty requireEnsure
|
||||
// function anyway. This can happen with multiple entrypoints.
|
||||
buf.push("// The chunk loading function for additional chunks");
|
||||
buf.push("// Since all referenced chunks are already included");
|
||||
buf.push("// in this file, this function is empty here.");
|
||||
buf.push(`${this.requireFn}.e = function requireEnsure() {`);
|
||||
buf.push(Template.indent("return Promise.resolve();"));
|
||||
buf.push("};");
|
||||
}
|
||||
buf.push("");
|
||||
buf.push("// expose the modules object (__webpack_modules__)");
|
||||
|
|
|
@ -20,7 +20,7 @@ module.exports = function() {
|
|||
var script = document.createElement("script");
|
||||
script.charset = "utf-8";
|
||||
script.src = $require$.p + $hotChunkFilename$;
|
||||
$crossOriginLoading$;
|
||||
if ($crossOriginLoading$) script.crossOrigin = $crossOriginLoading$;
|
||||
head.appendChild(script);
|
||||
}
|
||||
|
||||
|
|
|
@ -585,9 +585,7 @@ class JsonpMainTemplatePlugin {
|
|||
.replace(/\$require\$/g, mainTemplate.requireFn)
|
||||
.replace(
|
||||
/\$crossOriginLoading\$/g,
|
||||
crossOriginLoading
|
||||
? `script.crossOrigin = ${JSON.stringify(crossOriginLoading)}`
|
||||
: ""
|
||||
crossOriginLoading ? JSON.stringify(crossOriginLoading) : "null"
|
||||
)
|
||||
.replace(/\$hotMainFilename\$/g, currentHotUpdateMainFilename)
|
||||
.replace(/\$hotChunkFilename\$/g, currentHotUpdateChunkFilename)
|
||||
|
|
|
@ -53,7 +53,6 @@
|
|||
"husky": "^1.0.0-rc.6",
|
||||
"istanbul": "^0.4.5",
|
||||
"jest": "^23.4.1",
|
||||
"jest-silent-reporter": "^0.0.5",
|
||||
"json-loader": "^0.5.7",
|
||||
"json-schema-to-typescript": "^6.0.1",
|
||||
"less": "^2.5.1",
|
||||
|
|
|
@ -963,6 +963,7 @@
|
|||
"commonjs2",
|
||||
"commonjs-module",
|
||||
"amd",
|
||||
"amd-require",
|
||||
"umd",
|
||||
"umd2",
|
||||
"jsonp"
|
||||
|
|
|
@ -35,7 +35,7 @@ module.exports = ajv =>
|
|||
data,
|
||||
`The provided value ${JSON.stringify(
|
||||
data
|
||||
)} contans exclamation mark (!) which is not allowed because it's reserved for loader syntax.`
|
||||
)} contains exclamation mark (!) which is not allowed because it's reserved for loader syntax.`
|
||||
)
|
||||
];
|
||||
passes = false;
|
||||
|
|
|
@ -88,6 +88,7 @@
|
|||
"commonjs2",
|
||||
"commonjs-module",
|
||||
"amd",
|
||||
"amd-require",
|
||||
"umd",
|
||||
"umd2",
|
||||
"jsonp"
|
||||
|
|
|
@ -239,7 +239,7 @@ describe("Validation", () => {
|
|||
}
|
||||
},
|
||||
message: [
|
||||
' - configuration.output.path: The provided value "/somepath/!test" contans exclamation mark (!) which is not allowed because it\'s reserved for loader syntax.',
|
||||
' - configuration.output.path: The provided value "/somepath/!test" contains exclamation mark (!) which is not allowed because it\'s reserved for loader syntax.',
|
||||
" -> The output directory as **absolute path** (required)."
|
||||
]
|
||||
},
|
||||
|
|
|
@ -1163,13 +1163,13 @@ Child
|
|||
`;
|
||||
|
||||
exports[`StatsTestCases should print correct stats for limit-chunk-count-plugin 1`] = `
|
||||
"Hash: 05e860caf71fe3b2d19aee833b1335bf5cefe6d3074451f01c7cf41c58065d34f2c917d77c3f99ff
|
||||
"Hash: 4c55553bd94205710a5fee833b1335bf5cefe6d3074451f01c7cf41c58065d34f2c917d77c3f99ff
|
||||
Child 1 chunks:
|
||||
Hash: 05e860caf71fe3b2d19a
|
||||
Hash: 4c55553bd94205710a5f
|
||||
Time: Xms
|
||||
Built at: Thu Jan 01 1970 00:00:00 GMT
|
||||
Asset Size Chunks Chunk Names
|
||||
bundle.js 6.39 KiB 0 [emitted] main
|
||||
bundle.js 6.67 KiB 0 [emitted] main
|
||||
Entrypoint main = bundle.js
|
||||
chunk {0} bundle.js (main) 191 bytes <{0}> >{0}< [entry] [rendered]
|
||||
[0] ./index.js 73 bytes {0} [built]
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
import run from "./c";
|
||||
import "./d";
|
||||
|
||||
it("should not crash", () => {
|
||||
return run().then(result => {
|
||||
expect(result.default).toBe("ok");
|
||||
});
|
||||
})
|
|
@ -0,0 +1,3 @@
|
|||
import run from "./c";
|
||||
|
||||
run();
|
|
@ -0,0 +1,3 @@
|
|||
export default function run() {
|
||||
return import("./d");
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
export default "ok";
|
|
@ -0,0 +1,9 @@
|
|||
module.exports = {
|
||||
entry: {
|
||||
bundle0: "./a",
|
||||
other: "./b"
|
||||
},
|
||||
output: {
|
||||
filename: "[name].js"
|
||||
}
|
||||
};
|
|
@ -0,0 +1,11 @@
|
|||
afterEach(done => {
|
||||
delete global.EXTERNAL_TEST_GLOBAL;
|
||||
done();
|
||||
});
|
||||
|
||||
it("should move externals in chunks into entry chunk", function() {
|
||||
global.EXTERNAL_TEST_GLOBAL = 42;
|
||||
// eslint-disable-next-line node/no-missing-require
|
||||
const result = require("external");
|
||||
expect(result).toBe(42);
|
||||
});
|
|
@ -0,0 +1,5 @@
|
|||
module.exports = {
|
||||
externals: {
|
||||
external: "global EXTERNAL_TEST_GLOBAL"
|
||||
}
|
||||
};
|
|
@ -0,0 +1,3 @@
|
|||
it("should define global object with property", function() {
|
||||
expect(a["b"]).toBeDefined();
|
||||
});
|
|
@ -0,0 +1,5 @@
|
|||
module.exports = {
|
||||
output: {
|
||||
library: ["a", "b"]
|
||||
}
|
||||
};
|
|
@ -0,0 +1,3 @@
|
|||
it("should define property in 'window' object", function() {
|
||||
expect(window["a"]["b"]).toBeDefined();
|
||||
});
|
|
@ -0,0 +1,7 @@
|
|||
module.exports = {
|
||||
target: "web",
|
||||
output: {
|
||||
library: ["a", "b"],
|
||||
libraryTarget: "window"
|
||||
}
|
||||
};
|
|
@ -0,0 +1,10 @@
|
|||
it("should run", function() {
|
||||
|
||||
});
|
||||
|
||||
it("should name require", function() {
|
||||
var fs = nodeRequire("fs");
|
||||
var source = fs.readFileSync(__filename, "utf-8");
|
||||
|
||||
expect(source).toMatch(/require\(\[[^\]]*\], function\(/);
|
||||
});
|
|
@ -0,0 +1,17 @@
|
|||
const webpack = require("../../../../");
|
||||
module.exports = {
|
||||
output: {
|
||||
libraryTarget: "amd-require"
|
||||
},
|
||||
node: {
|
||||
__dirname: false,
|
||||
__filename: false
|
||||
},
|
||||
plugins: [
|
||||
new webpack.BannerPlugin({
|
||||
raw: true,
|
||||
banner:
|
||||
"var nodeRequire = require;\nvar require = function(deps, fn) { fn(); }\n"
|
||||
})
|
||||
]
|
||||
};
|
|
@ -6,5 +6,5 @@ it("should name define", function() {
|
|||
var fs = require("fs");
|
||||
var source = fs.readFileSync(__filename, "utf-8");
|
||||
|
||||
expect(source).toMatch("define(function(");
|
||||
expect(source).toMatch(/define\(\[[^\]]*\], function\(/);
|
||||
});
|
||||
|
|
34
yarn.lock
34
yarn.lock
|
@ -3842,17 +3842,6 @@ jest-matcher-utils@^23.2.0:
|
|||
jest-get-type "^22.1.0"
|
||||
pretty-format "^23.2.0"
|
||||
|
||||
jest-message-util@^23.0.0:
|
||||
version "23.3.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-23.3.0.tgz#bc07b11cec6971fb5dd9de2dfb60ebc22150c160"
|
||||
integrity sha1-vAexHOxpcftd2d4t+2DrwiFQwWA=
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.0.0-beta.35"
|
||||
chalk "^2.0.1"
|
||||
micromatch "^3.1.10"
|
||||
slash "^1.0.0"
|
||||
stack-utils "^1.0.1"
|
||||
|
||||
jest-message-util@^23.4.0:
|
||||
version "23.4.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-23.4.0.tgz#17610c50942349508d01a3d1e0bda2c079086a9f"
|
||||
|
@ -3942,14 +3931,6 @@ jest-serializer@^23.0.1:
|
|||
resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-23.0.1.tgz#a3776aeb311e90fe83fab9e533e85102bd164165"
|
||||
integrity sha1-o3dq6zEekP6D+rnlM+hRAr0WQWU=
|
||||
|
||||
jest-silent-reporter@^0.0.5:
|
||||
version "0.0.5"
|
||||
resolved "https://registry.yarnpkg.com/jest-silent-reporter/-/jest-silent-reporter-0.0.5.tgz#14139b7a991b7bcca880dd8a69c33a91723a8f1f"
|
||||
integrity sha512-LWNEJEeI9jbqOaNyqmnLWyEJXaNlDMCDqX6NbY89pzgerb3iExky56zD5oBvh+nvgzEND9cjL57EhifaAJBhjw==
|
||||
dependencies:
|
||||
chalk "^2.3.1"
|
||||
jest-util "^23.0.0"
|
||||
|
||||
jest-snapshot@^23.4.1:
|
||||
version "23.4.1"
|
||||
resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-23.4.1.tgz#090de9acae927f6a3af3005bda40d912b83e9c96"
|
||||
|
@ -3967,19 +3948,6 @@ jest-snapshot@^23.4.1:
|
|||
pretty-format "^23.2.0"
|
||||
semver "^5.5.0"
|
||||
|
||||
jest-util@^23.0.0:
|
||||
version "23.0.1"
|
||||
resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-23.0.1.tgz#68ea5bd7edb177d3059f9797259f8e0dacce2f99"
|
||||
integrity sha1-aOpb1+2xd9MFn5eXJZ+ODazOL5k=
|
||||
dependencies:
|
||||
callsites "^2.0.0"
|
||||
chalk "^2.0.1"
|
||||
graceful-fs "^4.1.11"
|
||||
is-ci "^1.0.10"
|
||||
jest-message-util "^23.0.0"
|
||||
mkdirp "^0.5.1"
|
||||
source-map "^0.6.0"
|
||||
|
||||
jest-util@^23.4.0:
|
||||
version "23.4.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-23.4.0.tgz#4d063cb927baf0a23831ff61bec2cbbf49793561"
|
||||
|
@ -4652,7 +4620,7 @@ micromatch@^2.3.11:
|
|||
parse-glob "^3.0.4"
|
||||
regex-cache "^0.4.2"
|
||||
|
||||
micromatch@^3.1.10, micromatch@^3.1.4, micromatch@^3.1.8:
|
||||
micromatch@^3.1.4, micromatch@^3.1.8:
|
||||
version "3.1.10"
|
||||
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23"
|
||||
integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==
|
||||
|
|
Loading…
Reference in New Issue