webpack
Version:
Packs CommonJs/AMD modules for the browser. Allows to split your codebase into multiple bundles, which can be loaded on demand. Support loaders to preprocess files, i.e. json, jsx, es7, css, less, ... and your custom stuff.
180 lines (155 loc) • 4.75 kB
JavaScript
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Yuta Hiroto @hiroppy
*/
;
const { validate } = require("schema-utils");
const { compareModulesByIdentifier } = require("../util/comparators");
const memorize = require("../util/memorize");
/** @typedef {import("webpack-sources").Source} Source */
/** @typedef {import("../Chunk")} Chunk */
/** @typedef {import("../Compiler")} Compiler */
/** @typedef {import("../Module")} Module */
const getGeneratorSchema = memorize(() =>
require("../../schemas/plugins/AssetModulesPluginGenerator.json")
);
const getGeneratorSchemaMap = {
asset: getGeneratorSchema,
"asset/resource": memorize(() => {
const base = getGeneratorSchema();
return {
...base,
properties: {
...base.properties,
dataUrl: false
}
};
}),
"asset/inline": memorize(() => {
const base = getGeneratorSchema();
return {
...base,
properties: {
...base.properties,
filename: false
}
};
})
};
const getParserSchema = memorize(() =>
require("../../schemas/plugins/AssetModulesPluginParser.json")
);
const getAssetGenerator = memorize(() => require("./AssetGenerator"));
const getAssetParser = memorize(() => require("./AssetParser"));
const getAssetSourceGenerator = memorize(() =>
require("./AssetSourceGenerator")
);
const type = "asset";
const plugin = "AssetModulesPlugin";
class AssetModulesPlugin {
/**
* Apply the plugin
* @param {Compiler} compiler the compiler instance
* @returns {void}
*/
apply(compiler) {
compiler.hooks.compilation.tap(
plugin,
(compilation, { normalModuleFactory }) => {
normalModuleFactory.hooks.createParser
.for("asset")
.tap(plugin, parserOptions => {
validate(getParserSchema(), parserOptions, {
name: "Asset Modules Plugin",
baseDataPath: "parser"
});
let dataUrlCondition = parserOptions.dataUrlCondition;
if (!dataUrlCondition || typeof dataUrlCondition === "object") {
dataUrlCondition = {
maxSize: 8096,
...dataUrlCondition
};
}
const AssetParser = getAssetParser();
return new AssetParser(dataUrlCondition);
});
normalModuleFactory.hooks.createParser
.for("asset/inline")
.tap(plugin, parserOptions => {
const AssetParser = getAssetParser();
return new AssetParser(true);
});
normalModuleFactory.hooks.createParser
.for("asset/resource")
.tap(plugin, parserOptions => {
const AssetParser = getAssetParser();
return new AssetParser(false);
});
normalModuleFactory.hooks.createParser
.for("asset/source")
.tap(plugin, parserOptions => {
const AssetParser = getAssetParser();
return new AssetParser(false);
});
for (const type of ["asset", "asset/inline", "asset/resource"]) {
normalModuleFactory.hooks.createGenerator
.for(type)
// eslint-disable-next-line no-loop-func
.tap(plugin, generatorOptions => {
validate(getGeneratorSchemaMap[type](), generatorOptions, {
name: "Asset Modules Plugin",
baseDataPath: "generator"
});
let dataUrl = undefined;
if (type !== "asset/resource") {
dataUrl = generatorOptions.dataUrl;
if (!dataUrl || typeof dataUrl === "object") {
dataUrl = {
encoding: "base64",
mimetype: undefined,
...dataUrl
};
}
}
let filename = undefined;
if (type !== "asset/inline") {
filename = generatorOptions.filename;
}
const AssetGenerator = getAssetGenerator();
return new AssetGenerator(compilation, dataUrl, filename);
});
}
normalModuleFactory.hooks.createGenerator
.for("asset/source")
.tap(plugin, () => {
const AssetSourceGenerator = getAssetSourceGenerator();
return new AssetSourceGenerator();
});
compilation.hooks.renderManifest.tap(plugin, (result, options) => {
const { chunkGraph } = compilation;
const { chunk, codeGenerationResults } = options;
const modules = chunkGraph.getOrderedChunkModulesIterableBySourceType(
chunk,
"asset",
compareModulesByIdentifier
);
if (modules) {
for (const module of modules) {
result.push({
render: () =>
codeGenerationResults.getSource(module, chunk.runtime, type),
filename: module.buildInfo.filename,
info: module.buildInfo.assetInfo,
auxiliary: true,
identifier: `assetModule${chunkGraph.getModuleId(module)}`,
hash: module.buildInfo.fullContentHash
});
}
}
return result;
});
}
);
}
}
module.exports = AssetModulesPlugin;