2019-03-31 22:12:19 +08:00
|
|
|
/*
|
|
|
|
MIT License http://www.opensource.org/licenses/mit-license.php
|
|
|
|
Author Yuta Hiroto @hiroppy
|
|
|
|
*/
|
|
|
|
|
|
|
|
"use strict";
|
|
|
|
|
2019-11-18 00:49:48 +08:00
|
|
|
const validateOptions = require("schema-utils");
|
|
|
|
const schema = require("../../schemas/plugins/AssetModulesPlugin.json");
|
2019-10-16 22:38:04 +08:00
|
|
|
const { compareModulesByIdentifier } = require("../util/comparators");
|
2019-07-16 19:16:27 +08:00
|
|
|
const AssetGenerator = require("./AssetGenerator");
|
|
|
|
const AssetParser = require("./AssetParser");
|
2019-03-31 22:12:19 +08:00
|
|
|
|
|
|
|
/** @typedef {import("webpack-sources").Source} Source */
|
2019-11-26 17:00:11 +08:00
|
|
|
/** @typedef {import("../../declarations/plugins/AssetModulesPlugin").AssetModulesPluginOptions} AssetModulesPluginOptions */
|
2019-03-31 22:12:19 +08:00
|
|
|
/** @typedef {import("../Chunk")} Chunk */
|
|
|
|
/** @typedef {import("../Compiler")} Compiler */
|
|
|
|
/** @typedef {import("../Module")} Module */
|
|
|
|
|
2019-07-16 19:16:27 +08:00
|
|
|
const type = "asset";
|
|
|
|
const plugin = "AssetModulesPlugin";
|
2019-03-31 22:12:19 +08:00
|
|
|
|
2019-11-26 17:00:11 +08:00
|
|
|
/**
|
|
|
|
* @type {Map<string|Buffer, string|null>}
|
|
|
|
*/
|
|
|
|
const dataUrlFnCache = new Map();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param {AssetModulesPluginOptions} options the options to the encoder
|
|
|
|
* @returns {AssetModulesPluginOptions} normalized options
|
|
|
|
*/
|
|
|
|
const prepareOptions = (options = {}) => {
|
|
|
|
const dataUrl = options.dataUrl || {};
|
|
|
|
|
|
|
|
if (options.dataUrl === false) {
|
|
|
|
return {
|
|
|
|
dataUrl: false
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
if (typeof dataUrl === "function") {
|
|
|
|
return {
|
|
|
|
dataUrl: (source, resourcePath) => {
|
|
|
|
if (dataUrlFnCache.has(source)) {
|
|
|
|
return dataUrlFnCache.get(source);
|
|
|
|
}
|
|
|
|
|
|
|
|
const encoded = dataUrl.call(null, source, resourcePath);
|
|
|
|
dataUrlFnCache.set(source, encoded);
|
|
|
|
|
|
|
|
return encoded;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
dataUrl: {
|
|
|
|
encoding: "base64",
|
|
|
|
maxSize: 8192,
|
|
|
|
...dataUrl
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2019-07-16 19:33:45 +08:00
|
|
|
class AssetModulesPlugin {
|
2019-03-31 22:12:19 +08:00
|
|
|
/**
|
|
|
|
* @param {Compiler} compiler webpack compiler
|
|
|
|
* @returns {void}
|
|
|
|
*/
|
|
|
|
apply(compiler) {
|
|
|
|
compiler.hooks.compilation.tap(
|
|
|
|
plugin,
|
|
|
|
(compilation, { normalModuleFactory }) => {
|
|
|
|
normalModuleFactory.hooks.createParser.for(type).tap(plugin, () => {
|
2019-07-16 19:16:27 +08:00
|
|
|
return new AssetParser();
|
2019-03-31 22:12:19 +08:00
|
|
|
});
|
|
|
|
|
2019-11-16 00:27:36 +08:00
|
|
|
normalModuleFactory.hooks.createGenerator
|
|
|
|
.for(type)
|
|
|
|
.tap(plugin, generatorOptions => {
|
2019-11-18 00:49:48 +08:00
|
|
|
validateOptions(schema, generatorOptions, {
|
|
|
|
name: "Asset Modules Plugin"
|
|
|
|
});
|
|
|
|
|
2019-11-26 17:00:11 +08:00
|
|
|
return new AssetGenerator(
|
|
|
|
compilation,
|
|
|
|
prepareOptions(generatorOptions)
|
|
|
|
);
|
2019-03-31 22:12:19 +08:00
|
|
|
});
|
|
|
|
|
2019-10-04 18:24:52 +08:00
|
|
|
compilation.hooks.renderManifest.tap(plugin, (result, options) => {
|
2019-10-09 04:29:46 +08:00
|
|
|
const { chunkGraph } = compilation;
|
|
|
|
const { chunk, runtimeTemplate, codeGenerationResults } = options;
|
2019-03-31 22:12:19 +08:00
|
|
|
|
2019-10-04 18:24:52 +08:00
|
|
|
const { outputOptions } = runtimeTemplate;
|
2019-03-31 22:12:19 +08:00
|
|
|
|
2019-11-20 18:20:34 +08:00
|
|
|
const modules = chunkGraph.getOrderedChunkModulesIterableBySourceType(
|
2019-10-04 18:24:52 +08:00
|
|
|
chunk,
|
2019-11-20 18:20:34 +08:00
|
|
|
"asset",
|
2019-10-16 22:38:04 +08:00
|
|
|
compareModulesByIdentifier
|
2019-11-20 18:20:34 +08:00
|
|
|
);
|
|
|
|
if (modules) {
|
|
|
|
for (const module of modules) {
|
2019-10-04 18:24:52 +08:00
|
|
|
const filename = module.nameForCondition();
|
|
|
|
const filenameTemplate = outputOptions.assetModuleFilename;
|
2019-03-31 22:12:19 +08:00
|
|
|
|
2019-10-04 18:24:52 +08:00
|
|
|
result.push({
|
|
|
|
render: () =>
|
2019-10-09 04:29:46 +08:00
|
|
|
codeGenerationResults.get(module).sources.get(type),
|
2019-10-04 18:24:52 +08:00
|
|
|
filenameTemplate,
|
|
|
|
pathOptions: {
|
|
|
|
module,
|
|
|
|
filename,
|
|
|
|
chunkGraph
|
|
|
|
},
|
|
|
|
auxiliary: true,
|
|
|
|
identifier: `assetModule${chunkGraph.getModuleId(module)}`,
|
|
|
|
hash: chunkGraph.getModuleHash(module)
|
|
|
|
});
|
2019-03-31 22:12:19 +08:00
|
|
|
}
|
|
|
|
}
|
2019-10-04 18:24:52 +08:00
|
|
|
|
|
|
|
return result;
|
|
|
|
});
|
2019-03-31 22:12:19 +08:00
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-16 19:16:27 +08:00
|
|
|
module.exports = AssetModulesPlugin;
|