@shuvi/platform-web 1.0.63 → 2.0.0-dev.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/node/features/html-render/index.js +5 -5
- package/lib/node/features/html-render/lib/buildHtml.js +1 -0
- package/lib/node/features/html-render/lib/webpack/build-manifest-plugin.d.ts +209 -1
- package/lib/node/features/html-render/lib/webpack/build-manifest-plugin.js +208 -6
- package/lib/node/features/html-render/lib/webpack/build-manifest-plugin.rspack.d.ts +249 -0
- package/lib/node/features/html-render/lib/webpack/build-manifest-plugin.rspack.js +498 -0
- package/lib/node/targets/react/bundler/index.js +5 -16
- package/package.json +12 -12
|
@@ -21,7 +21,7 @@ const version_1 = require("../../version");
|
|
|
21
21
|
const middlewares_1 = require("../middlewares");
|
|
22
22
|
const generateResource_1 = __importDefault(require("./lib/generateResource"));
|
|
23
23
|
const buildHtml_1 = require("./lib/buildHtml");
|
|
24
|
-
const
|
|
24
|
+
const build_manifest_plugin_rspack_1 = __importDefault(require("./lib/webpack/build-manifest-plugin.rspack"));
|
|
25
25
|
const server_1 = __importDefault(require("./server"));
|
|
26
26
|
const ENTRY_FLAG = 'shuviEntry';
|
|
27
27
|
function makeEntryRequest(req) {
|
|
@@ -46,7 +46,7 @@ Object.defineProperty(exports, "getPageMiddleware", { enumerable: true, get: fun
|
|
|
46
46
|
/** This plugin uses `platformContext` so that it is set to a plugin getter */
|
|
47
47
|
const getPlugin = (platformContext) => {
|
|
48
48
|
const core = (0, service_1.createPlugin)({
|
|
49
|
-
configWebpack: (chain, {
|
|
49
|
+
configWebpack: (chain, { rspack, name, mode }, ctx) => {
|
|
50
50
|
const isDev = mode === 'development';
|
|
51
51
|
const pkgVersion = (0, version_1.getVersion)();
|
|
52
52
|
const isServer = name === shared_1.BUNDLER_TARGET_SERVER;
|
|
@@ -68,7 +68,7 @@ const getPlugin = (platformContext) => {
|
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
70
|
]);
|
|
71
|
-
chain.plugin('private/build-manifest').use(
|
|
71
|
+
chain.plugin('private/build-manifest').use(build_manifest_plugin_rspack_1.default, [
|
|
72
72
|
{
|
|
73
73
|
filename: shared_1.CLIENT_BUILD_MANIFEST_PATH,
|
|
74
74
|
modules: true,
|
|
@@ -81,7 +81,7 @@ const getPlugin = (platformContext) => {
|
|
|
81
81
|
chain.resolve.alias.set('@shuvi/platform-shared/shuvi-app/application$', '@shuvi/platform-shared/shuvi-app/application.bare');
|
|
82
82
|
chain
|
|
83
83
|
.plugin('replace/ReactView.server')
|
|
84
|
-
.use(
|
|
84
|
+
.use(rspack.NormalModuleReplacementPlugin, [
|
|
85
85
|
/\.\/ReactView\.server/,
|
|
86
86
|
function (resource) {
|
|
87
87
|
const { context } = resource;
|
|
@@ -93,7 +93,7 @@ const getPlugin = (platformContext) => {
|
|
|
93
93
|
}
|
|
94
94
|
]);
|
|
95
95
|
}
|
|
96
|
-
chain.plugin('private/build-manifest').use(
|
|
96
|
+
chain.plugin('private/build-manifest').use(build_manifest_plugin_rspack_1.default, [
|
|
97
97
|
{
|
|
98
98
|
filename: shared_1.SERVER_BUILD_MANIFEST_PATH,
|
|
99
99
|
modules: false,
|
|
@@ -44,6 +44,7 @@ const buildHtml = (_a) => __awaiter(void 0, [_a], void 0, function* ({ context,
|
|
|
44
44
|
const request = (0, node_mocks_http_1.createRequest)({
|
|
45
45
|
url: pathname
|
|
46
46
|
});
|
|
47
|
+
// @ts-expect-error type error caused by adding dependency @rspack/cli
|
|
47
48
|
const response = (0, node_mocks_http_1.createResponse)({
|
|
48
49
|
eventEmitter: events_1.EventEmitter
|
|
49
50
|
});
|
|
@@ -1,27 +1,235 @@
|
|
|
1
|
-
import { Compiler, Compilation, Plugin } from '@shuvi/toolpack/lib/webpack';
|
|
1
|
+
import { Compiler, Compilation, Plugin } from '@shuvi/toolpack/lib/webpack/index.webpack';
|
|
2
|
+
/**
|
|
3
|
+
* Configuration options for BuildManifestPlugin
|
|
4
|
+
*/
|
|
2
5
|
interface Options {
|
|
6
|
+
/** Output filename for the build manifest JSON file */
|
|
3
7
|
filename: string;
|
|
8
|
+
/** Whether to include module information in the manifest */
|
|
4
9
|
modules: boolean;
|
|
10
|
+
/** Whether to include chunk request information */
|
|
5
11
|
chunkRequest: boolean;
|
|
6
12
|
}
|
|
13
|
+
/**
|
|
14
|
+
* Webpack plugin that generates a build manifest JSON file containing mappings
|
|
15
|
+
* of entry filenames to their actual output filenames (which may be hashed in production).
|
|
16
|
+
*
|
|
17
|
+
* This plugin is essential for frameworks that need to know the relationship between
|
|
18
|
+
* entry points and their corresponding built assets, especially when assets are
|
|
19
|
+
* hashed for cache busting.
|
|
20
|
+
*
|
|
21
|
+
* ## Features
|
|
22
|
+
* - Maps entry points to their output files
|
|
23
|
+
* - Tracks bundle files and their relationships
|
|
24
|
+
* - Collects polyfill files
|
|
25
|
+
* - Supports loadable modules/chunks
|
|
26
|
+
* - Handles both development and production builds
|
|
27
|
+
*
|
|
28
|
+
* ## Generated Manifest Structure
|
|
29
|
+
* ```json
|
|
30
|
+
* {
|
|
31
|
+
* "entries": {
|
|
32
|
+
* "main": {
|
|
33
|
+
* "js": ["/static/js/main.abc123.js"],
|
|
34
|
+
* "css": ["/static/css/main.def456.css"]
|
|
35
|
+
* }
|
|
36
|
+
* },
|
|
37
|
+
* "bundles": {
|
|
38
|
+
* "main": "/static/js/main.abc123.js"
|
|
39
|
+
* },
|
|
40
|
+
* "chunkRequest": {
|
|
41
|
+
* "/static/js/chunk.xyz789.js": "/pages/about"
|
|
42
|
+
* },
|
|
43
|
+
* "loadble": {
|
|
44
|
+
* "/pages/about": {
|
|
45
|
+
* "files": ["/static/js/chunk.xyz789.js"],
|
|
46
|
+
* "children": [
|
|
47
|
+
* {
|
|
48
|
+
* "id": "module-id",
|
|
49
|
+
* "name": "AboutPage"
|
|
50
|
+
* }
|
|
51
|
+
* ]
|
|
52
|
+
* }
|
|
53
|
+
* },
|
|
54
|
+
* "polyfillFiles": ["/static/js/polyfills.ghi012.js"]
|
|
55
|
+
* }
|
|
56
|
+
* ```
|
|
57
|
+
*
|
|
58
|
+
* ## Usage Example
|
|
59
|
+
* ```typescript
|
|
60
|
+
* // In webpack configuration
|
|
61
|
+
* const BuildManifestPlugin = require('./build-manifest-plugin');
|
|
62
|
+
*
|
|
63
|
+
* module.exports = {
|
|
64
|
+
* plugins: [
|
|
65
|
+
* new BuildManifestPlugin({
|
|
66
|
+
* filename: 'build-manifest.json',
|
|
67
|
+
* modules: true,
|
|
68
|
+
* chunkRequest: true
|
|
69
|
+
* })
|
|
70
|
+
* ]
|
|
71
|
+
* };
|
|
72
|
+
* ```
|
|
73
|
+
*
|
|
74
|
+
* ## Use Cases
|
|
75
|
+
* - **SSR Frameworks**: Map entry points to built assets for server-side rendering
|
|
76
|
+
* - **Asset Loading**: Determine which files to load for specific routes
|
|
77
|
+
* - **Cache Management**: Track hashed filenames for cache invalidation
|
|
78
|
+
* - **Code Splitting**: Understand relationships between chunks and their requests
|
|
79
|
+
*/
|
|
7
80
|
export default class BuildManifestPlugin implements Plugin {
|
|
8
81
|
private _options;
|
|
9
82
|
private _manifest;
|
|
83
|
+
/**
|
|
84
|
+
* Creates a new BuildManifestPlugin instance
|
|
85
|
+
* @param options - Configuration options for the plugin
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* ```typescript
|
|
89
|
+
* // Basic usage with default options
|
|
90
|
+
* new BuildManifestPlugin()
|
|
91
|
+
*
|
|
92
|
+
* // Custom configuration
|
|
93
|
+
* new BuildManifestPlugin({
|
|
94
|
+
* filename: 'assets-manifest.json',
|
|
95
|
+
* modules: true,
|
|
96
|
+
* chunkRequest: true
|
|
97
|
+
* })
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
10
100
|
constructor(options?: Partial<Options>);
|
|
101
|
+
/**
|
|
102
|
+
* Creates the build manifest by analyzing compilation assets and chunks
|
|
103
|
+
* @param compiler - Webpack compiler instance
|
|
104
|
+
* @param compilation - Webpack compilation instance
|
|
105
|
+
* @returns The generated manifest object
|
|
106
|
+
*
|
|
107
|
+
* This method performs the following operations:
|
|
108
|
+
* 1. Initializes the manifest structure
|
|
109
|
+
* 2. Collects entry point information
|
|
110
|
+
* 3. Processes chunk groups and their assets
|
|
111
|
+
* 4. Identifies polyfill files
|
|
112
|
+
* 5. Sorts and organizes loadable modules
|
|
113
|
+
*/
|
|
11
114
|
createAssets(compiler: Compiler, compilation: Compilation): {
|
|
12
115
|
entries: {};
|
|
13
116
|
bundles: {};
|
|
14
117
|
chunkRequest: {};
|
|
15
118
|
loadble: {};
|
|
16
119
|
};
|
|
120
|
+
/**
|
|
121
|
+
* Applies the plugin to the webpack compiler
|
|
122
|
+
* @param compiler - Webpack compiler instance
|
|
123
|
+
*
|
|
124
|
+
* This method hooks into the webpack compilation process to:
|
|
125
|
+
* 1. Listen for the 'make' hook to prepare for asset processing
|
|
126
|
+
* 2. Hook into 'processAssets' to generate the manifest file
|
|
127
|
+
* 3. Create the JSON file as a compilation asset
|
|
128
|
+
*/
|
|
17
129
|
apply(compiler: Compiler): void;
|
|
130
|
+
/**
|
|
131
|
+
* Collects entry point information from chunk groups
|
|
132
|
+
* @param entrypoint - The entry point chunk group to process
|
|
133
|
+
*
|
|
134
|
+
* This method processes entry points and maps them to their output files,
|
|
135
|
+
* filtering out source maps and hot update files.
|
|
136
|
+
*/
|
|
18
137
|
private _collectEntries;
|
|
138
|
+
/**
|
|
139
|
+
* Collects information from chunk groups including chunks and modules
|
|
140
|
+
* @param chunkGroup - The chunk group to process
|
|
141
|
+
* @param compiler - Webpack compiler instance
|
|
142
|
+
* @param compilation - Webpack compilation instance
|
|
143
|
+
* @param chunkRootModulesMap - Map of chunk root modules for efficient lookup
|
|
144
|
+
*
|
|
145
|
+
* This method processes chunk groups to collect:
|
|
146
|
+
* - Chunk information (files, requests)
|
|
147
|
+
* - Module information (if enabled)
|
|
148
|
+
* - Loadable modules and their relationships
|
|
149
|
+
*/
|
|
19
150
|
private _collect;
|
|
151
|
+
/**
|
|
152
|
+
* Collects information from individual chunks
|
|
153
|
+
* @param chunk - The webpack chunk to process
|
|
154
|
+
* @param request - The request that generated this chunk
|
|
155
|
+
*
|
|
156
|
+
* This method processes chunks to:
|
|
157
|
+
* - Identify bundle files
|
|
158
|
+
* - Map chunk requests to files
|
|
159
|
+
* - Filter out source maps and hot update files
|
|
160
|
+
*/
|
|
20
161
|
private _collectChunk;
|
|
162
|
+
/**
|
|
163
|
+
* Collects module information from chunks (when modules option is enabled)
|
|
164
|
+
* @param chunk - The webpack chunk to process
|
|
165
|
+
* @param request - The request that generated this chunk
|
|
166
|
+
* @param compiler - Webpack compiler instance
|
|
167
|
+
* @param compilation - Webpack compilation instance
|
|
168
|
+
* @param chunkRootModulesMap - Map of chunk root modules
|
|
169
|
+
*
|
|
170
|
+
* This method processes chunks to collect:
|
|
171
|
+
* - Loadable module files (JS and CSS)
|
|
172
|
+
* - Module metadata (ID, name)
|
|
173
|
+
* - Root modules for code splitting analysis
|
|
174
|
+
*/
|
|
21
175
|
private _collectChunkModule;
|
|
176
|
+
/**
|
|
177
|
+
* Adds entry information to the manifest
|
|
178
|
+
* @param name - Entry point name
|
|
179
|
+
* @param ext - File extension
|
|
180
|
+
* @param value - File path
|
|
181
|
+
*
|
|
182
|
+
* @example
|
|
183
|
+
* ```typescript
|
|
184
|
+
* this._pushEntries('main', 'js', '/static/js/main.abc123.js')
|
|
185
|
+
* // Results in: { entries: { main: { js: ['/static/js/main.abc123.js'] } } }
|
|
186
|
+
* ```
|
|
187
|
+
*/
|
|
22
188
|
private _pushEntries;
|
|
189
|
+
/**
|
|
190
|
+
* Adds bundle information to the manifest
|
|
191
|
+
* @param name - Bundle name
|
|
192
|
+
* @param file - Bundle file path
|
|
193
|
+
*
|
|
194
|
+
* @example
|
|
195
|
+
* ```typescript
|
|
196
|
+
* this._pushBundle({ name: 'main', file: '/static/js/main.abc123.js' })
|
|
197
|
+
* // Results in: { bundles: { main: '/static/js/main.abc123.js' } }
|
|
198
|
+
* ```
|
|
199
|
+
*/
|
|
23
200
|
private _pushBundle;
|
|
201
|
+
/**
|
|
202
|
+
* Adds chunk request information to the manifest (when chunkRequest option is enabled)
|
|
203
|
+
* @param file - Chunk file path
|
|
204
|
+
* @param request - Request that generated the chunk
|
|
205
|
+
*
|
|
206
|
+
* @example
|
|
207
|
+
* ```typescript
|
|
208
|
+
* this._pushChunkRequest({
|
|
209
|
+
* file: '/static/js/chunk.xyz789.js',
|
|
210
|
+
* request: '/pages/about'
|
|
211
|
+
* })
|
|
212
|
+
* // Results in: { chunkRequest: { '/static/js/chunk.xyz789.js': '/pages/about' } }
|
|
213
|
+
* ```
|
|
214
|
+
*/
|
|
24
215
|
private _pushChunkRequest;
|
|
216
|
+
/**
|
|
217
|
+
* Adds loadable module information to the manifest
|
|
218
|
+
* @param request - The request that generated the loadable module
|
|
219
|
+
* @param module - Module item with ID and name
|
|
220
|
+
*
|
|
221
|
+
* @example
|
|
222
|
+
* ```typescript
|
|
223
|
+
* // Adding a file
|
|
224
|
+
* this._pushLoadableModules('/pages/about', '/static/js/chunk.xyz789.js')
|
|
225
|
+
*
|
|
226
|
+
* // Adding a module
|
|
227
|
+
* this._pushLoadableModules('/pages/about', {
|
|
228
|
+
* id: 'module-id',
|
|
229
|
+
* name: 'AboutPage'
|
|
230
|
+
* })
|
|
231
|
+
* ```
|
|
232
|
+
*/
|
|
25
233
|
private _pushLoadableModules;
|
|
26
234
|
}
|
|
27
235
|
export {};
|
|
@@ -1,14 +1,29 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const shared_1 = require("../../../../../shared");
|
|
4
|
-
const
|
|
5
|
-
const Entrypoint = (0,
|
|
6
|
-
const { RawSource } =
|
|
4
|
+
const index_webpack_1 = require("@shuvi/toolpack/lib/webpack/index.webpack");
|
|
5
|
+
const Entrypoint = (0, index_webpack_1.resolveWebpackModule)('webpack/lib/Entrypoint');
|
|
6
|
+
const { RawSource } = index_webpack_1.sources;
|
|
7
|
+
/**
|
|
8
|
+
* Default configuration options for BuildManifestPlugin
|
|
9
|
+
*/
|
|
7
10
|
const defaultOptions = {
|
|
8
11
|
filename: 'build-manifest.json',
|
|
9
12
|
modules: false,
|
|
10
13
|
chunkRequest: false
|
|
11
14
|
};
|
|
15
|
+
/**
|
|
16
|
+
* Extracts file extension from a filepath
|
|
17
|
+
* @param filepath - The file path to extract extension from
|
|
18
|
+
* @returns The file extension (without dot) or empty string if no extension
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```typescript
|
|
22
|
+
* getFileExt('app.js') // returns 'js'
|
|
23
|
+
* getFileExt('styles.css') // returns 'css'
|
|
24
|
+
* getFileExt('README') // returns ''
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
12
27
|
function getFileExt(filepath) {
|
|
13
28
|
const match = filepath.match(/\.(\w+)$/);
|
|
14
29
|
if (!match)
|
|
@@ -30,12 +45,107 @@ function getFileExt(filepath) {
|
|
|
30
45
|
// }
|
|
31
46
|
// return entrypoints;
|
|
32
47
|
// }
|
|
33
|
-
|
|
34
|
-
|
|
48
|
+
/**
|
|
49
|
+
* Webpack plugin that generates a build manifest JSON file containing mappings
|
|
50
|
+
* of entry filenames to their actual output filenames (which may be hashed in production).
|
|
51
|
+
*
|
|
52
|
+
* This plugin is essential for frameworks that need to know the relationship between
|
|
53
|
+
* entry points and their corresponding built assets, especially when assets are
|
|
54
|
+
* hashed for cache busting.
|
|
55
|
+
*
|
|
56
|
+
* ## Features
|
|
57
|
+
* - Maps entry points to their output files
|
|
58
|
+
* - Tracks bundle files and their relationships
|
|
59
|
+
* - Collects polyfill files
|
|
60
|
+
* - Supports loadable modules/chunks
|
|
61
|
+
* - Handles both development and production builds
|
|
62
|
+
*
|
|
63
|
+
* ## Generated Manifest Structure
|
|
64
|
+
* ```json
|
|
65
|
+
* {
|
|
66
|
+
* "entries": {
|
|
67
|
+
* "main": {
|
|
68
|
+
* "js": ["/static/js/main.abc123.js"],
|
|
69
|
+
* "css": ["/static/css/main.def456.css"]
|
|
70
|
+
* }
|
|
71
|
+
* },
|
|
72
|
+
* "bundles": {
|
|
73
|
+
* "main": "/static/js/main.abc123.js"
|
|
74
|
+
* },
|
|
75
|
+
* "chunkRequest": {
|
|
76
|
+
* "/static/js/chunk.xyz789.js": "/pages/about"
|
|
77
|
+
* },
|
|
78
|
+
* "loadble": {
|
|
79
|
+
* "/pages/about": {
|
|
80
|
+
* "files": ["/static/js/chunk.xyz789.js"],
|
|
81
|
+
* "children": [
|
|
82
|
+
* {
|
|
83
|
+
* "id": "module-id",
|
|
84
|
+
* "name": "AboutPage"
|
|
85
|
+
* }
|
|
86
|
+
* ]
|
|
87
|
+
* }
|
|
88
|
+
* },
|
|
89
|
+
* "polyfillFiles": ["/static/js/polyfills.ghi012.js"]
|
|
90
|
+
* }
|
|
91
|
+
* ```
|
|
92
|
+
*
|
|
93
|
+
* ## Usage Example
|
|
94
|
+
* ```typescript
|
|
95
|
+
* // In webpack configuration
|
|
96
|
+
* const BuildManifestPlugin = require('./build-manifest-plugin');
|
|
97
|
+
*
|
|
98
|
+
* module.exports = {
|
|
99
|
+
* plugins: [
|
|
100
|
+
* new BuildManifestPlugin({
|
|
101
|
+
* filename: 'build-manifest.json',
|
|
102
|
+
* modules: true,
|
|
103
|
+
* chunkRequest: true
|
|
104
|
+
* })
|
|
105
|
+
* ]
|
|
106
|
+
* };
|
|
107
|
+
* ```
|
|
108
|
+
*
|
|
109
|
+
* ## Use Cases
|
|
110
|
+
* - **SSR Frameworks**: Map entry points to built assets for server-side rendering
|
|
111
|
+
* - **Asset Loading**: Determine which files to load for specific routes
|
|
112
|
+
* - **Cache Management**: Track hashed filenames for cache invalidation
|
|
113
|
+
* - **Code Splitting**: Understand relationships between chunks and their requests
|
|
114
|
+
*/
|
|
35
115
|
class BuildManifestPlugin {
|
|
116
|
+
/**
|
|
117
|
+
* Creates a new BuildManifestPlugin instance
|
|
118
|
+
* @param options - Configuration options for the plugin
|
|
119
|
+
*
|
|
120
|
+
* @example
|
|
121
|
+
* ```typescript
|
|
122
|
+
* // Basic usage with default options
|
|
123
|
+
* new BuildManifestPlugin()
|
|
124
|
+
*
|
|
125
|
+
* // Custom configuration
|
|
126
|
+
* new BuildManifestPlugin({
|
|
127
|
+
* filename: 'assets-manifest.json',
|
|
128
|
+
* modules: true,
|
|
129
|
+
* chunkRequest: true
|
|
130
|
+
* })
|
|
131
|
+
* ```
|
|
132
|
+
*/
|
|
36
133
|
constructor(options = {}) {
|
|
37
134
|
this._options = Object.assign(Object.assign({}, defaultOptions), options);
|
|
38
135
|
}
|
|
136
|
+
/**
|
|
137
|
+
* Creates the build manifest by analyzing compilation assets and chunks
|
|
138
|
+
* @param compiler - Webpack compiler instance
|
|
139
|
+
* @param compilation - Webpack compilation instance
|
|
140
|
+
* @returns The generated manifest object
|
|
141
|
+
*
|
|
142
|
+
* This method performs the following operations:
|
|
143
|
+
* 1. Initializes the manifest structure
|
|
144
|
+
* 2. Collects entry point information
|
|
145
|
+
* 3. Processes chunk groups and their assets
|
|
146
|
+
* 4. Identifies polyfill files
|
|
147
|
+
* 5. Sorts and organizes loadable modules
|
|
148
|
+
*/
|
|
39
149
|
createAssets(compiler, compilation) {
|
|
40
150
|
const assetMap = (this._manifest = {
|
|
41
151
|
entries: {},
|
|
@@ -43,6 +153,7 @@ class BuildManifestPlugin {
|
|
|
43
153
|
chunkRequest: {},
|
|
44
154
|
loadble: {}
|
|
45
155
|
});
|
|
156
|
+
// Create a map of chunk root modules for efficient lookup
|
|
46
157
|
const chunkRootModulesMap = new Map();
|
|
47
158
|
compilation.chunks.forEach(chunk => {
|
|
48
159
|
const { chunkGraph } = compilation;
|
|
@@ -55,6 +166,7 @@ class BuildManifestPlugin {
|
|
|
55
166
|
});
|
|
56
167
|
}
|
|
57
168
|
});
|
|
169
|
+
// Process all chunk groups
|
|
58
170
|
compilation.chunkGroups.forEach(chunkGroup => {
|
|
59
171
|
if (chunkGroup instanceof Entrypoint) {
|
|
60
172
|
this._collectEntries(chunkGroup);
|
|
@@ -62,6 +174,7 @@ class BuildManifestPlugin {
|
|
|
62
174
|
this._collect(chunkGroup, compiler, compilation, chunkRootModulesMap);
|
|
63
175
|
});
|
|
64
176
|
const compilationAssets = compilation.getAssets();
|
|
177
|
+
// Collect polyfill files
|
|
65
178
|
this._manifest.polyfillFiles = compilationAssets
|
|
66
179
|
.filter(p => {
|
|
67
180
|
// Ensure only .js files are passed through
|
|
@@ -71,22 +184,39 @@ class BuildManifestPlugin {
|
|
|
71
184
|
return p.info && shared_1.BUILD_CLIENT_RUNTIME_POLYFILLS_SYMBOL in p.info;
|
|
72
185
|
})
|
|
73
186
|
.map(v => v.name);
|
|
187
|
+
// Sort loadable modules for consistent output
|
|
74
188
|
this._manifest.loadble = Object.keys(this._manifest.loadble)
|
|
75
189
|
.sort()
|
|
76
190
|
// eslint-disable-next-line no-sequences
|
|
77
191
|
.reduce((a, c) => ((a[c] = this._manifest.loadble[c]), a), {});
|
|
78
192
|
return assetMap;
|
|
79
193
|
}
|
|
194
|
+
/**
|
|
195
|
+
* Applies the plugin to the webpack compiler
|
|
196
|
+
* @param compiler - Webpack compiler instance
|
|
197
|
+
*
|
|
198
|
+
* This method hooks into the webpack compilation process to:
|
|
199
|
+
* 1. Listen for the 'make' hook to prepare for asset processing
|
|
200
|
+
* 2. Hook into 'processAssets' to generate the manifest file
|
|
201
|
+
* 3. Create the JSON file as a compilation asset
|
|
202
|
+
*/
|
|
80
203
|
apply(compiler) {
|
|
81
204
|
compiler.hooks.make.tap('BuildManifestPlugin', compilation => {
|
|
82
205
|
compilation.hooks.processAssets.tap({
|
|
83
206
|
name: 'BuildManifestPlugin',
|
|
84
|
-
stage:
|
|
207
|
+
stage: index_webpack_1.webpack.Compilation.PROCESS_ASSETS_STAGE_ADDITIONS
|
|
85
208
|
}, assets => {
|
|
86
209
|
assets[this._options.filename] = new RawSource(JSON.stringify(this.createAssets(compiler, compilation), null, 2), true);
|
|
87
210
|
});
|
|
88
211
|
});
|
|
89
212
|
}
|
|
213
|
+
/**
|
|
214
|
+
* Collects entry point information from chunk groups
|
|
215
|
+
* @param entrypoint - The entry point chunk group to process
|
|
216
|
+
*
|
|
217
|
+
* This method processes entry points and maps them to their output files,
|
|
218
|
+
* filtering out source maps and hot update files.
|
|
219
|
+
*/
|
|
90
220
|
_collectEntries(entrypoint) {
|
|
91
221
|
for (const chunk of entrypoint.chunks) {
|
|
92
222
|
// If there's no name or no files
|
|
@@ -102,6 +232,18 @@ class BuildManifestPlugin {
|
|
|
102
232
|
}
|
|
103
233
|
}
|
|
104
234
|
}
|
|
235
|
+
/**
|
|
236
|
+
* Collects information from chunk groups including chunks and modules
|
|
237
|
+
* @param chunkGroup - The chunk group to process
|
|
238
|
+
* @param compiler - Webpack compiler instance
|
|
239
|
+
* @param compilation - Webpack compilation instance
|
|
240
|
+
* @param chunkRootModulesMap - Map of chunk root modules for efficient lookup
|
|
241
|
+
*
|
|
242
|
+
* This method processes chunk groups to collect:
|
|
243
|
+
* - Chunk information (files, requests)
|
|
244
|
+
* - Module information (if enabled)
|
|
245
|
+
* - Loadable modules and their relationships
|
|
246
|
+
*/
|
|
105
247
|
_collect(chunkGroup, compiler, compilation, chunkRootModulesMap) {
|
|
106
248
|
const collectModules = this._options.modules;
|
|
107
249
|
chunkGroup.origins.forEach(chunkGroupOrigin => {
|
|
@@ -115,6 +257,16 @@ class BuildManifestPlugin {
|
|
|
115
257
|
});
|
|
116
258
|
});
|
|
117
259
|
}
|
|
260
|
+
/**
|
|
261
|
+
* Collects information from individual chunks
|
|
262
|
+
* @param chunk - The webpack chunk to process
|
|
263
|
+
* @param request - The request that generated this chunk
|
|
264
|
+
*
|
|
265
|
+
* This method processes chunks to:
|
|
266
|
+
* - Identify bundle files
|
|
267
|
+
* - Map chunk requests to files
|
|
268
|
+
* - Filter out source maps and hot update files
|
|
269
|
+
*/
|
|
118
270
|
_collectChunk(chunk, { request }) {
|
|
119
271
|
if (!chunk.files) {
|
|
120
272
|
return;
|
|
@@ -140,6 +292,19 @@ class BuildManifestPlugin {
|
|
|
140
292
|
}
|
|
141
293
|
}
|
|
142
294
|
}
|
|
295
|
+
/**
|
|
296
|
+
* Collects module information from chunks (when modules option is enabled)
|
|
297
|
+
* @param chunk - The webpack chunk to process
|
|
298
|
+
* @param request - The request that generated this chunk
|
|
299
|
+
* @param compiler - Webpack compiler instance
|
|
300
|
+
* @param compilation - Webpack compilation instance
|
|
301
|
+
* @param chunkRootModulesMap - Map of chunk root modules
|
|
302
|
+
*
|
|
303
|
+
* This method processes chunks to collect:
|
|
304
|
+
* - Loadable module files (JS and CSS)
|
|
305
|
+
* - Module metadata (ID, name)
|
|
306
|
+
* - Root modules for code splitting analysis
|
|
307
|
+
*/
|
|
143
308
|
_collectChunkModule(chunk, { request, compiler, compilation, chunkRootModulesMap }) {
|
|
144
309
|
if (chunk.canBeInitial()) {
|
|
145
310
|
return;
|
|
@@ -174,6 +339,18 @@ class BuildManifestPlugin {
|
|
|
174
339
|
}
|
|
175
340
|
}
|
|
176
341
|
}
|
|
342
|
+
/**
|
|
343
|
+
* Adds entry information to the manifest
|
|
344
|
+
* @param name - Entry point name
|
|
345
|
+
* @param ext - File extension
|
|
346
|
+
* @param value - File path
|
|
347
|
+
*
|
|
348
|
+
* @example
|
|
349
|
+
* ```typescript
|
|
350
|
+
* this._pushEntries('main', 'js', '/static/js/main.abc123.js')
|
|
351
|
+
* // Results in: { entries: { main: { js: ['/static/js/main.abc123.js'] } } }
|
|
352
|
+
* ```
|
|
353
|
+
*/
|
|
177
354
|
_pushEntries(name, ext, value) {
|
|
178
355
|
const entries = this._manifest.entries;
|
|
179
356
|
if (!entries[name]) {
|
|
@@ -188,11 +365,36 @@ class BuildManifestPlugin {
|
|
|
188
365
|
entries[name][ext].push(value);
|
|
189
366
|
}
|
|
190
367
|
}
|
|
368
|
+
/**
|
|
369
|
+
* Adds bundle information to the manifest
|
|
370
|
+
* @param name - Bundle name
|
|
371
|
+
* @param file - Bundle file path
|
|
372
|
+
*
|
|
373
|
+
* @example
|
|
374
|
+
* ```typescript
|
|
375
|
+
* this._pushBundle({ name: 'main', file: '/static/js/main.abc123.js' })
|
|
376
|
+
* // Results in: { bundles: { main: '/static/js/main.abc123.js' } }
|
|
377
|
+
* ```
|
|
378
|
+
*/
|
|
191
379
|
_pushBundle({ name, file }) {
|
|
192
380
|
if (name) {
|
|
193
381
|
this._manifest.bundles[name] = file;
|
|
194
382
|
}
|
|
195
383
|
}
|
|
384
|
+
/**
|
|
385
|
+
* Adds chunk request information to the manifest (when chunkRequest option is enabled)
|
|
386
|
+
* @param file - Chunk file path
|
|
387
|
+
* @param request - Request that generated the chunk
|
|
388
|
+
*
|
|
389
|
+
* @example
|
|
390
|
+
* ```typescript
|
|
391
|
+
* this._pushChunkRequest({
|
|
392
|
+
* file: '/static/js/chunk.xyz789.js',
|
|
393
|
+
* request: '/pages/about'
|
|
394
|
+
* })
|
|
395
|
+
* // Results in: { chunkRequest: { '/static/js/chunk.xyz789.js': '/pages/about' } }
|
|
396
|
+
* ```
|
|
397
|
+
*/
|
|
196
398
|
_pushChunkRequest({ file, request }) {
|
|
197
399
|
if (this._options.chunkRequest && request) {
|
|
198
400
|
this._manifest.chunkRequest[file] = request;
|