mirror of https://github.com/webpack/webpack.git
perf: improve FlagDependencyExportsPlugin for large JSON by depth
This commit is contained in:
parent
3612d36e44
commit
38df65df32
|
@ -78,6 +78,8 @@ class WebpackOptionsApply extends OptionsApply {
|
||||||
compiler.recordsOutputPath = options.recordsOutputPath || null;
|
compiler.recordsOutputPath = options.recordsOutputPath || null;
|
||||||
compiler.name = options.name;
|
compiler.name = options.name;
|
||||||
|
|
||||||
|
const development = options.mode === "development";
|
||||||
|
|
||||||
if (options.externals) {
|
if (options.externals) {
|
||||||
// @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
|
// @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
|
||||||
const ExternalsPlugin = require("./ExternalsPlugin");
|
const ExternalsPlugin = require("./ExternalsPlugin");
|
||||||
|
@ -290,7 +292,9 @@ class WebpackOptionsApply extends OptionsApply {
|
||||||
}
|
}
|
||||||
|
|
||||||
new JavascriptModulesPlugin().apply(compiler);
|
new JavascriptModulesPlugin().apply(compiler);
|
||||||
new JsonModulesPlugin().apply(compiler);
|
new JsonModulesPlugin({
|
||||||
|
depth: development ? 1 : Infinity
|
||||||
|
}).apply(compiler);
|
||||||
new AssetModulesPlugin().apply(compiler);
|
new AssetModulesPlugin().apply(compiler);
|
||||||
|
|
||||||
if (!options.experiments.outputModule) {
|
if (!options.experiments.outputModule) {
|
||||||
|
|
|
@ -19,41 +19,47 @@ const NullDependency = require("./NullDependency");
|
||||||
/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
|
/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
|
||||||
/** @typedef {import("../util/Hash")} Hash */
|
/** @typedef {import("../util/Hash")} Hash */
|
||||||
|
|
||||||
|
/** @typedef {{depth:number}} JsonDependencyOptions */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {RawJsonData} data data
|
* @param {number} depth depth
|
||||||
* @returns {TODO} value
|
* @returns {((data: RawJsonData, curDepth?: number) => ExportSpec[] | undefined)} value
|
||||||
*/
|
*/
|
||||||
const getExportsFromData = data => {
|
const getExportsWithDepth = depth =>
|
||||||
if (data && typeof data === "object") {
|
function getExportsFromData(data, curDepth = 1) {
|
||||||
if (Array.isArray(data)) {
|
if (curDepth > depth) return undefined;
|
||||||
return data.length < 100
|
if (data && typeof data === "object") {
|
||||||
? data.map((item, idx) => ({
|
if (Array.isArray(data)) {
|
||||||
name: `${idx}`,
|
return data.length < 100
|
||||||
canMangle: true,
|
? data.map((item, idx) => ({
|
||||||
exports: getExportsFromData(item)
|
name: `${idx}`,
|
||||||
}))
|
canMangle: true,
|
||||||
: undefined;
|
exports: getExportsFromData(item, curDepth + 1)
|
||||||
|
}))
|
||||||
|
: undefined;
|
||||||
|
}
|
||||||
|
const exports = [];
|
||||||
|
for (const key of Object.keys(data)) {
|
||||||
|
exports.push({
|
||||||
|
name: key,
|
||||||
|
canMangle: true,
|
||||||
|
exports: getExportsFromData(data[key], curDepth + 1)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return exports;
|
||||||
}
|
}
|
||||||
const exports = [];
|
return undefined;
|
||||||
for (const key of Object.keys(data)) {
|
};
|
||||||
exports.push({
|
|
||||||
name: key,
|
|
||||||
canMangle: true,
|
|
||||||
exports: getExportsFromData(data[key])
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return exports;
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
class JsonExportsDependency extends NullDependency {
|
class JsonExportsDependency extends NullDependency {
|
||||||
/**
|
/**
|
||||||
* @param {JsonData} data json data
|
* @param {JsonData} data json data
|
||||||
|
* @param {JsonDependencyOptions} dependencyOptions dependency options
|
||||||
*/
|
*/
|
||||||
constructor(data) {
|
constructor(data, dependencyOptions) {
|
||||||
super();
|
super();
|
||||||
this.data = data;
|
this.data = data;
|
||||||
|
this.options = dependencyOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
get type() {
|
get type() {
|
||||||
|
@ -67,7 +73,7 @@ class JsonExportsDependency extends NullDependency {
|
||||||
*/
|
*/
|
||||||
getExports(moduleGraph) {
|
getExports(moduleGraph) {
|
||||||
return {
|
return {
|
||||||
exports: getExportsFromData(
|
exports: getExportsWithDepth(this.options.depth)(
|
||||||
this.data && /** @type {RawJsonData} */ (this.data.get())
|
this.data && /** @type {RawJsonData} */ (this.data.get())
|
||||||
),
|
),
|
||||||
dependencies: undefined
|
dependencies: undefined
|
||||||
|
|
|
@ -11,6 +11,7 @@ const JsonGenerator = require("./JsonGenerator");
|
||||||
const JsonParser = require("./JsonParser");
|
const JsonParser = require("./JsonParser");
|
||||||
|
|
||||||
/** @typedef {import("../Compiler")} Compiler */
|
/** @typedef {import("../Compiler")} Compiler */
|
||||||
|
/** @typedef {import("../dependencies/JsonExportsDependency").JsonDependencyOptions} JsonDependencyOptions */
|
||||||
/** @typedef {Record<string, any>} RawJsonData */
|
/** @typedef {Record<string, any>} RawJsonData */
|
||||||
|
|
||||||
const validate = createSchemaValidation(
|
const validate = createSchemaValidation(
|
||||||
|
@ -29,6 +30,13 @@ const PLUGIN_NAME = "JsonModulesPlugin";
|
||||||
* It adds the json module type to the compiler and registers the json parser and generator.
|
* It adds the json module type to the compiler and registers the json parser and generator.
|
||||||
*/
|
*/
|
||||||
class JsonModulesPlugin {
|
class JsonModulesPlugin {
|
||||||
|
/**
|
||||||
|
* @param {JsonDependencyOptions} dependencyOptions dependency options
|
||||||
|
*/
|
||||||
|
constructor(dependencyOptions) {
|
||||||
|
this.dependencyOptions = dependencyOptions;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply the plugin
|
* Apply the plugin
|
||||||
* @param {Compiler} compiler the compiler instance
|
* @param {Compiler} compiler the compiler instance
|
||||||
|
@ -43,7 +51,7 @@ class JsonModulesPlugin {
|
||||||
.tap(PLUGIN_NAME, parserOptions => {
|
.tap(PLUGIN_NAME, parserOptions => {
|
||||||
validate(parserOptions);
|
validate(parserOptions);
|
||||||
|
|
||||||
return new JsonParser(parserOptions);
|
return new JsonParser(parserOptions, this.dependencyOptions);
|
||||||
});
|
});
|
||||||
normalModuleFactory.hooks.createGenerator
|
normalModuleFactory.hooks.createGenerator
|
||||||
.for(JSON_MODULE_TYPE)
|
.for(JSON_MODULE_TYPE)
|
||||||
|
|
|
@ -15,17 +15,20 @@ const JsonData = require("./JsonData");
|
||||||
/** @typedef {import("../Module").BuildMeta} BuildMeta */
|
/** @typedef {import("../Module").BuildMeta} BuildMeta */
|
||||||
/** @typedef {import("../Parser").ParserState} ParserState */
|
/** @typedef {import("../Parser").ParserState} ParserState */
|
||||||
/** @typedef {import("../Parser").PreparsedAst} PreparsedAst */
|
/** @typedef {import("../Parser").PreparsedAst} PreparsedAst */
|
||||||
|
/** @typedef {import("../dependencies/JsonExportsDependency").JsonDependencyOptions} JsonDependencyOptions */
|
||||||
/** @typedef {import("./JsonModulesPlugin").RawJsonData} RawJsonData */
|
/** @typedef {import("./JsonModulesPlugin").RawJsonData} RawJsonData */
|
||||||
|
|
||||||
const getParseJson = memoize(() => require("json-parse-even-better-errors"));
|
const getParseJson = memoize(() => require("json-parse-even-better-errors"));
|
||||||
|
|
||||||
class JsonParser extends Parser {
|
class JsonParser extends Parser {
|
||||||
/**
|
/**
|
||||||
* @param {JsonModulesPluginParserOptions} options parser options
|
* @param {JsonModulesPluginParserOptions} parserOptions parser options
|
||||||
|
* @param {JsonDependencyOptions} dependencyOptions dependency options
|
||||||
*/
|
*/
|
||||||
constructor(options) {
|
constructor(parserOptions, dependencyOptions) {
|
||||||
super();
|
super();
|
||||||
this.options = options || {};
|
this.options = parserOptions || {};
|
||||||
|
this.dependencyOptions = dependencyOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -63,7 +66,9 @@ class JsonParser extends Parser {
|
||||||
buildMeta.exportsType = "default";
|
buildMeta.exportsType = "default";
|
||||||
buildMeta.defaultObject =
|
buildMeta.defaultObject =
|
||||||
typeof data === "object" ? "redirect-warn" : false;
|
typeof data === "object" ? "redirect-warn" : false;
|
||||||
state.module.addDependency(new JsonExportsDependency(jsonData));
|
state.module.addDependency(
|
||||||
|
new JsonExportsDependency(jsonData, this.dependencyOptions)
|
||||||
|
);
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
{
|
||||||
|
"depth_1": {
|
||||||
|
"depth_2": {
|
||||||
|
"depth_3": {
|
||||||
|
"depth_4": {
|
||||||
|
"depth_5": {
|
||||||
|
"depth_6": "depth_6"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"_depth_1": {
|
||||||
|
"_depth_2": {
|
||||||
|
"_depth_3": {
|
||||||
|
"_depth_4": {
|
||||||
|
"_depth_5": {
|
||||||
|
"_depth_6": "_depth_6"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"__depth_1": [
|
||||||
|
{ "__depth_3": [{ "__depth_5": [{ "__depth_7": ["__depth_8"] }] }] }
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
export * from './data.json';
|
||||||
|
|
||||||
|
it("should compile and run", () => {
|
||||||
|
expect(__webpack_exports_info__.depth_1.provideInfo).toBe(true)
|
||||||
|
expect(__webpack_exports_info__._depth_1.provideInfo).toBe(true)
|
||||||
|
expect(__webpack_exports_info__.__depth_1.provideInfo).toBe(true)
|
||||||
|
|
||||||
|
expect(__webpack_exports_info__.depth_1.depth_2.provideInfo).toBe(undefined)
|
||||||
|
expect(__webpack_exports_info__._depth_1._depth_2._depth_3._depth_4.provideInfo).toBe(undefined)
|
||||||
|
expect(__webpack_exports_info__.__depth_1[0].__depth_3[0].__depth_5.provideInfo).toBe(undefined)
|
||||||
|
});
|
|
@ -0,0 +1,4 @@
|
||||||
|
/** @type {import("../../../../").Configuration} */
|
||||||
|
module.exports = {
|
||||||
|
mode: "development"
|
||||||
|
};
|
Loading…
Reference in New Issue