@lynx-js/css-extract-webpack-plugin 0.5.4 → 0.6.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 CHANGED
@@ -1,5 +1,11 @@
1
1
  # @lynx-js/css-extract-webpack-plugin
2
2
 
3
+ ## 0.6.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Fix CSS HMR crash issues by using the same encode options with the main template. ([#1033](https://github.com/lynx-family/lynx-stack/pull/1033))
8
+
3
9
  ## 0.5.4
4
10
 
5
11
  ### Patch Changes
@@ -6,22 +6,6 @@ import { LynxTemplatePlugin } from '@lynx-js/template-webpack-plugin';
6
6
  * @public
7
7
  */
8
8
  interface CssExtractRspackPluginOptions extends ExternalCssExtractRspackPluginOptions {
9
- /**
10
- * {@inheritdoc @lynx-js/template-webpack-plugin#LynxTemplatePluginOptions.enableRemoveCSSScope}
11
- */
12
- enableRemoveCSSScope: boolean;
13
- /**
14
- * {@inheritdoc @lynx-js/template-webpack-plugin#LynxTemplatePluginOptions.enableCSSSelector}
15
- */
16
- enableCSSSelector: boolean;
17
- /**
18
- * {@inheritdoc @lynx-js/template-webpack-plugin#LynxTemplatePluginOptions.enableCSSInvalidation}
19
- */
20
- enableCSSInvalidation: boolean;
21
- /**
22
- * {@inheritdoc @lynx-js/template-webpack-plugin#LynxTemplatePluginOptions.targetSdkVersion}
23
- */
24
- targetSdkVersion: string;
25
9
  /**
26
10
  * plugins passed to parser
27
11
  */
@@ -2,7 +2,7 @@
2
2
  // Licensed under the Apache License Version 2.0 that can be found in the
3
3
  // LICENSE file in the root directory of this source tree.
4
4
  import { createRequire } from 'node:module';
5
- import { LynxEncodePlugin, LynxTemplatePlugin, } from '@lynx-js/template-webpack-plugin';
5
+ import { CSS, LynxTemplatePlugin } from '@lynx-js/template-webpack-plugin';
6
6
  const require = createRequire(import.meta.url);
7
7
  /**
8
8
  * @public
@@ -64,12 +64,10 @@ class CssExtractRspackPlugin {
64
64
  */
65
65
  static { this.defaultOptions = Object
66
66
  .freeze({
67
- enableRemoveCSSScope: false,
68
- enableCSSSelector: true,
69
- enableCSSInvalidation: true,
70
- targetSdkVersion: '3.2',
71
67
  filename: '[name].css',
72
- cssPlugins: [],
68
+ cssPlugins: [
69
+ CSS.Plugins.removeFunctionWhiteSpace(),
70
+ ],
73
71
  }); }
74
72
  /**
75
73
  * The entry point of a webpack plugin.
@@ -97,6 +95,52 @@ class CssExtractRspackPluginImpl {
97
95
  compiler.hooks.thisCompilation.tap(this.name, (compilation) => {
98
96
  if (compiler.options.mode === 'development'
99
97
  || process.env['NODE_ENV'] === 'development') {
98
+ const hooks = LynxTemplatePlugin.getLynxTemplatePluginHooks(
99
+ // @ts-expect-error Rspack to Webpack Compilation
100
+ compilation);
101
+ hooks.beforeEmit.tapPromise(this.name, async (args) => {
102
+ for (const { name: filename, source, } of args.cssChunks) {
103
+ const content = source.source().toString('utf-8');
104
+ const css = LynxTemplatePlugin.convertCSSChunksToMap([content], options.cssPlugins, Boolean(args.finalEncodeOptions.compilerOptions['enableCSSSelector']));
105
+ const cssDeps = Object.entries(css.cssMap).reduce((acc, [key, value]) => {
106
+ const importRuleNodes = value.filter((node) => node.type === 'ImportRule');
107
+ acc[key] = importRuleNodes.map(({ href }) => href);
108
+ return acc;
109
+ }, {});
110
+ try {
111
+ const { buffer } = await hooks.encode.promise({
112
+ encodeOptions: {
113
+ ...args.finalEncodeOptions,
114
+ css,
115
+ lepusCode: {
116
+ root: undefined,
117
+ lepusChunk: {},
118
+ },
119
+ manifest: {},
120
+ customSections: {},
121
+ },
122
+ });
123
+ const result = {
124
+ content: buffer.toString('base64'),
125
+ deps: cssDeps,
126
+ };
127
+ compilation.emitAsset(filename.replace('.css', `${this.hash ? `.${this.hash}` : ''}.css.hot-update.json`), new compiler.webpack.sources.RawSource(JSON.stringify(result), true));
128
+ }
129
+ catch (error) {
130
+ if (error && typeof error === 'object' && 'error_msg' in error) {
131
+ compilation.errors.push(
132
+ // TODO: use more human-readable error message(i.e.: using sourcemap to get source code)
133
+ // or give webpack/rspack with location of bundle
134
+ new compiler.webpack.WebpackError(error.error_msg));
135
+ }
136
+ else {
137
+ compilation.errors.push(error);
138
+ }
139
+ }
140
+ }
141
+ this.hash = compilation.hash;
142
+ return args;
143
+ });
100
144
  const { RuntimeGlobals, RuntimeModule } = compiler.webpack;
101
145
  class CSSHotUpdateRuntimeModule extends RuntimeModule {
102
146
  constructor(hash) {
@@ -147,60 +191,6 @@ ${RuntimeGlobals.require}.cssHotUpdateList = ${cssHotUpdateList ? JSON.stringify
147
191
  compilation.hooks.runtimeRequirementInTree
148
192
  .for(RuntimeGlobals.onChunksLoaded)
149
193
  .tap(this.name, handler);
150
- compilation.hooks.processAssets.tapPromise({
151
- name: this.name,
152
- stage: 300,
153
- }, async (assets) => {
154
- for (const [filename, source] of Object.entries(assets)) {
155
- if (!filename.endsWith('.css')) {
156
- continue;
157
- }
158
- // TODO: sourcemap
159
- const content = source.source().toString('utf-8');
160
- const { cssMap } = LynxTemplatePlugin.convertCSSChunksToMap([content], options.cssPlugins, options.enableCSSSelector);
161
- const cssDeps = Object.entries(cssMap).reduce((acc, [key, value]) => {
162
- const importRuleNodes = value.filter((node) => node.type === 'ImportRule');
163
- acc[key] = importRuleNodes.map(({ href }) => href);
164
- return acc;
165
- }, {});
166
- const hooks = LynxTemplatePlugin.getLynxTemplatePluginHooks(
167
- // @ts-expect-error Rspack to Webpack Compilation
168
- compilation);
169
- try {
170
- const encoded = await LynxEncodePlugin.encodeCSS([content], {
171
- targetSdkVersion: options.targetSdkVersion,
172
- enableCSSSelector: options.enableCSSSelector,
173
- enableRemoveCSSScope: options.enableRemoveCSSScope,
174
- enableCSSInvalidation: options.enableCSSInvalidation,
175
- }, options.cssPlugins, hooks.encode.taps.length > 0
176
- ? async (encodeOptions) => {
177
- // @ts-expect-error Only CSS is needed
178
- return await hooks.encode.promise({
179
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
180
- encodeOptions,
181
- });
182
- }
183
- : undefined);
184
- const result = {
185
- content: encoded.toString('base64'),
186
- deps: cssDeps,
187
- };
188
- compilation.emitAsset(filename.replace('.css', `${this.hash ? `.${this.hash}` : ''}.css.hot-update.json`), new compiler.webpack.sources.RawSource(JSON.stringify(result), true));
189
- }
190
- catch (error) {
191
- if (error && typeof error === 'object' && 'error_msg' in error) {
192
- compilation.errors.push(
193
- // TODO: use more human-readable error message(i.e.: using sourcemap to get source code)
194
- // or give webpack/rspack with location of bundle
195
- new compiler.webpack.WebpackError(error.error_msg));
196
- }
197
- else {
198
- compilation.errors.push(error);
199
- }
200
- }
201
- }
202
- this.hash = compilation.hash;
203
- });
204
194
  }
205
195
  });
206
196
  }
package/lib/util.js CHANGED
@@ -14,14 +14,14 @@ export function stringifyRequest(loaderContext, request) {
14
14
  && typeof loaderContext.utils.contextify === 'function') {
15
15
  return JSON.stringify(loaderContext.utils.contextify(loaderContext.context || loaderContext.rootContext, request));
16
16
  }
17
- const splitted = request.split('!');
17
+ const split = request.split('!');
18
18
  const { context } = loaderContext;
19
- return JSON.stringify(splitted
19
+ return JSON.stringify(split
20
20
  .map((part) => {
21
21
  // First, separate singlePath from query, because the query might contain paths again
22
- const splittedPart = /^(.*?)(\?.*)/.exec(part);
23
- const query = splittedPart ? splittedPart[2] : '';
24
- let singlePath = splittedPart ? splittedPart[1] : part;
22
+ const splitPart = /^(.*?)(\?.*)/.exec(part);
23
+ const query = splitPart ? splitPart[2] : '';
24
+ let singlePath = splitPart ? splitPart[1] : part;
25
25
  if (isAbsolutePath(singlePath) && context) {
26
26
  singlePath = path.relative(context, singlePath);
27
27
  if (isAbsolutePath(singlePath)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lynx-js/css-extract-webpack-plugin",
3
- "version": "0.5.4",
3
+ "version": "0.6.0",
4
4
  "description": "This plugin extracts CSS into separate files. It creates a CSS file per JS file which contains CSS.",
5
5
  "keywords": [
6
6
  "webpack",
@@ -45,17 +45,17 @@
45
45
  },
46
46
  "devDependencies": {
47
47
  "@microsoft/api-extractor": "7.52.8",
48
- "@rspack/core": "1.3.11",
48
+ "@rspack/core": "1.3.15",
49
49
  "css-loader": "^7.1.2",
50
50
  "sass-loader": "^16.0.5",
51
51
  "webpack": "^5.99.9",
52
- "@lynx-js/css-serializer": "0.1.2",
53
- "@lynx-js/template-webpack-plugin": "0.7.0",
52
+ "@lynx-js/css-serializer": "0.1.3",
53
+ "@lynx-js/template-webpack-plugin": "0.8.0",
54
54
  "@lynx-js/test-tools": "0.0.0",
55
55
  "@lynx-js/vitest-setup": "0.0.0"
56
56
  },
57
57
  "peerDependencies": {
58
- "@lynx-js/template-webpack-plugin": "^0.5.0 || ^0.6.0 || ^0.7.0"
58
+ "@lynx-js/template-webpack-plugin": "^0.8.0"
59
59
  },
60
60
  "engines": {
61
61
  "node": ">=18"