add more types and fix/remove TODOs

change Chunk.files to Set
remove checkContext from IgnorePlugin
remove external flag from ExternalModule
This commit is contained in:
Tobias Koppers 2019-06-14 10:45:56 +02:00
parent 4b2c5784ed
commit 0505e177f1
21 changed files with 126 additions and 97 deletions

View File

@ -16,10 +16,6 @@ export type IgnorePluginOptions =
resourceRegExp?: RegExp;
}
| {
/**
* A filter function for context
*/
checkContext?: (context: string) => boolean;
/**
* A filter function for resource and context
*/

View File

@ -7,6 +7,7 @@
const WebpackError = require("./WebpackError");
/** @typedef {import("./Dependency").DependencyLocation} DependencyLocation */
/** @typedef {import("./Module")} Module */
class AsyncDependencyToInitialChunkError extends WebpackError {
@ -14,7 +15,7 @@ class AsyncDependencyToInitialChunkError extends WebpackError {
* Creates an instance of AsyncDependencyToInitialChunkError.
* @param {string} chunkName Name of Chunk
* @param {Module} module module tied to dependency
* @param {TODO} loc location of dependency
* @param {DependencyLocation} loc location of dependency
*/
constructor(chunkName, module, loc) {
super(

View File

@ -10,6 +10,7 @@ const Entrypoint = require("./Entrypoint");
const { intersect } = require("./util/SetHelpers");
const SortableSet = require("./util/SortableSet");
const { compareModulesByIdOrIdentifier } = require("./util/comparators");
const { arrayToSetDeprecation } = require("./util/deprecation");
/** @typedef {import("webpack-sources").Source} Source */
/** @typedef {import("./ChunkGraph").ChunkFilterPredicate} ChunkFilterPredicate */
@ -73,9 +74,9 @@ class Chunk {
this.filenameTemplate = undefined;
/** @private @type {SortableSet<ChunkGroup>} */
this._groups = new SortableSet(undefined, sortChunkGroupById);
// TODO convert files to a Set
/** @type {string[]} */
this.files = [];
/** @type {Set<string>} */
this.files = new Set();
arrayToSetDeprecation(this.files, "Chunk.files");
/** @type {boolean} */
this.rendered = false;
/** @type {string=} */
@ -88,8 +89,6 @@ class Chunk {
this.chunkReason = undefined;
/** @type {boolean} */
this.extraAsync = false;
// TODO remove this, it's wrong
this.removedModules = undefined;
}
// TODO remove in webpack 6

View File

@ -69,7 +69,6 @@ module.exports = class ChunkTemplate {
}
/**
* TODO webpack 5: remove moduleTemplate and dependencyTemplates
* Updates hash with chunk-specific information from this template
* @param {Hash} hash the hash to update
* @param {Chunk} chunk the chunk

View File

@ -2409,14 +2409,11 @@ class Compilation {
asyncLib.forEach(
this.chunks,
(chunk, _callback) => {
// TODO Workaround for https://github.com/suguru03/neo-async/issues/63
const callback = err => process.nextTick(() => _callback(err));
(chunk, callback) => {
/** @type {RenderManifestEntry[]} */
let manifest;
try {
chunk.files = [];
chunk.files.clear();
const template = chunk.hasRuntime()
? this.mainTemplate
: this.chunkTemplate;
@ -2437,10 +2434,7 @@ class Compilation {
}
asyncLib.forEach(
manifest,
(fileManifest, _callback) => {
// TODO Workaround for https://github.com/suguru03/neo-async/issues/63
const callback = err => process.nextTick(() => _callback(err));
(fileManifest, callback) => {
const ident = fileManifest.identifier;
const cacheName = `${this.compilerPath}/asset/${ident}`;
const usedHash = fileManifest.hash;
@ -2464,7 +2458,7 @@ class Compilation {
if (alreadyWritten !== undefined) {
if (alreadyWritten.hash !== usedHash) {
return callback(
new Error(
new WebpackError(
`Conflict: Multiple chunks emit assets to the same filename ${file}` +
` (chunks ${alreadyWritten.chunk.id} and ${chunk.id})`
)
@ -2490,7 +2484,7 @@ class Compilation {
}
if (this.assets[file] && this.assets[file] !== source) {
return callback(
new Error(
new WebpackError(
`Conflict: Rendering chunk ${chunk.id} ` +
`emits to the filename ${file} ` +
"which was already written to by something else " +
@ -2499,7 +2493,7 @@ class Compilation {
);
}
this.assets[file] = source;
chunk.files.push(file);
chunk.files.add(file);
this.hooks.chunkAsset.call(chunk, file);
alreadyWrittenFiles.set(file, {
hash: usedHash,

View File

@ -50,7 +50,6 @@ const DependencyReference = require("./dependencies/DependencyReference");
class Dependency {
constructor() {
// TODO remove in webpack 5
/** @type {boolean} */
this.weak = false;
/** @type {boolean} */

View File

@ -130,8 +130,6 @@ class ExternalModule extends Module {
this.externalType = type;
/** @type {string} */
this.userRequest = userRequest;
/** @type {boolean} */
this.external = true;
}
/**

View File

@ -357,7 +357,7 @@ class HotModuleReplacementPlugin {
const source = entry.render();
compilation.additionalChunkAssets.push(filename);
compilation.assets[filename] = source;
currentChunk.files.push(filename);
currentChunk.files.add(filename);
compilation.hooks.chunkAsset.call(currentChunk, filename);
}
hotUpdateMainContent.c.push(chunkId);

View File

@ -37,14 +37,7 @@ class IgnorePlugin {
this.options.checkResource &&
this.options.checkResource(resolveData.request, resolveData.context)
) {
// TODO webpack 5 remove checkContext, as checkResource already gets context
if ("checkContext" in this.options && this.options.checkContext) {
if (this.options.checkContext(resolveData.context)) {
return false;
}
} else {
return false;
}
return false;
}
if (

View File

@ -15,41 +15,76 @@ const { relative, dirname } = require("./util/fs");
const schema = require("../schemas/plugins/SourceMapDevToolPlugin.json");
/** @typedef {import("webpack-sources").Source} Source */
/** @typedef {import("../declarations/plugins/SourceMapDevToolPlugin").SourceMapDevToolPluginOptions} SourceMapDevToolPluginOptions */
/** @typedef {import("./Chunk")} Chunk */
/** @typedef {import("./Compilation")} Compilation */
/** @typedef {import("./Compiler")} Compiler */
/** @typedef {import("./Module")} Module */
/** @type {WeakMap<Source, { file: string, assets: Record<string, Source>}>} */
const assetsCache = new WeakMap();
/**
* @typedef {Object} SourceMapObject
* @property {string[]} sources
* @property {string[]=} sourcesContent
* @property {string} sourceRoot
* @property {string} file
*/
/**
* @typedef {Object} SourceMapDevToolTask
* @property {Chunk} chunk
* @property {string} file
* @property {Source} asset
* @property {string} source
* @property {SourceMapObject} sourceMap
* @property {(Module|string)[]} modules
*/
/**
* @param {string} file the filename
* @param {Chunk} chunk the chunk
* @param {TODO} options options
* @param {Compilation} compilation the compilation
* @returns {SourceMapDevToolTask|undefined} the task for this file
*/
const getTaskForFile = (file, chunk, options, compilation) => {
const asset = compilation.assets[file];
const cache = assetsCache.get(asset);
if (cache && cache.file === file) {
for (const cachedFile in cache.assets) {
compilation.assets[cachedFile] = cache.assets[cachedFile];
if (cachedFile !== file) chunk.files.push(cachedFile);
if (cachedFile !== file) chunk.files.add(cachedFile);
}
return;
}
let source, sourceMap;
let source;
/** @type {SourceMapObject} */
let sourceMap;
if (asset.sourceAndMap) {
const sourceAndMap = asset.sourceAndMap(options);
sourceMap = sourceAndMap.map;
sourceMap = /** @type {SourceMapObject} */ (sourceAndMap.map);
source = sourceAndMap.source;
} else {
sourceMap = asset.map(options);
sourceMap = /** @type {SourceMapObject} */ (asset.map(options));
source = asset.source();
}
if (sourceMap) {
return {
chunk,
file,
asset,
source,
sourceMap,
modules: undefined
};
}
if (!sourceMap || typeof source !== "string") return;
const modules = sourceMap.sources.map(source => {
const module = compilation.findModule(source);
return module || source;
});
return {
chunk,
file,
asset,
source,
sourceMap,
modules
};
};
class SourceMapDevToolPlugin {
@ -119,6 +154,7 @@ class SourceMapDevToolPlugin {
}
reportProgress(0.0);
/** @type {SourceMapDevToolTask[]} */
const tasks = [];
files.forEach(({ file, chunk }, idx) => {
reportProgress(
@ -129,10 +165,7 @@ class SourceMapDevToolPlugin {
const task = getTaskForFile(file, chunk, options, compilation);
if (task) {
const modules = task.sourceMap.sources.map(source => {
const module = compilation.findModule(source);
return module || source;
});
const modules = task.modules;
for (let idx = 0; idx < modules.length; idx++) {
const module = modules[idx];
@ -154,8 +187,6 @@ class SourceMapDevToolPlugin {
}
}
task.modules = modules;
tasks.push(task);
}
});
@ -279,7 +310,7 @@ class SourceMapDevToolPlugin {
assets[sourceMapFile] = compilation.assets[
sourceMapFile
] = new RawSource(sourceMapString);
chunk.files.push(sourceMapFile);
chunk.files.add(sourceMapFile);
} else {
if (currentSourceMappingURLComment === false) {
throw new Error(

View File

@ -6,6 +6,7 @@
"use strict";
const { ConcatSource } = require("webpack-sources");
const ExternalModule = require("./ExternalModule");
const Template = require("./Template");
/** @typedef {import("./Compilation")} Compilation */
@ -31,7 +32,11 @@ class SystemMainTemplatePlugin {
const { mainTemplate, chunkTemplate } = compilation;
const onRenderWithEntry = (source, chunk, hash) => {
const externals = chunk.getModules().filter(m => m.external);
const chunkGraph = compilation.chunkGraph;
const modules = chunkGraph
.getChunkModules(chunk)
.filter(m => m instanceof ExternalModule);
const externals = /** @type {ExternalModule[]} */ (modules);
// The name this bundle should be registered as with System
const name = this.name ? `${JSON.stringify(this.name)}, ` : "";
@ -39,7 +44,9 @@ class SystemMainTemplatePlugin {
// 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
typeof m.request === "object" && !Array.isArray(m.request)
? m.request.amd
: m.request
)
);
@ -48,7 +55,10 @@ class SystemMainTemplatePlugin {
// An array of the internal variable names for the webpack externals
const externalWebpackNames = externals.map(
m => `__WEBPACK_EXTERNAL_MODULE_${Template.toIdentifier(`${m.id}`)}__`
m =>
`__WEBPACK_EXTERNAL_MODULE_${Template.toIdentifier(
`${chunkGraph.getModuleId(m)}`
)}__`
);
// Declaring variables for the internal variable names for the webpack externals

View File

@ -214,8 +214,7 @@ const compareEntries = (a, b) => {
// 5. by module identifiers
modulesA.sort();
modulesB.sort();
// TODO logic is inverted: fix this
return compareModuleIterables(modulesB, modulesA);
return compareModuleIterables(modulesA, modulesB);
};
/**

View File

@ -157,7 +157,6 @@ class UseEffectRulePlugin {
ident: options && typeof options === "object" ? path : undefined
}
});
// TODO
}
}
);

View File

@ -264,7 +264,7 @@ const SIMPLE_EXTRACTORS = {
object.name = asset.name;
object.size = asset.source.size();
const chunks = Array.from(compilation.chunks).filter(chunk =>
chunk.files.includes(asset.name)
chunk.files.has(asset.name)
);
object.chunks = Array.from(
chunks.reduce((ids, chunk) => {
@ -299,7 +299,7 @@ const SIMPLE_EXTRACTORS = {
name,
chunks: chunkGroup.chunks.map(c => c.id),
assets: chunkGroup.chunks.reduce(
(array, c) => array.concat(c.files || []),
(array, c) => array.concat(Array.from(c.files)),
/** @type {string[]} */ ([])
),
children: Object.keys(children).reduce((obj, key) => {
@ -308,7 +308,7 @@ const SIMPLE_EXTRACTORS = {
name: group.name,
chunks: group.chunks.map(c => c.id),
assets: group.chunks.reduce(
(array, c) => array.concat(c.files || []),
(array, c) => array.concat(Array.from(c.files)),
/** @type {string[]} */ ([])
)
}));
@ -546,7 +546,7 @@ const SIMPLE_EXTRACTORS = {
size: chunkGraph.getChunkModulesSize(chunk),
sizes: chunkGraph.getChunkModulesSizes(chunk),
names: chunk.name ? [chunk.name] : [],
files: chunk.files.slice(),
files: Array.from(chunk.files),
hash: chunk.renderedHash,
childrenByOrder: childIdByOrder
});

View File

@ -77,6 +77,12 @@ exports.arrayToSetDeprecation = (set, name) => {
const dPush = createDeprecation(
`${name} was changed from Array to Set (using Array method 'push' is deprecated)`
);
const dLength = createDeprecation(
`${name} was changed from Array to Set (using Array property 'length' is deprecated)`
);
const dIndexer = createDeprecation(
`${name} was changed from Array to Set (indexing Array is deprecated)`
);
/**
* @deprecated
* @this {Set}
@ -97,9 +103,30 @@ exports.arrayToSetDeprecation = (set, name) => {
);
};
}
const createIndexGetter = index => () => {
dIndexer();
let i = 0;
for (const item of set) {
if (i++ === index) return item;
}
return undefined;
};
let indexerDefined = 0;
Object.defineProperty(set, "length", {
get() {
return set.size;
dLength();
const length = set.size;
for (indexerDefined; indexerDefined < length; indexerDefined++) {
Object.defineProperty(set, indexerDefined, {
get: createIndexGetter(indexerDefined),
set(value) {
throw new Error(
`${name} was changed from Array to Set (indexing Array with write is not possible)`
);
}
});
}
return length;
},
set(value) {
throw new Error(
@ -107,4 +134,5 @@ exports.arrayToSetDeprecation = (set, name) => {
);
}
});
set[Symbol.isConcatSpreadable] = true;
};

View File

@ -45,8 +45,6 @@ const compose = (...fns) => {
);
};
// TODO replace with @callback
/**
* Removes the start instruction
*

View File

@ -24,7 +24,7 @@
"loader-runner": "3.0.0",
"loader-utils": "^1.1.0",
"memory-fs": "~0.4.1",
"neo-async": "^2.5.0",
"neo-async": "^2.6.0",
"schema-utils": "^1.0.0",
"tapable": "2.0.0-beta.4",
"terser-webpack-plugin": "^1.2.1",

View File

@ -21,11 +21,6 @@
"type": "object",
"additionalProperties": false,
"properties": {
"checkContext": {
"description": "A filter function for context",
"instanceof": "Function",
"tsType": "((context: string) => boolean)"
},
"checkResource": {
"description": "A filter function for resource and context",
"instanceof": "Function",

View File

@ -38,13 +38,6 @@ describe("Examples", () => {
options.output.publicPath = "dist/";
if (!options.entry) options.entry = "./example.js";
if (!options.plugins) options.plugins = [];
// To support deprecated loaders
// TODO remove in webpack 5
options.plugins.push(
new webpack.LoaderOptionsPlugin({
options: {}
})
);
}
webpack(options, (err, stats) => {
if (err) return done(err);

View File

@ -2731,9 +2731,9 @@ Child name-too-long:
Child custom-chunks-filter:
Entrypoint main = default/main.js
Entrypoint a = default/a.js
Entrypoint b = default/282.js default/954.js default/767.js default/b.js
Entrypoint c = default/282.js default/769.js default/767.js default/c.js
chunk {128} default/b.js (b) 92 bytes (javascript) 2.57 KiB (runtime) ={282}= ={767}= ={954}= [entry] [rendered]
Entrypoint b = default/282.js default/954.js default/568.js default/b.js
Entrypoint c = default/282.js default/769.js default/568.js default/c.js
chunk {128} default/b.js (b) 92 bytes (javascript) 2.57 KiB (runtime) ={282}= ={568}= ={954}= [entry] [rendered]
> ./b b
[996] ./b.js 72 bytes {128} {334} [built]
+ 2 hidden root modules
@ -2758,23 +2758,23 @@ Child custom-chunks-filter:
chunk {383} default/async-c.js (async-c) 72 bytes <{179}> ={282}= ={568}= ={767}= ={769}= [rendered]
> ./c [10] ./index.js 3:0-47
[460] ./c.js 72 bytes {383} {459} [built]
chunk {459} default/c.js (c) 92 bytes (javascript) 2.57 KiB (runtime) ={282}= ={767}= ={769}= [entry] [rendered]
chunk {459} default/c.js (c) 92 bytes (javascript) 2.57 KiB (runtime) ={282}= ={568}= ={769}= [entry] [rendered]
> ./c c
[460] ./c.js 72 bytes {383} {459} [built]
+ 2 hidden root modules
+ 1 hidden dependent module
chunk {568} default/568.js 20 bytes <{179}> <{282}> <{767}> <{786}> <{794}> <{954}> ={137}= ={282}= ={334}= ={383}= ={767}= ={769}= ={954}= [rendered] split chunk (cache group: default)
chunk {568} default/568.js 20 bytes <{179}> <{282}> <{767}> <{786}> <{794}> <{954}> ={128}= ={137}= ={282}= ={334}= ={383}= ={459}= ={767}= ={769}= ={954}= [initial] [rendered] split chunk (cache group: default)
> ./b [10] ./index.js 2:0-47
> ./c [10] ./index.js 3:0-47
> ./g ./a.js 6:0-47
[568] ./f.js 20 bytes {128} {459} {568} [built]
chunk {767} default/767.js 20 bytes <{179}> ={128}= ={282}= ={334}= ={383}= ={459}= ={568}= ={769}= ={794}= ={954}= >{137}< >{568}< [initial] [rendered] split chunk (cache group: default)
> ./b b
> ./c c
[568] ./f.js 20 bytes {568} [built]
chunk {767} default/767.js 20 bytes <{179}> ={282}= ={334}= ={383}= ={568}= ={769}= ={794}= ={954}= >{137}< >{568}< [rendered] split chunk (cache group: default)
> ./a [10] ./index.js 1:0-47
> ./b [10] ./index.js 2:0-47
> ./c [10] ./index.js 3:0-47
> ./b b
> ./c c
[767] ./d.js 20 bytes {767} {786} [built]
[767] ./d.js 20 bytes {128} {459} {767} {786} [built]
chunk {769} default/769.js 20 bytes <{179}> ={282}= ={383}= ={459}= ={568}= ={767}= [initial] [rendered] split chunk (cache group: defaultVendors)
> ./c [10] ./index.js 3:0-47
> ./c c

View File

@ -6,11 +6,8 @@ module.exports = {
entry: "./test.js",
plugins: [
new IgnorePlugin({
checkResource(resource) {
return /ignored-module/.test(resource);
},
checkContext(context) {
return /folder-b/.test(context);
checkResource(resource, context) {
return /ignored-module/.test(resource) && /folder-b/.test(context);
}
})
]