source: frontend/node_modules/webpack/lib/ids/SyncModuleIdsPlugin.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 11 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 4.7 KB
Line 
1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Tobias Koppers @sokra
4*/
5
6"use strict";
7
8const { WebpackError } = require("..");
9const { getUsedModuleIdsAndModules } = require("./IdHelpers");
10
11/** @typedef {import("../Compiler")} Compiler */
12/** @typedef {import("../Module")} Module */
13/** @typedef {import("../Module").ModuleId} ModuleId */
14/** @typedef {import("../util/fs").IntermediateFileSystem} IntermediateFileSystem */
15
16/** @typedef {{ [key: string]: ModuleId }} JSONContent */
17
18const plugin = "SyncModuleIdsPlugin";
19
20/**
21 * Represents the sync module ids plugin runtime component.
22 * @typedef {object} SyncModuleIdsPluginOptions
23 * @property {string} path path to file
24 * @property {string=} context context for module names
25 * @property {((module: Module) => boolean)=} test selector for modules
26 * @property {"read" | "create" | "merge" | "update"=} mode operation mode (defaults to merge)
27 */
28
29class SyncModuleIdsPlugin {
30 /**
31 * Creates an instance of SyncModuleIdsPlugin.
32 * @param {SyncModuleIdsPluginOptions} options options
33 */
34 constructor(options) {
35 /** @type {SyncModuleIdsPluginOptions} */
36 this.options = options;
37 }
38
39 /**
40 * Applies the plugin by registering its hooks on the compiler.
41 * @param {Compiler} compiler the compiler instance
42 * @returns {void}
43 */
44 apply(compiler) {
45 /** @type {Map<string, ModuleId>} */
46 let data;
47 let dataChanged = false;
48
49 const readAndWrite =
50 !this.options.mode ||
51 this.options.mode === "merge" ||
52 this.options.mode === "update";
53
54 const needRead = readAndWrite || this.options.mode === "read";
55 const needWrite = readAndWrite || this.options.mode === "create";
56 const needPrune = this.options.mode === "update";
57
58 if (needRead) {
59 compiler.hooks.readRecords.tapAsync(plugin, (callback) => {
60 const fs =
61 /** @type {IntermediateFileSystem} */
62 (compiler.intermediateFileSystem);
63 fs.readFile(this.options.path, (err, buffer) => {
64 if (err) {
65 if (err.code !== "ENOENT") {
66 return callback(err);
67 }
68 return callback();
69 }
70 /** @type {JSONContent} */
71 const json = JSON.parse(/** @type {Buffer} */ (buffer).toString());
72 /** @type {Map<string, string | number | null>} */
73 data = new Map();
74 for (const key of Object.keys(json)) {
75 data.set(key, json[key]);
76 }
77 dataChanged = false;
78 return callback();
79 });
80 });
81 }
82 if (needWrite) {
83 compiler.hooks.emitRecords.tapAsync(plugin, (callback) => {
84 if (!data || !dataChanged) return callback();
85 /** @type {JSONContent} */
86 const json = {};
87 const sorted = [...data].sort(([a], [b]) => (a < b ? -1 : 1));
88 for (const [key, value] of sorted) {
89 json[key] = value;
90 }
91 const fs =
92 /** @type {IntermediateFileSystem} */
93 (compiler.intermediateFileSystem);
94 fs.writeFile(this.options.path, JSON.stringify(json), callback);
95 });
96 }
97 compiler.hooks.thisCompilation.tap(plugin, (compilation) => {
98 const associatedObjectForCache = compiler.root;
99 const context = this.options.context || compiler.context;
100 const test = this.options.test || (() => true);
101 if (needRead) {
102 compilation.hooks.reviveModules.tap(plugin, (_1, _2) => {
103 if (!data) return;
104 const { chunkGraph } = compilation;
105 const [usedIds, modules] = getUsedModuleIdsAndModules(
106 compilation,
107 test
108 );
109 for (const module of modules) {
110 const name = module.libIdent({
111 context,
112 associatedObjectForCache
113 });
114 if (!name) continue;
115 const id = data.get(name);
116 const idAsString = `${id}`;
117 if (usedIds.has(idAsString)) {
118 const err = new WebpackError(
119 `SyncModuleIdsPlugin: Unable to restore id '${id}' from '${this.options.path}' as it's already used.`
120 );
121 err.module = module;
122 compilation.errors.push(err);
123 }
124 chunkGraph.setModuleId(module, /** @type {ModuleId} */ (id));
125 usedIds.add(idAsString);
126 }
127 });
128 }
129 if (needWrite) {
130 compilation.hooks.recordModules.tap(plugin, (modules) => {
131 const { chunkGraph } = compilation;
132 let oldData = data;
133 if (!oldData) {
134 oldData = data = new Map();
135 } else if (needPrune) {
136 data = new Map();
137 }
138 for (const module of modules) {
139 if (test(module)) {
140 const name = module.libIdent({
141 context,
142 associatedObjectForCache
143 });
144 if (!name) continue;
145 const id = chunkGraph.getModuleId(module);
146 if (id === null) continue;
147 const oldId = oldData.get(name);
148 if (oldId !== id) {
149 dataChanged = true;
150 } else if (data === oldData) {
151 continue;
152 }
153 data.set(name, id);
154 }
155 }
156 if (data.size !== oldData.size) dataChanged = true;
157 });
158 }
159 });
160 }
161}
162
163module.exports = SyncModuleIdsPlugin;
Note: See TracBrowser for help on using the repository browser.