@lynx-js/template-webpack-plugin-canary 0.7.0-canary-20250523-790e6b63 → 0.7.0
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 +9 -5
- package/lib/WebEncodePlugin.d.ts +13 -0
- package/lib/WebEncodePlugin.js +96 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/web/StyleInfo.d.ts +10 -0
- package/lib/web/StyleInfo.js +5 -0
- package/lib/web/genStyleInfo.d.ts +3 -0
- package/lib/web/genStyleInfo.js +97 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @lynx-js/template-webpack-plugin
|
|
2
2
|
|
|
3
|
-
## 0.7.0
|
|
3
|
+
## 0.7.0
|
|
4
4
|
|
|
5
5
|
### Minor Changes
|
|
6
6
|
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
example:
|
|
18
18
|
|
|
19
19
|
```js
|
|
20
|
-
import { defineConfig } from
|
|
20
|
+
import { defineConfig } from '@lynx-js/rspeedy';
|
|
21
21
|
|
|
22
22
|
export default defineConfig({
|
|
23
23
|
output: {
|
|
@@ -33,6 +33,10 @@
|
|
|
33
33
|
multi-thread: startMainWorker -> prepareMainThreadAPIs -> startMainThread -> createMainThreadContext(new MainThreadRuntime)
|
|
34
34
|
all-on-ui: prepareMainThreadAPIs -> startMainThread -> createMainThreadContext(new MainThreadRuntime)
|
|
35
35
|
|
|
36
|
+
- Add `WebEncodePlugin`. ([#904](https://github.com/lynx-family/lynx-stack/pull/904))
|
|
37
|
+
|
|
38
|
+
This is previously known as `WebWebpackPlugin` from `@lynx-js/web-webpack-plugin`.
|
|
39
|
+
|
|
36
40
|
- Fix a bug that the `lepus` arg of `beforeEmit` hook does not contains the `root` main chunk of the main thread. ([#898](https://github.com/lynx-family/lynx-stack/pull/898))
|
|
37
41
|
|
|
38
42
|
## 0.6.11
|
|
@@ -108,7 +112,7 @@
|
|
|
108
112
|
- Add `defaultOverflowVisible` option to `LynxTemplatePlugin`. ([#78](https://github.com/lynx-family/lynx-stack/pull/78))
|
|
109
113
|
|
|
110
114
|
```js
|
|
111
|
-
import { LynxTemplatePlugin } from
|
|
115
|
+
import { LynxTemplatePlugin } from '@lynx-js/template-webpack-plugin';
|
|
112
116
|
|
|
113
117
|
new LynxTemplatePlugin({
|
|
114
118
|
defaultOverflowVisible: false,
|
|
@@ -127,10 +131,10 @@
|
|
|
127
131
|
- 1abf8f0: Add `entryNames` parameter to `beforeEncode` hook.
|
|
128
132
|
|
|
129
133
|
```js
|
|
130
|
-
import { LynxTemplatePlugin } from
|
|
134
|
+
import { LynxTemplatePlugin } from '@lynx-js/template-webpack-plugin';
|
|
131
135
|
|
|
132
136
|
const hooks = LynxTemplatePlugin.getLynxTemplatePluginHooks(compilation);
|
|
133
|
-
hooks.beforeEncode.tap(
|
|
137
|
+
hooks.beforeEncode.tap('MyPlugin', ({ entryNames }) => {
|
|
134
138
|
console.log(entryNames);
|
|
135
139
|
});
|
|
136
140
|
```
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Compilation, Compiler } from 'webpack';
|
|
2
|
+
export declare class WebEncodePlugin {
|
|
3
|
+
static name: string;
|
|
4
|
+
static BEFORE_ENCODE_HOOK_STAGE: number;
|
|
5
|
+
static ENCODE_HOOK_STAGE: number;
|
|
6
|
+
apply(compiler: Compiler): void;
|
|
7
|
+
/**
|
|
8
|
+
* The deleteDebuggingAssets delete all the assets that are inlined into the template.
|
|
9
|
+
*/
|
|
10
|
+
deleteDebuggingAssets(compilation: Compilation, assets: ({
|
|
11
|
+
name: string;
|
|
12
|
+
} | undefined)[]): void;
|
|
13
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
// Copyright 2024 The Lynx Authors. All rights reserved.
|
|
2
|
+
// Licensed under the Apache License Version 2.0 that can be found in the
|
|
3
|
+
// LICENSE file in the root directory of this source tree.
|
|
4
|
+
import { LynxTemplatePlugin, isDebug, isRsdoctor, } from './LynxTemplatePlugin.js';
|
|
5
|
+
import { genStyleInfo } from './web/genStyleInfo.js';
|
|
6
|
+
export class WebEncodePlugin {
|
|
7
|
+
static name = 'WebEncodePlugin';
|
|
8
|
+
static BEFORE_ENCODE_HOOK_STAGE = 100;
|
|
9
|
+
static ENCODE_HOOK_STAGE = 100;
|
|
10
|
+
apply(compiler) {
|
|
11
|
+
const isDev = process.env['NODE_ENV'] === 'development'
|
|
12
|
+
|| compiler.options.mode === 'development';
|
|
13
|
+
compiler.hooks.thisCompilation.tap(WebEncodePlugin.name, (compilation) => {
|
|
14
|
+
const hooks = LynxTemplatePlugin.getLynxTemplatePluginHooks(compilation);
|
|
15
|
+
const inlinedAssets = new Set();
|
|
16
|
+
const { Compilation } = compiler.webpack;
|
|
17
|
+
compilation.hooks.processAssets.tap({
|
|
18
|
+
name: WebEncodePlugin.name,
|
|
19
|
+
// `PROCESS_ASSETS_STAGE_REPORT` is the last stage of the `processAssets` hook.
|
|
20
|
+
// We need to run our asset deletion after this stage to ensure all assets have been processed.
|
|
21
|
+
// E.g.: upload source-map to sentry.
|
|
22
|
+
stage: Compilation.PROCESS_ASSETS_STAGE_REPORT + 1,
|
|
23
|
+
}, () => {
|
|
24
|
+
inlinedAssets.forEach((name) => {
|
|
25
|
+
compilation.deleteAsset(name);
|
|
26
|
+
});
|
|
27
|
+
inlinedAssets.clear();
|
|
28
|
+
});
|
|
29
|
+
hooks.beforeEncode.tap({
|
|
30
|
+
name: WebEncodePlugin.name,
|
|
31
|
+
stage: WebEncodePlugin.BEFORE_ENCODE_HOOK_STAGE,
|
|
32
|
+
}, (encodeOptions) => {
|
|
33
|
+
const { encodeData } = encodeOptions;
|
|
34
|
+
const { cssMap } = encodeData.css;
|
|
35
|
+
const styleInfo = genStyleInfo(cssMap);
|
|
36
|
+
const [name, content] = last(Object.entries(encodeData.manifest));
|
|
37
|
+
if (!isDebug() && !isDev && !isRsdoctor()) {
|
|
38
|
+
[
|
|
39
|
+
{ name },
|
|
40
|
+
encodeData.lepusCode.root,
|
|
41
|
+
...encodeData.lepusCode.chunks,
|
|
42
|
+
...encodeData.css.chunks,
|
|
43
|
+
]
|
|
44
|
+
.filter(asset => asset !== undefined)
|
|
45
|
+
.forEach(asset => inlinedAssets.add(asset.name));
|
|
46
|
+
}
|
|
47
|
+
Object.assign(encodeData, {
|
|
48
|
+
styleInfo,
|
|
49
|
+
manifest: {
|
|
50
|
+
// `app-service.js` is the entry point of a template.
|
|
51
|
+
'/app-service.js': content,
|
|
52
|
+
},
|
|
53
|
+
customSections: encodeData.customSections,
|
|
54
|
+
cardType: encodeData.sourceContent.dsl.substring(0, 5),
|
|
55
|
+
pageConfig: encodeData.compilerOptions,
|
|
56
|
+
});
|
|
57
|
+
return encodeOptions;
|
|
58
|
+
});
|
|
59
|
+
hooks.encode.tap({
|
|
60
|
+
name: WebEncodePlugin.name,
|
|
61
|
+
stage: WebEncodePlugin.ENCODE_HOOK_STAGE,
|
|
62
|
+
}, ({ encodeOptions }) => {
|
|
63
|
+
return {
|
|
64
|
+
buffer: Buffer.from(JSON.stringify({
|
|
65
|
+
styleInfo: encodeOptions['styleInfo'],
|
|
66
|
+
manifest: encodeOptions.manifest,
|
|
67
|
+
cardType: encodeOptions['cardType'],
|
|
68
|
+
pageConfig: encodeOptions.compilerOptions,
|
|
69
|
+
lepusCode: {
|
|
70
|
+
// flatten the lepusCode to a single object
|
|
71
|
+
...encodeOptions.lepusCode.lepusChunk,
|
|
72
|
+
root: encodeOptions.lepusCode.root,
|
|
73
|
+
},
|
|
74
|
+
customSections: encodeOptions.customSections,
|
|
75
|
+
})),
|
|
76
|
+
debugInfo: '',
|
|
77
|
+
};
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* The deleteDebuggingAssets delete all the assets that are inlined into the template.
|
|
83
|
+
*/
|
|
84
|
+
deleteDebuggingAssets(compilation, assets) {
|
|
85
|
+
assets
|
|
86
|
+
.filter(asset => asset !== undefined)
|
|
87
|
+
.forEach(asset => deleteAsset(asset));
|
|
88
|
+
function deleteAsset({ name }) {
|
|
89
|
+
return compilation.deleteAsset(name);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
function last(array) {
|
|
94
|
+
return array[array.length - 1];
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=WebEncodePlugin.js.map
|
package/lib/index.d.ts
CHANGED
|
@@ -7,5 +7,6 @@ export { LynxTemplatePlugin } from './LynxTemplatePlugin.js';
|
|
|
7
7
|
export type { LynxTemplatePluginOptions, TemplateHooks, } from './LynxTemplatePlugin.js';
|
|
8
8
|
export { LynxEncodePlugin } from './LynxEncodePlugin.js';
|
|
9
9
|
export type { LynxEncodePluginOptions, EncodeCSSOptions, } from './LynxEncodePlugin.js';
|
|
10
|
+
export { WebEncodePlugin } from './WebEncodePlugin.js';
|
|
10
11
|
export * as CSSPlugins from './css/plugins/index.js';
|
|
11
12
|
export * as CSS from './css/index.js';
|
package/lib/index.js
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
export { LynxTemplatePlugin } from './LynxTemplatePlugin.js';
|
|
10
10
|
export { LynxEncodePlugin } from './LynxEncodePlugin.js';
|
|
11
|
+
export { WebEncodePlugin } from './WebEncodePlugin.js';
|
|
11
12
|
export * as CSSPlugins from './css/plugins/index.js';
|
|
12
13
|
export * as CSS from './css/index.js';
|
|
13
14
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
// Copyright 2024 The Lynx Authors. All rights reserved.
|
|
2
|
+
// Licensed under the Apache License Version 2.0 that can be found in the
|
|
3
|
+
// LICENSE file in the root directory of this source tree.
|
|
4
|
+
import * as CSS from '../css/index.js';
|
|
5
|
+
export function genStyleInfo(cssMap) {
|
|
6
|
+
return Object.fromEntries(Object.entries(cssMap).map(([cssId, nodes]) => {
|
|
7
|
+
/**
|
|
8
|
+
* note that "0" implies it's a common style
|
|
9
|
+
*/
|
|
10
|
+
const contentsAtom = [];
|
|
11
|
+
const imports = [];
|
|
12
|
+
const rules = [];
|
|
13
|
+
for (const node of nodes) {
|
|
14
|
+
if (node.type === 'FontFaceRule') {
|
|
15
|
+
contentsAtom.push([
|
|
16
|
+
'@font-face {',
|
|
17
|
+
node.style.map((declaration) => `${declaration.name}:${declaration.value}`).join(';'),
|
|
18
|
+
'}',
|
|
19
|
+
].join(''));
|
|
20
|
+
}
|
|
21
|
+
else if (node.type === 'ImportRule') {
|
|
22
|
+
imports.push(node.href);
|
|
23
|
+
}
|
|
24
|
+
else if (node.type === 'KeyframesRule') {
|
|
25
|
+
contentsAtom.push([
|
|
26
|
+
`@keyframes ${node.name.value} {`,
|
|
27
|
+
node.styles.map((keyframesStyle) => `${keyframesStyle.keyText.value} {${keyframesStyle.style.map((declaration) => `${declaration.name}:${declaration.value};`).join('')}}`).join(' '),
|
|
28
|
+
'}',
|
|
29
|
+
].join(''));
|
|
30
|
+
}
|
|
31
|
+
else if (node.type === 'StyleRule') {
|
|
32
|
+
const ast = CSS.csstree.parse(`${node.selectorText.value}{ --mocked-declaration:1;}`);
|
|
33
|
+
const selectors = ast.children.first
|
|
34
|
+
.prelude.children
|
|
35
|
+
.toArray();
|
|
36
|
+
const groupedSelectors = [];
|
|
37
|
+
for (const selectorList of selectors) {
|
|
38
|
+
let plainSelectors = [];
|
|
39
|
+
let pseudoClassSelectors = [];
|
|
40
|
+
let pseudoElementSelectors = [];
|
|
41
|
+
const currentSplittedSelectorInfo = [];
|
|
42
|
+
for (const selector of selectorList.children.toArray()) {
|
|
43
|
+
if (selector.type === 'PseudoClassSelector'
|
|
44
|
+
&& selector.name === 'root') {
|
|
45
|
+
/**
|
|
46
|
+
* [aa]:root {
|
|
47
|
+
* }
|
|
48
|
+
* ===>
|
|
49
|
+
* [aa][lynx-tag="page"] {
|
|
50
|
+
* }
|
|
51
|
+
*/
|
|
52
|
+
plainSelectors.push('[lynx-tag="page"]');
|
|
53
|
+
}
|
|
54
|
+
else if (selector.type === 'PseudoClassSelector') {
|
|
55
|
+
pseudoClassSelectors.push(CSS.csstree.generate(selector));
|
|
56
|
+
}
|
|
57
|
+
else if (selector.type === 'PseudoElementSelector') {
|
|
58
|
+
pseudoElementSelectors.push(CSS.csstree.generate(selector));
|
|
59
|
+
}
|
|
60
|
+
else if (selector.type === 'TypeSelector') {
|
|
61
|
+
plainSelectors.push(`[lynx-tag="${selector.name}"]`);
|
|
62
|
+
}
|
|
63
|
+
else if (selector.type === 'Combinator') {
|
|
64
|
+
currentSplittedSelectorInfo.push(plainSelectors, pseudoClassSelectors, pseudoElementSelectors, [CSS.csstree.generate(selector)]);
|
|
65
|
+
plainSelectors = [];
|
|
66
|
+
pseudoClassSelectors = [];
|
|
67
|
+
pseudoElementSelectors = [];
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
plainSelectors.push(CSS.csstree.generate(selector));
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
currentSplittedSelectorInfo.push(plainSelectors, pseudoClassSelectors, pseudoElementSelectors, []);
|
|
74
|
+
groupedSelectors.push(currentSplittedSelectorInfo);
|
|
75
|
+
}
|
|
76
|
+
const decl = node.style.map((declaration) => [
|
|
77
|
+
declaration.name,
|
|
78
|
+
declaration.value.replaceAll(/\{\{--([^}]+)\}\}/g, 'var(--$1)'),
|
|
79
|
+
]);
|
|
80
|
+
decl.push(...(Object.entries(node.variables)));
|
|
81
|
+
rules.push({
|
|
82
|
+
sel: groupedSelectors,
|
|
83
|
+
decl,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
const info = {
|
|
88
|
+
content: [contentsAtom.join('\n')],
|
|
89
|
+
rules,
|
|
90
|
+
};
|
|
91
|
+
if (imports.length > 0) {
|
|
92
|
+
info.imports = imports;
|
|
93
|
+
}
|
|
94
|
+
return [cssId, info];
|
|
95
|
+
}));
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=genStyleInfo.js.map
|
package/package.json
CHANGED