make libIdent required

add types
This commit is contained in:
Tobias Koppers 2018-07-20 16:24:35 +02:00
parent 78f01763a2
commit ec1329a7d4
20 changed files with 156 additions and 40 deletions

View File

@ -14,7 +14,7 @@ const DependenciesBlock = require("./DependenciesBlock");
/** @typedef {import("./util/createHash").Hash} Hash */
/** @typedef {TODO} GroupOptions */
module.exports = class AsyncDependenciesBlock extends DependenciesBlock {
class AsyncDependenciesBlock extends DependenciesBlock {
/**
* @param {GroupOptions} groupOptions options for the group
* @param {Module} module the Module object
@ -36,6 +36,8 @@ module.exports = class AsyncDependenciesBlock extends DependenciesBlock {
this.request = request;
/** @type {DependenciesBlock} */
this.parent = undefined;
/** @type {[number, number]} */
this.range = undefined;
}
/**
@ -96,4 +98,6 @@ module.exports = class AsyncDependenciesBlock extends DependenciesBlock {
sortItems(sortChunks) {
super.sortItems();
}
};
}
module.exports = AsyncDependenciesBlock;

View File

@ -109,9 +109,9 @@ class Chunk {
* @param {string=} name of chunk being created, is optional (for subclasses)
*/
constructor(name) {
/** @type {number | null} */
/** @type {number | string | null} */
this.id = null;
/** @type {number[] | null} */
/** @type {(number|string)[] | null} */
this.ids = null;
/** @type {number} */
this.debugId = debugId++;
@ -227,7 +227,7 @@ class Chunk {
}
/**
* @returns {SortableSet} return the modules SortableSet for this chunk
* @returns {SortableSet<Module>} return the modules SortableSet for this chunk
*/
get modulesIterable() {
return this._modules;

View File

@ -14,6 +14,7 @@ const contextify = require("./util/identifier").contextify;
/** @typedef {import("webpack-sources").Source} Source */
/** @typedef {import("./Compilation")} Compilation */
/** @typedef {import("./DependencyTemplates")} DependencyTemplates */
/** @typedef {import("./Module").LibIdentOptions} LibIdentOptions */
/** @typedef {import("./Module").SourceContext} SourceContext */
/** @typedef {import("./RequestShortener")} RequestShortener */
/** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */
@ -183,6 +184,10 @@ class ContextModule extends Module {
return identifier;
}
/**
* @param {LibIdentOptions} options options
* @returns {string | null} an identifier for library inclusion
*/
libIdent(options) {
let identifier = contextify(options.context, this.context);
if (this.options.mode) {

View File

@ -14,6 +14,7 @@ const DelegatedSourceDependency = require("./dependencies/DelegatedSourceDepende
/** @typedef {import("webpack-sources").Source} Source */
/** @typedef {import("./Compilation")} Compilation */
/** @typedef {import("./DependencyTemplates")} DependencyTemplates */
/** @typedef {import("./Module").LibIdentOptions} LibIdentOptions */
/** @typedef {import("./Module").SourceContext} SourceContext */
/** @typedef {import("./RequestShortener")} RequestShortener */
/** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */
@ -36,6 +37,10 @@ class DelegatedModule extends Module {
this.delegatedSourceDependency = undefined;
}
/**
* @param {LibIdentOptions} options options
* @returns {string | null} an identifier for library inclusion
*/
libIdent(options) {
return typeof this.originalRequest === "string"
? this.originalRequest

View File

@ -74,8 +74,8 @@ class DelegatedModuleFactoryPlugin {
normalModuleFactory.hooks.module.tap(
"DelegatedModuleFactoryPlugin",
module => {
if (module.libIdent) {
const request = module.libIdent(this.options);
const request = module.libIdent(this.options);
if (request) {
if (request && request in this.options.content) {
const resolved = this.options.content[request];
return new DelegatedModule(

View File

@ -13,6 +13,7 @@ const Template = require("./Template");
/** @typedef {import("./Chunk")} Chunk */
/** @typedef {import("./Compilation")} Compilation */
/** @typedef {import("./DependencyTemplates")} DependencyTemplates */
/** @typedef {import("./Module").LibIdentOptions} LibIdentOptions */
/** @typedef {import("./Module").SourceContext} SourceContext */
/** @typedef {import("./RequestShortener")} RequestShortener */
/** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */
@ -102,7 +103,7 @@ class ExternalModule extends Module {
super("javascript/dynamic", null);
// Info from Factory
/** @type {string} */
/** @type {string | string[] | Record<string, string | string[]>} */
this.request = request;
/** @type {string} */
this.externalType = type;
@ -113,9 +114,10 @@ class ExternalModule extends Module {
}
/**
* @returns {string} the external module identifier
* @param {LibIdentOptions} options options
* @returns {string | null} an identifier for library inclusion
*/
libIdent() {
libIdent(options) {
return this.userRequest;
}

View File

@ -11,6 +11,12 @@
/** @typedef {false | true | string[]} UsedExports */
/**
* @template T
* @param {T[]} a array (will be modified)
* @param {T[]} b array (will be added to a)
* @returns {T[]} a again
*/
const addToSet = (a, b) => {
for (const item of b) {
if (!a.includes(item)) a.push(item);
@ -34,6 +40,12 @@ class FlagDependencyUsagePlugin {
compilation.hooks.optimizeDependencies.tap(
"FlagDependencyUsagePlugin",
modules => {
/**
*
* @param {Module} module module to process
* @param {string[] | boolean} usedExports list of used exports
* @returns {void}
*/
const processModule = (module, usedExports) => {
module.used = true;
if (module.usedExports === true) return;

View File

@ -5,11 +5,17 @@
"use strict";
/** @typedef {import("./Compiler")} Compiler */
class FlagInitialModulesAsUsedPlugin {
constructor(explanation) {
this.explanation = explanation;
}
/**
* @param {Compiler} compiler webpack compiler
* @returns {void}
*/
apply(compiler) {
compiler.hooks.compilation.tap(
"FlagInitialModulesAsUsedPlugin",

View File

@ -33,17 +33,19 @@ class HashedModuleIdsPlugin {
"HashedModuleIdsPlugin",
modules => {
for (const module of modules) {
if (module.id === null && module.libIdent) {
if (module.id === null) {
const id = module.libIdent({
context: this.options.context || compiler.options.context
});
const hash = createHash(options.hashFunction);
hash.update(id);
const hashId = hash.digest(options.hashDigest);
let len = options.hashDigestLength;
while (usedIds.has(hashId.substr(0, len))) len++;
module.id = hashId.substr(0, len);
usedIds.add(module.id);
if (id) {
const hash = createHash(options.hashFunction);
hash.update(id);
const hashId = hash.digest(options.hashDigest);
let len = options.hashDigestLength;
while (usedIds.has(hashId.substr(0, len))) len++;
module.id = hashId.substr(0, len);
usedIds.add(module.id);
}
}
}
}

View File

@ -20,6 +20,9 @@ const ConstDependency = require("./dependencies/ConstDependency");
const ModuleHotAcceptDependency = require("./dependencies/ModuleHotAcceptDependency");
const ModuleHotDeclineDependency = require("./dependencies/ModuleHotDeclineDependency");
/** @typedef {import("./Compiler")} Compiler */
/** @typedef {import("./Module")} Module */
const hotInitCode = Template.getFunctionContent(
require("./HotModuleReplacement.runtime")
);
@ -51,6 +54,10 @@ module.exports = class HotModuleReplacementPlugin {
this.requestTimeout = this.options.requestTimeout || 10000;
}
/**
* @param {Compiler} compiler webpack compiler
* @returns {void}
*/
apply(compiler) {
const multiStep = this.multiStep;
const fullBuildTimeout = this.fullBuildTimeout;
@ -259,10 +266,14 @@ module.exports = class HotModuleReplacementPlugin {
!records.chunkModuleIds
)
return;
/** @type {Set<Module>} */
const updatedModules = new Set();
for (const module of compilation.modules) {
const identifier = module.identifier();
let hash = module.hash;
module.hotUpdate = records.moduleHashs[identifier] !== hash;
const hash = module.hash;
if (records.moduleHashs[identifier] !== hash) {
updatedModules.add(module);
}
}
const hotUpdateMainContent = {
h: compilation.hash,
@ -276,7 +287,8 @@ module.exports = class HotModuleReplacementPlugin {
if (currentChunk) {
const newModules = currentChunk
.getModules()
.filter(module => module.hotUpdate);
.filter(module => updatedModules.has(module));
/** @type {Set<number|string>} */
const allModules = new Set();
for (const module of currentChunk.modulesIterable) {
allModules.add(module.id);

View File

@ -47,19 +47,17 @@ class LibManifestPlugin {
) {
return;
}
if (module.libIdent) {
const ident = module.libIdent({
context: this.options.context || compiler.options.context
});
if (ident) {
return {
ident,
data: {
id: module.id,
buildMeta: module.buildMeta
}
};
}
const ident = module.libIdent({
context: this.options.context || compiler.options.context
});
if (ident) {
return {
ident,
data: {
id: module.id,
buildMeta: module.buildMeta
}
};
}
})
.filter(Boolean)

View File

@ -28,6 +28,11 @@ const SortableSet = require("./util/SortableSet");
* @property {string=} type the type of source that should be generated
*/
/**
* @typedef {Object} LibIdentOptions
* @property {string} context absolute context path to which lib ident is relative to
*/
const EMPTY_RESOLVE_OPTIONS = {};
let debugId = 1000;
@ -498,6 +503,14 @@ class Module extends DependenciesBlock {
throw new Error("Module.size: Must be overriden");
}
/**
* @param {LibIdentOptions} options options
* @returns {string | null} an identifier for library inclusion
*/
libIdent(options) {
return null;
}
/**
* @returns {string | null} absolute path which should be used for condition matching (usually the resource path)
*/

View File

@ -26,8 +26,11 @@ class NamedModulesPlugin {
const context = this.options.context || compiler.options.context;
for (const module of modules) {
if (module.id === null && module.libIdent) {
module.id = module.libIdent({ context });
if (module.id === null) {
const id = module.libIdent({ context });
if (id) {
module.id = id;
}
}
if (module.id !== null) {

View File

@ -26,6 +26,7 @@ const contextify = require("./util/identifier").contextify;
/** @typedef {import("webpack-sources").Source} Source */
/** @typedef {import("./Compilation")} Compilation */
/** @typedef {import("./DependencyTemplates")} DependencyTemplates */
/** @typedef {import("./Module").LibIdentOptions} LibIdentOptions */
/** @typedef {import("./Module").SourceContext} SourceContext */
/** @typedef {import("./RequestShortener")} RequestShortener */
/** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */
@ -121,6 +122,10 @@ class NormalModule extends Module {
return requestShortener.shorten(this.userRequest);
}
/**
* @param {LibIdentOptions} options options
* @returns {string | null} an identifier for library inclusion
*/
libIdent(options) {
return contextify(options.context, this.userRequest);
}

View File

@ -6,8 +6,11 @@
"use strict";
const { ConcatSource, OriginalSource } = require("webpack-sources");
const ExternalModule = require("./ExternalModule");
const Template = require("./Template");
/** @typedef {import("webpack-sources").Source} Source */
/** @typedef {import("./Chunk")} Chunk */
/** @typedef {import("./Compilation")} Compilation */
/**
@ -85,14 +88,21 @@ class UmdMainTemplatePlugin {
apply(compilation) {
const { mainTemplate, chunkTemplate, runtimeTemplate } = compilation;
/**
* @param {Source} source source
* @param {Chunk} chunk chunk
* @param {string} hash Hash
* @returns {Source} new source
*/
const onRenderWithEntry = (source, chunk, hash) => {
let externals = chunk
/** @type {ExternalModule[]} */
let externals = /** @type {ExternalModule[]} */ (chunk
.getModules()
.filter(
m =>
m.external &&
m instanceof ExternalModule &&
(m.externalType === "umd" || m.externalType === "umd2")
);
));
const optionalExternals = [];
let requiredExternals = [];
if (this.optionalAmdExternalAsGlobal) {

View File

@ -20,12 +20,17 @@ module.exports = class RequireEnsureDependenciesBlock extends AsyncDependenciesB
) {
super(chunkName, module, loc, null);
this.expr = expr;
/** @type {[number, number] | undefined} */
const successBodyRange =
successExpression &&
successExpression.body &&
successExpression.body.range;
if (successBodyRange) {
this.range = [successBodyRange[0] + 1, successBodyRange[1] - 1];
const range = /** @type {[number, number]} */ ([
successBodyRange[0] + 1,
successBodyRange[1] - 1
]);
this.range = range;
}
this.chunkNameRange = chunkNameRange;
const dep = new RequireEnsureDependency(this);

View File

@ -7,7 +7,13 @@
const { ConcatSource } = require("webpack-sources");
/** @typedef {import("../ChunkTemplate")} ChunkTemplate */
class NodeChunkTemplatePlugin {
/**
* @param {ChunkTemplate} chunkTemplate the chunk template
* @returns {void}
*/
apply(chunkTemplate) {
chunkTemplate.hooks.render.tap(
"NodeChunkTemplatePlugin",

View File

@ -27,6 +27,7 @@ const createHash = require("../util/createHash");
/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
/** @typedef {import("../DependencyTemplates")} DependencyTemplates */
/** @typedef {import("../InitFragment")} InitFragment */
/** @typedef {import("../Module").LibIdentOptions} LibIdentOptions */
/** @typedef {import("../Module").SourceContext} SourceContext */
/** @typedef {import("../RequestShortener")} RequestShortener */
/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
@ -410,6 +411,10 @@ class ConcatenatedModule extends Module {
);
}
/**
* @param {LibIdentOptions} options options
* @returns {string | null} an identifier for library inclusion
*/
libIdent(options) {
return this.rootModule.libIdent(options);
}

View File

@ -8,12 +8,19 @@
const validateOptions = require("schema-utils");
const schema = require("../../schemas/plugins/optimize/OccurrenceOrderModuleIdsPlugin.json");
/** @typedef {import("../Compiler")} Compiler */
/** @typedef {import("../ModuleReason")} ModuleReason */
class OccurrenceOrderModuleIdsPlugin {
constructor(options = {}) {
validateOptions(schema, options, "Occurrence Order Module Ids Plugin");
this.options = options;
}
/**
* @param {Compiler} compiler webpack compiler
* @returns {void}
*/
apply(compiler) {
const prioritiseInitial = this.options.prioritiseInitial;
compiler.hooks.compilation.tap(
@ -38,12 +45,23 @@ class OccurrenceOrderModuleIdsPlugin {
entryCountMap.set(m, entry);
}
/**
* @param {number} sum sum of occurs
* @param {ModuleReason} r module reason
* @returns {number} count of occurs
*/
const countOccursInEntry = (sum, r) => {
if (!r.module) {
return sum;
}
return sum + initialChunkChunkMap.get(r.module);
};
/**
* @param {number} sum sum of occurs
* @param {ModuleReason} r module reason
* @returns {number} count of occurs
*/
const countOccurs = (sum, r) => {
if (!r.module) {
return sum;

View File

@ -9,6 +9,7 @@ const mm = require("micromatch");
const HarmonyExportImportedSpecifierDependency = require("../dependencies/HarmonyExportImportedSpecifierDependency");
const HarmonyImportSpecifierDependency = require("../dependencies/HarmonyImportSpecifierDependency");
/** @typedef {import("../Compiler")} Compiler */
/** @typedef {import("../Dependency")} Dependency */
/** @typedef {import("../Module")} Module */
@ -19,6 +20,10 @@ const HarmonyImportSpecifierDependency = require("../dependencies/HarmonyImportS
*/
class SideEffectsFlagPlugin {
/**
* @param {Compiler} compiler webpack compiler
* @returns {void}
*/
apply(compiler) {
compiler.hooks.normalModuleFactory.tap("SideEffectsFlagPlugin", nmf => {
nmf.hooks.module.tap("SideEffectsFlagPlugin", (module, data) => {