@lynx-js/react-webpack-plugin-canary 0.9.2 → 0.9.3
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/CHANGELOG.md +6 -0
- package/lib/ReactWebpackPlugin.d.ts +15 -0
- package/lib/ReactWebpackPlugin.js +29 -1
- package/lib/loaders/main-thread.d.ts +1 -0
- package/lib/loaders/main-thread.js +7 -0
- package/lib/loaders/options.d.ts +8 -0
- package/lib/loaders/options.js +35 -4
- package/lib/loaders/testing.js +12 -3
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# @lynx-js/react-webpack-plugin
|
|
2
2
|
|
|
3
|
+
## 0.9.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Inject the `lynxProcessEvalResult` runtime module only into main-thread chunks. The previous guard checked the chunk name for `:background`, which never matched the actual chunk names (`main__background`, `foo.js-react__background`), so the runtime was duplicated into background and async background chunks. ([#2692](https://github.com/lynx-family/lynx-stack/pull/2692))
|
|
8
|
+
|
|
3
9
|
## 0.9.2
|
|
4
10
|
|
|
5
11
|
### Patch Changes
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import type { Compiler } from '@rspack/core';
|
|
2
2
|
import type { ExtractStrConfig } from '@lynx-js/react/transform';
|
|
3
3
|
import { LAYERS } from './layer.js';
|
|
4
|
+
interface ElementTemplateBuildInfo {
|
|
5
|
+
templateId: string;
|
|
6
|
+
compiledTemplate: Record<string, unknown>;
|
|
7
|
+
}
|
|
8
|
+
export interface ModuleWithElementTemplateBuildInfo {
|
|
9
|
+
buildInfo?: Record<string, unknown>;
|
|
10
|
+
modules?: Iterable<ModuleWithElementTemplateBuildInfo>;
|
|
11
|
+
}
|
|
12
|
+
export declare function collectElementTemplatesFromModule(module: ModuleWithElementTemplateBuildInfo): ElementTemplateBuildInfo[];
|
|
4
13
|
/**
|
|
5
14
|
* The options for ReactWebpackPlugin
|
|
6
15
|
*
|
|
@@ -50,6 +59,12 @@ interface ReactWebpackPluginOptions {
|
|
|
50
59
|
* The file path of `@lynx-js/react/worklet-runtime`.
|
|
51
60
|
*/
|
|
52
61
|
workletRuntimePath: string;
|
|
62
|
+
/**
|
|
63
|
+
* Whether to enable Element Template compilation.
|
|
64
|
+
*
|
|
65
|
+
* @experimental
|
|
66
|
+
*/
|
|
67
|
+
experimental_useElementTemplate?: boolean;
|
|
53
68
|
}
|
|
54
69
|
/**
|
|
55
70
|
* ReactWebpackPlugin allows using ReactLynx with webpack
|
|
@@ -7,8 +7,22 @@ import invariant from 'tiny-invariant';
|
|
|
7
7
|
import { LynxTemplatePlugin } from '@lynx-js/template-webpack-plugin';
|
|
8
8
|
import { RuntimeGlobals } from '@lynx-js/webpack-runtime-globals';
|
|
9
9
|
import { LAYERS } from './layer.js';
|
|
10
|
+
import { ELEMENT_TEMPLATE_BUILD_INFO } from './loaders/main-thread.js';
|
|
10
11
|
import { createLynxProcessEvalResultRuntimeModule } from './LynxProcessEvalResultRuntimeModule.js';
|
|
11
12
|
const require = createRequire(import.meta.url);
|
|
13
|
+
export function collectElementTemplatesFromModule(module) {
|
|
14
|
+
const elementTemplates = [];
|
|
15
|
+
const templates = module.buildInfo?.[ELEMENT_TEMPLATE_BUILD_INFO];
|
|
16
|
+
if (Array.isArray(templates)) {
|
|
17
|
+
elementTemplates.push(...templates);
|
|
18
|
+
}
|
|
19
|
+
if (module.modules) {
|
|
20
|
+
for (const nestedModule of module.modules) {
|
|
21
|
+
elementTemplates.push(...collectElementTemplatesFromModule(nestedModule));
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return elementTemplates;
|
|
25
|
+
}
|
|
12
26
|
/**
|
|
13
27
|
* ReactWebpackPlugin allows using ReactLynx with webpack
|
|
14
28
|
*
|
|
@@ -81,6 +95,7 @@ class ReactWebpackPlugin {
|
|
|
81
95
|
experimental_isLazyBundle: false,
|
|
82
96
|
profile: undefined,
|
|
83
97
|
workletRuntimePath: '',
|
|
98
|
+
experimental_useElementTemplate: false,
|
|
84
99
|
}); }
|
|
85
100
|
/**
|
|
86
101
|
* The entry point of a webpack plugin.
|
|
@@ -120,6 +135,7 @@ class ReactWebpackPlugin {
|
|
|
120
135
|
__GLOBAL_PROPS_MODE__: JSON.stringify(options.globalPropsMode),
|
|
121
136
|
__ENABLE_SSR__: JSON.stringify(options.enableSSR),
|
|
122
137
|
__DISABLE_CREATE_SELECTOR_QUERY_INCOMPATIBLE_WARNING__: JSON.stringify(options.disableCreateSelectorQueryIncompatibleWarning),
|
|
138
|
+
__USE_ELEMENT_TEMPLATE__: JSON.stringify(options.experimental_useElementTemplate),
|
|
123
139
|
}).apply(compiler);
|
|
124
140
|
compiler.hooks.thisCompilation.tap(this.constructor.name, compilation => {
|
|
125
141
|
const onceForChunkSet = new WeakSet();
|
|
@@ -131,7 +147,7 @@ class ReactWebpackPlugin {
|
|
|
131
147
|
return;
|
|
132
148
|
}
|
|
133
149
|
onceForChunkSet.add(chunk);
|
|
134
|
-
if (chunk.name?.includes('
|
|
150
|
+
if (!chunk.name?.includes('__main-thread')) {
|
|
135
151
|
return;
|
|
136
152
|
}
|
|
137
153
|
const LynxProcessEvalResultRuntimeModule = createLynxProcessEvalResultRuntimeModule(compiler.webpack);
|
|
@@ -222,6 +238,18 @@ class ReactWebpackPlugin {
|
|
|
222
238
|
hooks.asyncChunkName.tap(this.constructor.name, (chunkName) => chunkName
|
|
223
239
|
?.replaceAll(`-react__background`, '')
|
|
224
240
|
?.replaceAll(`-react__main-thread`, ''));
|
|
241
|
+
if (options.experimental_useElementTemplate) {
|
|
242
|
+
hooks.beforeEncode.tap(`${this.constructor.name}.ElementTemplate`, (args) => {
|
|
243
|
+
const elementTemplates = {};
|
|
244
|
+
for (const module of compilation.modules) {
|
|
245
|
+
for (const { templateId, compiledTemplate } of collectElementTemplatesFromModule(module)) {
|
|
246
|
+
elementTemplates[templateId] = compiledTemplate;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
args.encodeData.elementTemplate = elementTemplates;
|
|
250
|
+
return args;
|
|
251
|
+
});
|
|
252
|
+
}
|
|
225
253
|
});
|
|
226
254
|
}
|
|
227
255
|
#updateMainThreadInfo(compilation, name) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { LoaderDefinitionFunction } from '@rspack/core';
|
|
2
2
|
import type { ReactLoaderOptions } from './options.js';
|
|
3
|
+
export declare const ELEMENT_TEMPLATE_BUILD_INFO = "lynx:element-templates";
|
|
3
4
|
declare const mainThreadLoader: LoaderDefinitionFunction<ReactLoaderOptions>;
|
|
4
5
|
export default mainThreadLoader;
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import { createRequire } from 'node:module';
|
|
5
5
|
import { UI_SOURCE_MAP_RECORDS_BUILD_INFO } from '@lynx-js/template-webpack-plugin';
|
|
6
6
|
import { getMainThreadTransformOptions } from './options.js';
|
|
7
|
+
export const ELEMENT_TEMPLATE_BUILD_INFO = 'lynx:element-templates';
|
|
7
8
|
const mainThreadLoader = function (content, sourceMap) {
|
|
8
9
|
const require = createRequire(import.meta.url);
|
|
9
10
|
const { transformPath = '@lynx-js/react/transform' } = this.getOptions();
|
|
@@ -80,6 +81,12 @@ const mainThreadLoader = function (content, sourceMap) {
|
|
|
80
81
|
const buildInfo = currentModule?.buildInfo;
|
|
81
82
|
if (buildInfo) {
|
|
82
83
|
buildInfo[UI_SOURCE_MAP_RECORDS_BUILD_INFO] = result.uiSourceMapRecords;
|
|
84
|
+
if (result.elementTemplates && result.elementTemplates.length > 0) {
|
|
85
|
+
buildInfo[ELEMENT_TEMPLATE_BUILD_INFO] = result.elementTemplates;
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
delete buildInfo[ELEMENT_TEMPLATE_BUILD_INFO];
|
|
89
|
+
}
|
|
83
90
|
}
|
|
84
91
|
this.callback(null, result.code + (this.hot
|
|
85
92
|
// TODO: temporary fix LEPUS error `$RefreshReg$ is not defined`
|
package/lib/loaders/options.d.ts
CHANGED
|
@@ -3,8 +3,10 @@ import type { CompatVisitorConfig, DefineDceVisitorConfig, JsxTransformerConfig,
|
|
|
3
3
|
export declare const JSX_IMPORT_SOURCE: {
|
|
4
4
|
MAIN_THREAD: string;
|
|
5
5
|
BACKGROUND: string;
|
|
6
|
+
ELEMENT_TEMPLATE: string;
|
|
6
7
|
};
|
|
7
8
|
export declare const RUNTIME_PKG = "@lynx-js/react/internal";
|
|
9
|
+
export declare const ELEMENT_TEMPLATE_RUNTIME_PKG = "@lynx-js/react/element-template";
|
|
8
10
|
/**
|
|
9
11
|
* The options of the ReactLynx plugin.
|
|
10
12
|
* @public
|
|
@@ -46,6 +48,12 @@ export interface ReactLoaderOptions {
|
|
|
46
48
|
* The engine version.
|
|
47
49
|
*/
|
|
48
50
|
engineVersion?: string | undefined;
|
|
51
|
+
/**
|
|
52
|
+
* Whether to enable Element Template compilation.
|
|
53
|
+
*
|
|
54
|
+
* @experimental
|
|
55
|
+
*/
|
|
56
|
+
experimental_useElementTemplate?: boolean | undefined;
|
|
49
57
|
}
|
|
50
58
|
export declare function getMainThreadTransformOptions(this: LoaderContext<ReactLoaderOptions>, inputSourceMap: string | undefined): TransformNodiffOptions;
|
|
51
59
|
export declare function getBackgroundTransformOptions(this: LoaderContext<ReactLoaderOptions>, inputSourceMap: string | undefined): TransformNodiffOptions;
|
package/lib/loaders/options.js
CHANGED
|
@@ -6,9 +6,11 @@ const PLUGIN_NAME = 'react:webpack';
|
|
|
6
6
|
export const JSX_IMPORT_SOURCE = {
|
|
7
7
|
MAIN_THREAD: '@lynx-js/react/lepus',
|
|
8
8
|
BACKGROUND: '@lynx-js/react',
|
|
9
|
+
ELEMENT_TEMPLATE: '@lynx-js/react/element-template',
|
|
9
10
|
};
|
|
10
11
|
const PUBLIC_RUNTIME_PKG = '@lynx-js/react';
|
|
11
12
|
export const RUNTIME_PKG = '@lynx-js/react/internal';
|
|
13
|
+
export const ELEMENT_TEMPLATE_RUNTIME_PKG = '@lynx-js/react/element-template';
|
|
12
14
|
const OLD_RUNTIME_PKG = '@lynx-js/react-runtime';
|
|
13
15
|
const COMPONENT_PKG = '@lynx-js/react-components';
|
|
14
16
|
function normalizeSlashes(file) {
|
|
@@ -16,7 +18,8 @@ function normalizeSlashes(file) {
|
|
|
16
18
|
}
|
|
17
19
|
function getCommonOptions(inputSourceMap) {
|
|
18
20
|
const filename = normalizeSlashes(path.relative(this.rootContext, this.resourcePath));
|
|
19
|
-
const { compat, enableRemoveCSSScope, enableUiSourceMap, inlineSourcesContent, isDynamicComponent, engineVersion, defineDCE = { define: {} }, } = this.getOptions();
|
|
21
|
+
const { compat, enableRemoveCSSScope, enableUiSourceMap, inlineSourcesContent, isDynamicComponent, engineVersion, experimental_useElementTemplate, defineDCE = { define: {} }, } = this.getOptions();
|
|
22
|
+
const useElementTemplate = experimental_useElementTemplate === true;
|
|
20
23
|
const syntax = (/\.[mc]?tsx?$/.exec(this.resourcePath))
|
|
21
24
|
? 'typescript'
|
|
22
25
|
: 'ecmascript';
|
|
@@ -61,7 +64,7 @@ function getCommonOptions(inputSourceMap) {
|
|
|
61
64
|
...(inputSourceMap && { inputSourceMap }),
|
|
62
65
|
sourceMapColumns: this.sourceMap && !this.hot,
|
|
63
66
|
inlineSourcesContent: inlineSourcesContent ?? !this.hot,
|
|
64
|
-
snapshot: {
|
|
67
|
+
snapshot: useElementTemplate ? false : {
|
|
65
68
|
// TODO: config
|
|
66
69
|
preserveJsx: false,
|
|
67
70
|
// In standalone lazy bundle mode, we do not support HMR now.
|
|
@@ -75,6 +78,16 @@ function getCommonOptions(inputSourceMap) {
|
|
|
75
78
|
filename,
|
|
76
79
|
isDynamicComponent: isDynamicComponent ?? false,
|
|
77
80
|
},
|
|
81
|
+
elementTemplate: useElementTemplate
|
|
82
|
+
? {
|
|
83
|
+
preserveJsx: false,
|
|
84
|
+
runtimePkg: ELEMENT_TEMPLATE_RUNTIME_PKG,
|
|
85
|
+
jsxImportSource: JSX_IMPORT_SOURCE.ELEMENT_TEMPLATE,
|
|
86
|
+
filename,
|
|
87
|
+
target: 'JS',
|
|
88
|
+
isDynamicComponent: isDynamicComponent ?? false,
|
|
89
|
+
}
|
|
90
|
+
: false,
|
|
78
91
|
engineVersion: engineVersion ?? '',
|
|
79
92
|
syntaxConfig: JSON.stringify({
|
|
80
93
|
syntax,
|
|
@@ -100,6 +113,7 @@ function getCommonOptions(inputSourceMap) {
|
|
|
100
113
|
export function getMainThreadTransformOptions(inputSourceMap) {
|
|
101
114
|
const commonOptions = getCommonOptions.call(this, inputSourceMap);
|
|
102
115
|
const { shake } = this.getOptions();
|
|
116
|
+
const useElementTemplate = typeof commonOptions.elementTemplate === 'object';
|
|
103
117
|
return {
|
|
104
118
|
...commonOptions,
|
|
105
119
|
compat: typeof commonOptions.compat === 'object'
|
|
@@ -108,11 +122,18 @@ export function getMainThreadTransformOptions(inputSourceMap) {
|
|
|
108
122
|
target: 'LEPUS',
|
|
109
123
|
}
|
|
110
124
|
: false,
|
|
111
|
-
snapshot: {
|
|
125
|
+
snapshot: useElementTemplate ? false : {
|
|
112
126
|
...commonOptions.snapshot,
|
|
113
127
|
jsxImportSource: JSX_IMPORT_SOURCE.MAIN_THREAD,
|
|
114
128
|
target: 'LEPUS',
|
|
115
129
|
},
|
|
130
|
+
elementTemplate: useElementTemplate
|
|
131
|
+
? {
|
|
132
|
+
...commonOptions.elementTemplate,
|
|
133
|
+
jsxImportSource: JSX_IMPORT_SOURCE.ELEMENT_TEMPLATE,
|
|
134
|
+
target: 'LEPUS',
|
|
135
|
+
}
|
|
136
|
+
: false,
|
|
116
137
|
dynamicImport: {
|
|
117
138
|
layer: `react__main-thread`,
|
|
118
139
|
runtimePkg: RUNTIME_PKG,
|
|
@@ -141,6 +162,8 @@ export function getMainThreadTransformOptions(inputSourceMap) {
|
|
|
141
162
|
PUBLIC_RUNTIME_PKG,
|
|
142
163
|
`${PUBLIC_RUNTIME_PKG}/legacy-react-runtime`,
|
|
143
164
|
RUNTIME_PKG,
|
|
165
|
+
ELEMENT_TEMPLATE_RUNTIME_PKG,
|
|
166
|
+
`${ELEMENT_TEMPLATE_RUNTIME_PKG}/internal`,
|
|
144
167
|
...typeof commonOptions.compat === 'object'
|
|
145
168
|
? commonOptions.compat.oldRuntimePkg
|
|
146
169
|
: [],
|
|
@@ -178,6 +201,7 @@ export function getMainThreadTransformOptions(inputSourceMap) {
|
|
|
178
201
|
}
|
|
179
202
|
export function getBackgroundTransformOptions(inputSourceMap) {
|
|
180
203
|
const commonOptions = getCommonOptions.call(this, inputSourceMap);
|
|
204
|
+
const useElementTemplate = typeof commonOptions.elementTemplate === 'object';
|
|
181
205
|
return {
|
|
182
206
|
...commonOptions,
|
|
183
207
|
compat: typeof commonOptions.compat === 'object'
|
|
@@ -190,10 +214,17 @@ export function getBackgroundTransformOptions(inputSourceMap) {
|
|
|
190
214
|
layer: `react__background`,
|
|
191
215
|
runtimePkg: RUNTIME_PKG,
|
|
192
216
|
},
|
|
193
|
-
snapshot: {
|
|
217
|
+
snapshot: useElementTemplate ? false : {
|
|
194
218
|
...commonOptions.snapshot,
|
|
195
219
|
jsxImportSource: JSX_IMPORT_SOURCE.BACKGROUND,
|
|
196
220
|
},
|
|
221
|
+
elementTemplate: useElementTemplate
|
|
222
|
+
? {
|
|
223
|
+
...commonOptions.elementTemplate,
|
|
224
|
+
jsxImportSource: JSX_IMPORT_SOURCE.BACKGROUND,
|
|
225
|
+
target: 'JS',
|
|
226
|
+
}
|
|
227
|
+
: false,
|
|
197
228
|
defineDCE: {
|
|
198
229
|
define: {
|
|
199
230
|
...commonOptions.defineDCE?.define,
|
package/lib/loaders/testing.js
CHANGED
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
// LICENSE file in the root directory of this source tree.
|
|
4
4
|
import { createRequire } from 'node:module';
|
|
5
5
|
import path from 'node:path';
|
|
6
|
-
import { JSX_IMPORT_SOURCE, RUNTIME_PKG } from './options.js';
|
|
6
|
+
import { ELEMENT_TEMPLATE_RUNTIME_PKG, JSX_IMPORT_SOURCE, RUNTIME_PKG, } from './options.js';
|
|
7
7
|
function normalizeSlashes(file) {
|
|
8
8
|
return file.replaceAll(path.win32.sep, '/');
|
|
9
9
|
}
|
|
10
10
|
function testingLoader(content) {
|
|
11
11
|
const require = createRequire(import.meta.url);
|
|
12
|
-
const { compat = false, defineDCE = { define: {} }, engineVersion = '', shake = false, transformPath = '@lynx-js/react/transform', } = this.getOptions();
|
|
12
|
+
const { compat = false, defineDCE = { define: {} }, engineVersion = '', experimental_useElementTemplate = false, shake = false, transformPath = '@lynx-js/react/transform', } = this.getOptions();
|
|
13
13
|
const { transformReactLynxSync } = require(transformPath);
|
|
14
14
|
const filename = normalizeSlashes(path.relative(this.rootContext, this.resourcePath));
|
|
15
15
|
const normalizedCompat = typeof compat === 'object'
|
|
@@ -33,13 +33,22 @@ function testingLoader(content) {
|
|
|
33
33
|
pluginName: '',
|
|
34
34
|
filename: this.resourcePath,
|
|
35
35
|
sourcemap: true,
|
|
36
|
-
snapshot: {
|
|
36
|
+
snapshot: experimental_useElementTemplate ? false : {
|
|
37
37
|
preserveJsx: false,
|
|
38
38
|
runtimePkg: RUNTIME_PKG,
|
|
39
39
|
jsxImportSource: JSX_IMPORT_SOURCE.BACKGROUND,
|
|
40
40
|
filename,
|
|
41
41
|
target: 'MIXED',
|
|
42
42
|
},
|
|
43
|
+
elementTemplate: experimental_useElementTemplate
|
|
44
|
+
? {
|
|
45
|
+
preserveJsx: false,
|
|
46
|
+
runtimePkg: ELEMENT_TEMPLATE_RUNTIME_PKG,
|
|
47
|
+
jsxImportSource: JSX_IMPORT_SOURCE.ELEMENT_TEMPLATE,
|
|
48
|
+
filename,
|
|
49
|
+
target: 'MIXED',
|
|
50
|
+
}
|
|
51
|
+
: false,
|
|
43
52
|
// snapshot: true,
|
|
44
53
|
directiveDCE: false,
|
|
45
54
|
defineDCE,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lynx-js/react-webpack-plugin-canary",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.3",
|
|
4
4
|
"description": "A webpack plugin for ReactLynx",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"webpack",
|
|
@@ -42,11 +42,11 @@
|
|
|
42
42
|
"css-loader": "^7.1.4",
|
|
43
43
|
"swc-loader": "^0.2.7",
|
|
44
44
|
"webpack": "^5.105.2",
|
|
45
|
-
"@lynx-js/
|
|
46
|
-
"@lynx-js/template-webpack-plugin": "npm:@lynx-js/template-webpack-plugin-canary@0.11.0",
|
|
47
|
-
"@lynx-js/react": "npm:@lynx-js/react-canary@0.120.0",
|
|
45
|
+
"@lynx-js/react": "npm:@lynx-js/react-canary@0.121.1",
|
|
48
46
|
"@lynx-js/test-tools": "0.0.0",
|
|
49
|
-
"@lynx-js/vitest-setup": "0.0.0"
|
|
47
|
+
"@lynx-js/vitest-setup": "0.0.0",
|
|
48
|
+
"@lynx-js/template-webpack-plugin": "npm:@lynx-js/template-webpack-plugin-canary@0.11.2",
|
|
49
|
+
"@lynx-js/css-extract-webpack-plugin": "npm:@lynx-js/css-extract-webpack-plugin-canary@0.7.1"
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|
|
52
52
|
"@lynx-js/template-webpack-plugin": "*"
|