Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding types #12875

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
34 changes: 12 additions & 22 deletions declarations/WebpackOptions.d.ts
Expand Up @@ -705,11 +705,6 @@ export type AssetParserDataUrlFunction = (
source: string | Buffer,
context: {filename: string; module: import("../lib/Module")}
) => boolean;
/**
* Parser options for asset modules.
*/
export type AssetParserOptions = AssetResourceParserOptions &
AssetParserOptionsExtra;
/**
* A Function returning a Promise resolving to a normalized entry.
*/
Expand Down Expand Up @@ -2577,18 +2572,22 @@ export interface AssetParserDataUrlOptions {
maxSize?: number;
}
/**
* Generator options for asset/resource modules.
* Parser options for asset modules.
*/
export interface AssetResourceGeneratorOptions {
export interface AssetParserOptions {
/**
* This is deprecated and has moved to 'parser.filename'.
* The condition for inlining the asset as DataUrl.
*/
filename?: FilenameTemplate;
dataUrlCondition?: AssetParserDataUrlOptions | AssetParserDataUrlFunction;
}
/**
* Parser options for asset/resource modules.
* Generator options for asset/resource modules.
*/
export interface AssetResourceParserOptions {
export interface AssetResourceGeneratorOptions {
/**
* Emit an output asset from this asset module. This can be set to 'false' to omit emitting e. g. for SSR.
*/
emit?: boolean;
/**
* Specifies the filename template of output files on disk. You must **not** specify an absolute path here, but the path may contain folders separated by '/'! The specified path is joined with the value of the 'output.path' option to determine the location on disk.
*/
Expand Down Expand Up @@ -3142,15 +3141,6 @@ export interface WebpackOptionsNormalized {
*/
watchOptions: WatchOptions;
}
/**
* Parser options for asset modules.
*/
export interface AssetParserOptionsExtra {
/**
* The condition for inlining the asset as DataUrl.
*/
dataUrlCondition?: AssetParserDataUrlOptions | AssetParserDataUrlFunction;
}
/**
* If an dependency matches exactly a property of the object, the property value is used as dependency.
*/
Expand Down Expand Up @@ -3227,9 +3217,9 @@ export interface ParserOptionsByModuleTypeKnown {
*/
"asset/inline"?: EmptyParserOptions;
/**
* Parser options for asset/resource modules.
* No parser options are supported for this module type.
*/
"asset/resource"?: AssetResourceParserOptions;
"asset/resource"?: EmptyParserOptions;
/**
* No parser options are supported for this module type.
*/
Expand Down
6 changes: 5 additions & 1 deletion lib/Chunk.js
Expand Up @@ -592,7 +592,11 @@ class Chunk {
* @returns {Set<Chunk>} a set of all the initial chunks (including itself)
*/
getAllInitialChunks() {
return intersect(Array.from(this.groupsIterable, g => new Set(g.chunks)));
const chunks = new Set();
for (const group of this.groupsIterable) {
for (const c of group.chunks) chunks.add(c);
}
return chunks;
}

/**
Expand Down
7 changes: 2 additions & 5 deletions lib/ChunkGraph.js
Expand Up @@ -683,11 +683,8 @@ class ChunkGraph {
*/
getChunkConditionMap(chunk, filterFn) {
const map = Object.create(null);
for (const asyncChunk of chunk.getAllAsyncChunks()) {
map[asyncChunk.id] = filterFn(asyncChunk, this);
}
for (const depChunk of this.getChunkEntryDependentChunksIterable(chunk)) {
map[depChunk.id] = filterFn(depChunk, this);
for (const c of chunk.getAllReferencedChunks()) {
map[c.id] = filterFn(c, this);
}
return map;
}
Expand Down
1 change: 1 addition & 0 deletions lib/Compilation.js
Expand Up @@ -788,6 +788,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
this.mainTemplate = new MainTemplate(this.outputOptions, this);
this.chunkTemplate = new ChunkTemplate(this.outputOptions, this);
this.runtimeTemplate = new RuntimeTemplate(
this,
this.outputOptions,
this.requestShortener
);
Expand Down
15 changes: 15 additions & 0 deletions lib/Dependency.js
Expand Up @@ -5,6 +5,8 @@

"use strict";

const memoize = require("./util/memoize");

/** @typedef {import("webpack-sources").Source} Source */
/** @typedef {import("./ChunkGraph")} ChunkGraph */
/** @typedef {import("./DependencyTemplates")} DependencyTemplates */
Expand Down Expand Up @@ -73,6 +75,11 @@
* @property {boolean=} canMangle when false, referenced export can not be mangled, defaults to true
*/

const getIgnoredModule = memoize(() => {
const RawModule = require("./RawModule");
return new RawModule("/* (ignored) */", `ignored`, `(ignored)`);
});

class Dependency {
constructor() {
// TODO check if this can be moved into ModuleDependency
Expand Down Expand Up @@ -187,6 +194,14 @@ class Dependency {
return true;
}

/**
* @param {string} context context directory
* @returns {Module} a module
*/
createIgnoredModule(context) {
return getIgnoredModule();
}

serialize({ write }) {
write(this.weak);
write(this.optional);
Expand Down
10 changes: 1 addition & 9 deletions lib/NormalModuleFactory.js
Expand Up @@ -16,7 +16,6 @@ const {
const Module = require("./Module");
const ModuleFactory = require("./ModuleFactory");
const NormalModule = require("./NormalModule");
const RawModule = require("./RawModule");
const BasicEffectRulePlugin = require("./rules/BasicEffectRulePlugin");
const BasicMatcherRulePlugin = require("./rules/BasicMatcherRulePlugin");
const DescriptionDataMatcherRulePlugin = require("./rules/DescriptionDataMatcherRulePlugin");
Expand Down Expand Up @@ -427,14 +426,7 @@ class NormalModuleFactory extends ModuleFactory {

if (!resourceData) {
// ignored
return callback(
null,
new RawModule(
"/* (ignored) */",
`ignored|${request}`,
`${request} (ignored)`
)
);
return callback(null, dependencies[0].createIgnoredModule(context));
}

const userRequest =
Expand Down
16 changes: 11 additions & 5 deletions lib/RawModule.js
Expand Up @@ -28,14 +28,18 @@ const makeSerializable = require("./util/makeSerializable");
const TYPES = new Set(["javascript"]);

class RawModule extends Module {
constructor(source, identifier, readableIdentifier) {
/**
* @param {string} source source code
* @param {string} identifier unique identifier
* @param {string=} readableIdentifier readable identifier
* @param {ReadonlySet<string>=} runtimeRequirements runtime requirements needed for the source code
*/
constructor(source, identifier, readableIdentifier, runtimeRequirements) {
super("javascript/dynamic", null);
/** @type {string} */
this.sourceStr = source;
/** @type {string} */
this.identifierStr = identifier || this.sourceStr;
/** @type {string} */
this.readableIdentifierStr = readableIdentifier || this.identifierStr;
this.runtimeRequirements = runtimeRequirements || null;
}

/**
Expand Down Expand Up @@ -107,7 +111,7 @@ class RawModule extends Module {
} else {
sources.set("javascript", new RawSource(this.sourceStr));
}
return { sources, runtimeRequirements: null };
return { sources, runtimeRequirements: this.runtimeRequirements };
}

/**
Expand All @@ -126,6 +130,7 @@ class RawModule extends Module {
write(this.sourceStr);
write(this.identifierStr);
write(this.readableIdentifierStr);
write(this.runtimeRequirements);

super.serialize(context);
}
Expand All @@ -136,6 +141,7 @@ class RawModule extends Module {
this.sourceStr = read();
this.identifierStr = read();
this.readableIdentifierStr = read();
this.runtimeRequirements = read();

super.deserialize(context);
}
Expand Down
6 changes: 4 additions & 2 deletions lib/RuntimeTemplate.js
Expand Up @@ -16,6 +16,7 @@ const { forEachRuntime, subtractRuntime } = require("./util/runtime");
/** @typedef {import("../declarations/WebpackOptions").OutputNormalized} OutputOptions */
/** @typedef {import("./AsyncDependenciesBlock")} AsyncDependenciesBlock */
/** @typedef {import("./ChunkGraph")} ChunkGraph */
/** @typedef {import("./Compilation")} Compilation */
/** @typedef {import("./Dependency")} Dependency */
/** @typedef {import("./Module")} Module */
/** @typedef {import("./ModuleGraph")} ModuleGraph */
Expand Down Expand Up @@ -51,12 +52,13 @@ Module has these incoming connections: ${Array.from(

class RuntimeTemplate {
/**
* @param {Compilation} compilation the compilation
* @param {OutputOptions} outputOptions the compilation output options
* @param {RequestShortener} requestShortener the request shortener
*/
constructor(outputOptions, requestShortener) {
constructor(compilation, outputOptions, requestShortener) {
this.compilation = compilation;
this.outputOptions = outputOptions || {};
/** @type {RequestShortener} */
this.requestShortener = requestShortener;
}

Expand Down
60 changes: 51 additions & 9 deletions lib/asset/AssetGenerator.js
Expand Up @@ -10,6 +10,8 @@ const path = require("path");
const { RawSource } = require("webpack-sources");
const Generator = require("../Generator");
const RuntimeGlobals = require("../RuntimeGlobals");
const createHash = require("../util/createHash");
const { makePathsRelative } = require("../util/identifier");

/** @typedef {import("webpack-sources").Source} Source */
/** @typedef {import("../../declarations/WebpackOptions").AssetGeneratorOptions} AssetGeneratorOptions */
Expand All @@ -29,11 +31,13 @@ class AssetGenerator extends Generator {
/**
* @param {AssetGeneratorOptions["dataUrl"]=} dataUrlOptions the options for the data url
* @param {string=} filename override for output.assetModuleFilename
* @param {boolean=} emit generate output asset
*/
constructor(dataUrlOptions, filename) {
constructor(dataUrlOptions, filename, emit) {
super();
this.dataUrlOptions = dataUrlOptions;
this.filename = filename;
this.emit = emit;
}

/**
Expand Down Expand Up @@ -107,22 +111,60 @@ class AssetGenerator extends Generator {
)};`
);
} else {
const assetModuleFilename =
this.filename || runtimeTemplate.outputOptions.assetModuleFilename;
const hash = createHash(runtimeTemplate.outputOptions.hashFunction);
if (runtimeTemplate.outputOptions.hashSalt) {
hash.update(runtimeTemplate.outputOptions.hashSalt);
}
hash.update(originalSource.buffer());
const fullHash = /** @type {string} */ (hash.digest(
runtimeTemplate.outputOptions.hashDigest
));
const contentHash = fullHash.slice(
0,
runtimeTemplate.outputOptions.hashDigestLength
);
module.buildInfo.fullContentHash = fullHash;
const sourceFilename = makePathsRelative(
runtimeTemplate.compilation.compiler.context,
module.matchResource || module.resource,
runtimeTemplate.compilation.compiler.root
).replace(/^\.\//, "");
const {
path: filename,
info
} = runtimeTemplate.compilation.getAssetPathWithInfo(
assetModuleFilename,
{
module,
runtime,
filename: sourceFilename,
chunkGraph,
contentHash
}
);
module.buildInfo.filename = filename;
module.buildInfo.assetInfo = {
sourceFilename,
...info
};
if (getData) {
// We did a mistake in some minor version of 5.x
// Now we have to keep it for backward-compat reasons
// TODO webpack 6 remove
// Due to code generation caching module.buildInfo.XXX can't used to store such information
// It need to be stored in the code generation results instead, where it's cached too
// TODO webpack 6 For back-compat reasons we also store in on module.buildInfo
const data = getData();
data.set("fullContentHash", module.buildInfo.fullContentHash);
data.set("filename", module.buildInfo.filename);
data.set("assetInfo", module.buildInfo.assetInfo);
data.set("fullContentHash", fullHash);
data.set("filename", filename);
data.set("assetInfo", info);
}

runtimeRequirements.add(RuntimeGlobals.publicPath); // add __webpack_require__.p

return new RawSource(
`${RuntimeGlobals.module}.exports = ${
RuntimeGlobals.publicPath
} + ${JSON.stringify(module.buildInfo.filename)};`
} + ${JSON.stringify(filename)};`
);
}
}
Expand All @@ -134,7 +176,7 @@ class AssetGenerator extends Generator {
* @returns {Set<string>} available types (do not mutate)
*/
getTypes(module) {
if (module.buildInfo.dataUrl) {
if (module.buildInfo.dataUrl || this.emit === false) {
return JS_TYPES;
} else {
return JS_AND_ASSET_TYPES;
Expand Down
22 changes: 16 additions & 6 deletions lib/asset/AssetModulesPlugin.js
Expand Up @@ -71,7 +71,7 @@ class AssetModulesPlugin {

const AssetParser = getAssetParser();

return new AssetParser(dataUrlCondition, parserOptions.filename);
return new AssetParser(dataUrlCondition);
});
normalModuleFactory.hooks.createParser
.for("asset/inline")
Expand All @@ -85,7 +85,7 @@ class AssetModulesPlugin {
.tap(plugin, parserOptions => {
const AssetParser = getAssetParser();

return new AssetParser(false, parserOptions.filename);
return new AssetParser(false);
});
normalModuleFactory.hooks.createParser
.for("asset/source")
Expand Down Expand Up @@ -124,7 +124,11 @@ class AssetModulesPlugin {

const AssetGenerator = getAssetGenerator();

return new AssetGenerator(dataUrl, filename);
return new AssetGenerator(
dataUrl,
filename,
generatorOptions.emit !== false
);
});
}
normalModuleFactory.hooks.createGenerator
Expand Down Expand Up @@ -152,11 +156,17 @@ class AssetModulesPlugin {
);
result.push({
render: () => codeGenResult.sources.get(type),
filename: module.buildInfo.filename,
info: module.buildInfo.assetInfo,
filename:
module.buildInfo.filename ||
codeGenResult.data.get("filename"),
info:
module.buildInfo.assetInfo ||
codeGenResult.data.get("assetInfo"),
auxiliary: true,
identifier: `assetModule${chunkGraph.getModuleId(module)}`,
hash: module.buildInfo.fullContentHash
hash:
module.buildInfo.fullContentHash ||
codeGenResult.data.get("fullContentHash")
});
}
}
Expand Down