@lynx-js/css-extract-webpack-plugin 0.7.1 → 0.8.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 +20 -0
- package/lib/CssExtractRspackPlugin.d.ts +2 -2
- package/lib/CssExtractRspackPlugin.js +8 -7
- package/lib/index.d.ts +2 -4
- package/lib/index.js +0 -6
- package/lib/rspack-loader.d.ts +50 -1
- package/lib/rspack-loader.js +195 -4
- package/lib/util.d.ts +2 -2
- package/lib/util.js +1 -1
- package/package.json +7 -11
- package/lib/CssExtractWebpackPlugin.d.ts +0 -74
- package/lib/CssExtractWebpackPlugin.js +0 -99
- package/lib/loader.d.ts +0 -53
- package/lib/loader.js +0 -241
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# @lynx-js/css-extract-webpack-plugin
|
|
2
2
|
|
|
3
|
+
## 0.8.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- **BREAKING CHANGE** ([#2803](https://github.com/lynx-family/lynx-stack/pull/2803))
|
|
8
|
+
|
|
9
|
+
Remove `CssExtractWebpackPlugin` / `CssExtractWebpackPluginOptions` along with the `mini-css-extract-plugin` dependency. Use `CssExtractRspackPlugin` instead.
|
|
10
|
+
|
|
11
|
+
The `cssPlugins` option is now optional, defaulting to `[CSS.Plugins.removeFunctionWhiteSpace()]`.
|
|
12
|
+
|
|
13
|
+
- **BREAKING CHANGE** ([#2803](https://github.com/lynx-family/lynx-stack/pull/2803))
|
|
14
|
+
|
|
15
|
+
Drop webpack support — the plugins now target Rspack only. All public types come from `@rspack/core` instead of `webpack` (e.g. `Compiler`, `Compilation`, `LoaderContext`), and the `webpack` dependency is removed.
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- Prefix Lynx runtime module names with `webpack/runtime/` (e.g. `Lynx async chunks` → `webpack/runtime/lynx async chunks`), matching the path-structured naming of the bundler's built-in runtime modules. The previous bare names had no path segment, so when they appear as a source-map `sources` entry under a `file://` module-filename template they collapsed into an invalid URL authority (the space-containing name became the host) and broke `SourceMapConsumer` parsing. ([#2642](https://github.com/lynx-family/lynx-stack/pull/2642))
|
|
20
|
+
|
|
21
|
+
- Widen peer ranges to admit the new minor versions of `@lynx-js/template-webpack-plugin` (^0.12.0) and `@lynx-js/rspeedy` (^0.15.0) shipping with the unified `debug-metadata.json` feature. ([#2642](https://github.com/lynx-family/lynx-stack/pull/2642))
|
|
22
|
+
|
|
3
23
|
## 0.7.1
|
|
4
24
|
|
|
5
25
|
### Patch Changes
|
|
@@ -9,7 +9,7 @@ interface CssExtractRspackPluginOptions extends ExternalCssExtractRspackPluginOp
|
|
|
9
9
|
/**
|
|
10
10
|
* plugins passed to parser
|
|
11
11
|
*/
|
|
12
|
-
cssPlugins
|
|
12
|
+
cssPlugins?: Parameters<typeof LynxTemplatePlugin.convertCSSChunksToMap>[1];
|
|
13
13
|
/**
|
|
14
14
|
* The name of non-initial CSS chunk files
|
|
15
15
|
*/
|
|
@@ -75,7 +75,7 @@ declare class CssExtractRspackPlugin {
|
|
|
75
75
|
*
|
|
76
76
|
* @public
|
|
77
77
|
*/
|
|
78
|
-
static defaultOptions: Readonly<CssExtractRspackPluginOptions
|
|
78
|
+
static defaultOptions: Readonly<CssExtractRspackPluginOptions & Pick<Required<CssExtractRspackPluginOptions>, 'cssPlugins'>>;
|
|
79
79
|
/**
|
|
80
80
|
* The entry point of a webpack plugin.
|
|
81
81
|
* @param compiler - the webpack compiler
|
|
@@ -107,9 +107,7 @@ class CssExtractRspackPluginImpl {
|
|
|
107
107
|
}).apply(compiler);
|
|
108
108
|
compiler.hooks.thisCompilation.tap(this.name, (compilation) => {
|
|
109
109
|
if (this.isHMREnabled(compiler)) {
|
|
110
|
-
const hooks = LynxTemplatePlugin.getLynxTemplatePluginHooks(
|
|
111
|
-
// @ts-expect-error Rspack to Webpack Compilation
|
|
112
|
-
compilation);
|
|
110
|
+
const hooks = LynxTemplatePlugin.getLynxTemplatePluginHooks(compilation);
|
|
113
111
|
hooks.beforeEmit.tapPromise(this.name, async (args) => {
|
|
114
112
|
const cssChunks = args.cssChunks;
|
|
115
113
|
const content = cssChunks.map((chunk) => chunk.source.source().toString('utf-8'));
|
|
@@ -119,7 +117,8 @@ class CssExtractRspackPluginImpl {
|
|
|
119
117
|
if (!hotUpdateFilePath) {
|
|
120
118
|
continue;
|
|
121
119
|
}
|
|
122
|
-
const css = LynxTemplatePlugin.convertCSSChunksToMap(content, options.cssPlugins
|
|
120
|
+
const css = LynxTemplatePlugin.convertCSSChunksToMap(content, options.cssPlugins
|
|
121
|
+
?? CssExtractRspackPlugin.defaultOptions.cssPlugins, Boolean(args.finalEncodeOptions.compilerOptions['enableCSSSelector']));
|
|
123
122
|
const cssDeps = Object.entries(css.cssMap).reduce((acc, [key, value]) => {
|
|
124
123
|
const importRuleNodes = value.filter((node) => node.type === 'ImportRule');
|
|
125
124
|
acc[key] = importRuleNodes.map(({ href }) => href);
|
|
@@ -129,10 +128,12 @@ class CssExtractRspackPluginImpl {
|
|
|
129
128
|
const { compilerOptions: {
|
|
130
129
|
// remove the `templateDebugUrl` to avoid "emit different content to the same filename" error while chunk splitting is enabled, see #1481
|
|
131
130
|
templateDebugUrl, ...restCompilerOptions }, } = args.finalEncodeOptions;
|
|
131
|
+
const baseEncodeOptions = { ...args.finalEncodeOptions };
|
|
132
|
+
baseEncodeOptions.compilerOptions = restCompilerOptions;
|
|
133
|
+
delete baseEncodeOptions.elementTemplate;
|
|
132
134
|
const { buffer } = await hooks.encode.promise({
|
|
133
135
|
encodeOptions: {
|
|
134
|
-
...
|
|
135
|
-
compilerOptions: restCompilerOptions,
|
|
136
|
+
...baseEncodeOptions,
|
|
136
137
|
css,
|
|
137
138
|
lepusCode: {
|
|
138
139
|
root: undefined,
|
|
@@ -167,7 +168,7 @@ class CssExtractRspackPluginImpl {
|
|
|
167
168
|
const { RuntimeGlobals, RuntimeModule } = compiler.webpack;
|
|
168
169
|
class CSSHotUpdateRuntimeModule extends RuntimeModule {
|
|
169
170
|
constructor(hash, hotUpdateFiles) {
|
|
170
|
-
super('lynx css hot update');
|
|
171
|
+
super('webpack/runtime/lynx css hot update');
|
|
171
172
|
this.hash = hash;
|
|
172
173
|
this.hotUpdateFiles = hotUpdateFiles;
|
|
173
174
|
}
|
package/lib/index.d.ts
CHANGED
|
@@ -3,9 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* This plugin extracts CSS into separate files. It creates a CSS file per JS file which contains CSS and CSSId.
|
|
5
5
|
*/
|
|
6
|
-
export {
|
|
7
|
-
export type {
|
|
8
|
-
export type { LoaderOptions } from './loader.js';
|
|
9
|
-
export type { LoaderOptions as CssExtractRspackLoaderOptions } from './loader.js';
|
|
6
|
+
export type { LoaderOptions } from './rspack-loader.js';
|
|
7
|
+
export type { LoaderOptions as CssExtractRspackLoaderOptions } from './rspack-loader.js';
|
|
10
8
|
export { CssExtractRspackPlugin } from './CssExtractRspackPlugin.js';
|
|
11
9
|
export type { CssExtractRspackPluginOptions } from './CssExtractRspackPlugin.js';
|
package/lib/index.js
CHANGED
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
// Copyright 2024 The Lynx Authors. All rights reserved.
|
|
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
|
-
/**
|
|
5
|
-
* @packageDocumentation
|
|
6
|
-
*
|
|
7
|
-
* This plugin extracts CSS into separate files. It creates a CSS file per JS file which contains CSS and CSSId.
|
|
8
|
-
*/
|
|
9
|
-
export { CssExtractWebpackPlugin } from './CssExtractWebpackPlugin.js';
|
|
10
4
|
export { CssExtractRspackPlugin } from './CssExtractRspackPlugin.js';
|
|
11
5
|
//# sourceMappingURL=index.js.map
|
package/lib/rspack-loader.d.ts
CHANGED
|
@@ -1,5 +1,54 @@
|
|
|
1
1
|
import type { LoaderContext } from '@rspack/core';
|
|
2
|
-
import type { LoaderOptions } from './loader.js';
|
|
3
2
|
export declare function pitch(this: LoaderContext<LoaderOptions>, request: string,
|
|
4
3
|
/** previousRequest */ _: string, data: Record<string, unknown>): Promise<void>;
|
|
5
4
|
export default function loader(this: LoaderContext<LoaderOptions>, content: string): string | undefined;
|
|
5
|
+
/**
|
|
6
|
+
* The options of CSS extract loader.
|
|
7
|
+
*
|
|
8
|
+
* @public
|
|
9
|
+
*/
|
|
10
|
+
export interface LoaderOptions {
|
|
11
|
+
/**
|
|
12
|
+
* The same as {@link https://github.com/webpack-contrib/mini-css-extract-plugin/tree/master?tab=readme-ov-file#emit | mini-css-extract-plugin}.
|
|
13
|
+
* Control whether emit the CSS to filesystem.
|
|
14
|
+
*
|
|
15
|
+
* - If `true`(default), emits a file (writes a file to the filesystem).
|
|
16
|
+
*
|
|
17
|
+
* - If `false`, the plugin will extract the CSS but will not emit the file.
|
|
18
|
+
*
|
|
19
|
+
* It is often useful to disable this option for server-side packages.
|
|
20
|
+
*
|
|
21
|
+
* @defaultValue true
|
|
22
|
+
* @public
|
|
23
|
+
*/
|
|
24
|
+
emit?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* {@inheritdoc @lynx-js/rspeedy#CssExtractRspackLoaderOptions.esModule}
|
|
27
|
+
*/
|
|
28
|
+
esModule?: boolean | undefined;
|
|
29
|
+
/**
|
|
30
|
+
* The layer of the CSS execution.
|
|
31
|
+
*
|
|
32
|
+
* @remarks
|
|
33
|
+
*
|
|
34
|
+
* This should be combined with `experiments.layers`.
|
|
35
|
+
*/
|
|
36
|
+
layer?: string | undefined;
|
|
37
|
+
}
|
|
38
|
+
interface DependencySourceMap {
|
|
39
|
+
mappings?: string | undefined;
|
|
40
|
+
[key: string]: unknown;
|
|
41
|
+
}
|
|
42
|
+
export interface Dep {
|
|
43
|
+
identifier: string;
|
|
44
|
+
context: string | null;
|
|
45
|
+
content: Buffer;
|
|
46
|
+
media: string;
|
|
47
|
+
identifierIndex?: number;
|
|
48
|
+
supports?: string | undefined;
|
|
49
|
+
layer?: string | undefined;
|
|
50
|
+
sourceMap?: Buffer | undefined;
|
|
51
|
+
}
|
|
52
|
+
export declare function load(this: LoaderContext<LoaderOptions>, request: string, addDependencies: (deps: Dep[]) => void): Promise<string>;
|
|
53
|
+
export declare function offsetSourceMapLines<T extends DependencySourceMap>(sourceMap: T, lineOffset: number): T;
|
|
54
|
+
export {};
|
package/lib/rspack-loader.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
// Copyright 2024 The Lynx Authors. All rights reserved.
|
|
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
|
-
import
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
import { extractPathFromIdentifier, stringifyRequest } from './util.js';
|
|
5
7
|
export async function pitch(request,
|
|
6
8
|
/** previousRequest */ _, data) {
|
|
7
9
|
if (this._compiler?.options?.experiments?.css) {
|
|
@@ -17,9 +19,7 @@ export async function pitch(request,
|
|
|
17
19
|
// So the `load` function may crash.
|
|
18
20
|
// We make an temporary try-catch here.
|
|
19
21
|
// See: https://github.com/web-infra-dev/rspack/issues/8536
|
|
20
|
-
const resultSource = await load.call(
|
|
21
|
-
// @ts-expect-error webpack & rspack loaderContext
|
|
22
|
-
this, request, addDependencies.bind(this));
|
|
22
|
+
const resultSource = await load.call(this, request, addDependencies.bind(this));
|
|
23
23
|
callback(null, resultSource, undefined, data);
|
|
24
24
|
}
|
|
25
25
|
catch (error) {
|
|
@@ -47,4 +47,195 @@ export default function loader(content) {
|
|
|
47
47
|
}
|
|
48
48
|
return;
|
|
49
49
|
}
|
|
50
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
51
|
+
const BASE_URI = 'webpack://';
|
|
52
|
+
export async function load(request, addDependencies) {
|
|
53
|
+
/** TODO: schema */
|
|
54
|
+
const options = this.getOptions();
|
|
55
|
+
const emit = options.emit ?? true;
|
|
56
|
+
const esModule = options.esModule ?? true;
|
|
57
|
+
const moduleExports = await new Promise((resolve, reject) => {
|
|
58
|
+
this.importModule(`${this.resourcePath}.webpack[javascript/auto]!=!!!${request}`, {
|
|
59
|
+
baseUri: `${BASE_URI}/`,
|
|
60
|
+
layer: options.layer,
|
|
61
|
+
}, (err, exports) => {
|
|
62
|
+
if (err) {
|
|
63
|
+
return reject(err);
|
|
64
|
+
}
|
|
65
|
+
return resolve(exports);
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
let locals;
|
|
69
|
+
if (isNamedExports(moduleExports)) {
|
|
70
|
+
Object.keys(moduleExports).forEach((key) => {
|
|
71
|
+
if (key !== 'default') {
|
|
72
|
+
locals ??= {};
|
|
73
|
+
locals[key] = moduleExports[key];
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
locals =
|
|
79
|
+
(isCJSExports(moduleExports) ? moduleExports : moduleExports.default)
|
|
80
|
+
?.locals;
|
|
81
|
+
}
|
|
82
|
+
let dependencies;
|
|
83
|
+
const exportContent = isCJSExports(moduleExports)
|
|
84
|
+
? moduleExports
|
|
85
|
+
: moduleExports.default;
|
|
86
|
+
const { cssId: rawCssId } = parseQuery(this.resourceQuery);
|
|
87
|
+
const cssId = rawCssId ?? '';
|
|
88
|
+
const identifierCountMap = new Map();
|
|
89
|
+
if (Array.isArray(exportContent)) {
|
|
90
|
+
dependencies = exportContent.map(([identifier, content, media, sourceMap, supports, layer]) => {
|
|
91
|
+
const count = identifierCountMap.get(identifier) ?? 0;
|
|
92
|
+
const rawResourcePath = extractPathFromIdentifier(identifier, true);
|
|
93
|
+
const [resourcePath, resourceQuery] = rawResourcePath.split('?');
|
|
94
|
+
const params = new URLSearchParams(resourceQuery ? `?${resourceQuery}` : '');
|
|
95
|
+
if (params.get('cssId') === null) {
|
|
96
|
+
params.set('cssId', cssId);
|
|
97
|
+
}
|
|
98
|
+
const filePath = path.relative(this.rootContext, extractPathFromIdentifier(identifier));
|
|
99
|
+
const shouldWrapCSSId = Boolean(cssId)
|
|
100
|
+
&& (params.get('common') === null
|
|
101
|
+
|| params.get('common') === 'false');
|
|
102
|
+
identifierCountMap.set(identifier, count + 1);
|
|
103
|
+
return {
|
|
104
|
+
identifier: identifier.replace(rawResourcePath, `${resourcePath}?${params.toString()}`),
|
|
105
|
+
context: this.rootContext,
|
|
106
|
+
content: Buffer.from(shouldWrapCSSId
|
|
107
|
+
/**
|
|
108
|
+
* Given the following source code:
|
|
109
|
+
*
|
|
110
|
+
* ```css foo.css?cssId=1001
|
|
111
|
+
* @import 'bar.css'
|
|
112
|
+
* .foo {
|
|
113
|
+
* color: red;
|
|
114
|
+
* }
|
|
115
|
+
* ```
|
|
116
|
+
*
|
|
117
|
+
* ```css bar.css
|
|
118
|
+
* .bar {
|
|
119
|
+
* color: blue;
|
|
120
|
+
* }
|
|
121
|
+
* ```
|
|
122
|
+
*
|
|
123
|
+
* The output should be:
|
|
124
|
+
*
|
|
125
|
+
* ```css
|
|
126
|
+
* @cssId "1001" "bar.css" {
|
|
127
|
+
* .bar {
|
|
128
|
+
* color: blue;
|
|
129
|
+
* }
|
|
130
|
+
* }
|
|
131
|
+
* @cssId "1001" "foo.css" {
|
|
132
|
+
* .foo {
|
|
133
|
+
* color: red;
|
|
134
|
+
* }
|
|
135
|
+
* }
|
|
136
|
+
* ```
|
|
137
|
+
*/
|
|
138
|
+
? `@cssId "${cssId}" "${filePath}" {
|
|
139
|
+
${content}
|
|
140
|
+
}
|
|
141
|
+
`
|
|
142
|
+
: content),
|
|
143
|
+
media,
|
|
144
|
+
supports,
|
|
145
|
+
layer,
|
|
146
|
+
identifierIndex: count,
|
|
147
|
+
sourceMap: sourceMap
|
|
148
|
+
? Buffer.from(JSON.stringify(shouldWrapCSSId ? offsetSourceMapLines(sourceMap, 1) : sourceMap))
|
|
149
|
+
: undefined,
|
|
150
|
+
};
|
|
151
|
+
});
|
|
152
|
+
addDependencies(dependencies);
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
dependencies = [[null, exportContent]];
|
|
156
|
+
}
|
|
157
|
+
const result = (function makeResult() {
|
|
158
|
+
if (locals) {
|
|
159
|
+
if (isNamedExports(moduleExports)) {
|
|
160
|
+
const identifiers = Array.from((function* generateIdentifiers() {
|
|
161
|
+
let identifierId = 0;
|
|
162
|
+
for (const key of Object.keys(locals)) {
|
|
163
|
+
identifierId += 1;
|
|
164
|
+
yield [`_${identifierId.toString(16)}`, key];
|
|
165
|
+
}
|
|
166
|
+
})());
|
|
167
|
+
const localsString = identifiers
|
|
168
|
+
.map(
|
|
169
|
+
// TODO: support function locals
|
|
170
|
+
([id, key]) => `\nvar ${id} = ${JSON.stringify(locals[key])};`)
|
|
171
|
+
.join('');
|
|
172
|
+
const exportsString = `export { ${identifiers
|
|
173
|
+
.map(([id, key]) => `${id} as ${JSON.stringify(key)}`)
|
|
174
|
+
.join(', ')} }`;
|
|
175
|
+
return `${localsString}\n${exportsString}\n`;
|
|
176
|
+
}
|
|
177
|
+
return `\n${esModule ? 'export default' : 'module.exports = '} ${JSON.stringify(locals)};`;
|
|
178
|
+
}
|
|
179
|
+
else if (esModule) {
|
|
180
|
+
return '\nexport {};';
|
|
181
|
+
}
|
|
182
|
+
return '';
|
|
183
|
+
})();
|
|
184
|
+
let resultSource = `// extracted by mini-css-extract-plugin`;
|
|
185
|
+
// only attempt hot reloading if the css is actually used for something other than hash values
|
|
186
|
+
resultSource += this.hot && emit
|
|
187
|
+
? hotLoader(result, {
|
|
188
|
+
loaderContext: this,
|
|
189
|
+
options,
|
|
190
|
+
locals,
|
|
191
|
+
cssId,
|
|
192
|
+
})
|
|
193
|
+
: result;
|
|
194
|
+
return resultSource;
|
|
195
|
+
}
|
|
196
|
+
export function offsetSourceMapLines(sourceMap, lineOffset) {
|
|
197
|
+
if (lineOffset <= 0 || !sourceMap.mappings) {
|
|
198
|
+
return sourceMap;
|
|
199
|
+
}
|
|
200
|
+
return {
|
|
201
|
+
...sourceMap,
|
|
202
|
+
mappings: `${';'.repeat(lineOffset)}${sourceMap.mappings}`,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
function hotLoader(content, context) {
|
|
206
|
+
const localsJsonString = JSON.stringify(JSON.stringify(context.locals));
|
|
207
|
+
return `${content}
|
|
208
|
+
if (module.hot) {
|
|
209
|
+
(function() {
|
|
210
|
+
var localsJsonString = ${localsJsonString};
|
|
211
|
+
// ${Date.now()}
|
|
212
|
+
var cssReload = require(${stringifyRequest(context.loaderContext, path.resolve(__dirname, '../runtime/hotModuleReplacement.cjs'))})(module.id, ${JSON.stringify(context.options)}, "${context.cssId ?? '0'}");
|
|
213
|
+
// only invalidate when locals change
|
|
214
|
+
if (
|
|
215
|
+
module.hot.data &&
|
|
216
|
+
module.hot.data.value &&
|
|
217
|
+
module.hot.data.value !== localsJsonString
|
|
218
|
+
) {
|
|
219
|
+
module.hot.invalidate();
|
|
220
|
+
} else {
|
|
221
|
+
module.hot.accept();
|
|
222
|
+
}
|
|
223
|
+
module.hot.dispose(function(data) {
|
|
224
|
+
data.value = localsJsonString;
|
|
225
|
+
cssReload();
|
|
226
|
+
});
|
|
227
|
+
})();
|
|
228
|
+
}`;
|
|
229
|
+
}
|
|
230
|
+
function isCJSExports(exports) {
|
|
231
|
+
return !exports.__esModule;
|
|
232
|
+
}
|
|
233
|
+
function isNamedExports(exports) {
|
|
234
|
+
return !isCJSExports(exports)
|
|
235
|
+
&& (!exports.default || !('locals' in exports.default));
|
|
236
|
+
}
|
|
237
|
+
function parseQuery(query) {
|
|
238
|
+
const params = new URLSearchParams(query);
|
|
239
|
+
return Object.fromEntries(params);
|
|
240
|
+
}
|
|
50
241
|
//# sourceMappingURL=rspack-loader.js.map
|
package/lib/util.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
1
|
+
import type { LoaderContext } from '@rspack/core';
|
|
2
|
+
import type { LoaderOptions } from './rspack-loader.js';
|
|
3
3
|
export declare function isAbsolutePath(str: string): boolean;
|
|
4
4
|
export declare function isRelativePath(str: string): boolean;
|
|
5
5
|
export declare function stringifyRequest(loaderContext: LoaderContext<LoaderOptions>, request: string): string;
|
package/lib/util.js
CHANGED
|
@@ -12,7 +12,7 @@ export function isRelativePath(str) {
|
|
|
12
12
|
export function stringifyRequest(loaderContext, request) {
|
|
13
13
|
if (typeof loaderContext.utils !== 'undefined'
|
|
14
14
|
&& typeof loaderContext.utils.contextify === 'function') {
|
|
15
|
-
return JSON.stringify(loaderContext.utils.contextify(loaderContext.context
|
|
15
|
+
return JSON.stringify(loaderContext.utils.contextify(loaderContext.context ?? loaderContext.rootContext, request));
|
|
16
16
|
}
|
|
17
17
|
const split = request.split('!');
|
|
18
18
|
const { context } = loaderContext;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lynx-js/css-extract-webpack-plugin",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.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",
|
|
@@ -40,28 +40,24 @@
|
|
|
40
40
|
"CHANGELOG.md",
|
|
41
41
|
"README.md"
|
|
42
42
|
],
|
|
43
|
-
"dependencies": {
|
|
44
|
-
"mini-css-extract-plugin": "^2.10.0"
|
|
45
|
-
},
|
|
46
43
|
"devDependencies": {
|
|
47
44
|
"@microsoft/api-extractor": "7.58.2",
|
|
48
|
-
"@rspack/core": "
|
|
45
|
+
"@rspack/core": "2.0.8",
|
|
46
|
+
"@rstest/core": "0.10.5",
|
|
49
47
|
"css-loader": "^7.1.4",
|
|
50
48
|
"sass-loader": "^16.0.7",
|
|
51
|
-
"webpack": "^5.105.2",
|
|
52
49
|
"@lynx-js/css-serializer": "0.1.6",
|
|
53
|
-
"@lynx-js/template-webpack-plugin": "0.
|
|
54
|
-
"@lynx-js/test-tools": "0.0.0"
|
|
55
|
-
"@lynx-js/vitest-setup": "0.0.0"
|
|
50
|
+
"@lynx-js/template-webpack-plugin": "0.12.0",
|
|
51
|
+
"@lynx-js/test-tools": "0.0.0"
|
|
56
52
|
},
|
|
57
53
|
"peerDependencies": {
|
|
58
|
-
"@lynx-js/template-webpack-plugin": "^0.11.0"
|
|
54
|
+
"@lynx-js/template-webpack-plugin": "^0.11.0 || ^0.12.0"
|
|
59
55
|
},
|
|
60
56
|
"engines": {
|
|
61
57
|
"node": ">=18"
|
|
62
58
|
},
|
|
63
59
|
"scripts": {
|
|
64
60
|
"api-extractor": "api-extractor run --verbose",
|
|
65
|
-
"test": "
|
|
61
|
+
"test": "rstest"
|
|
66
62
|
}
|
|
67
63
|
}
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
|
|
2
|
-
import type { Compiler } from 'webpack';
|
|
3
|
-
/**
|
|
4
|
-
* The options for CssExtractWebpackPlugin
|
|
5
|
-
*
|
|
6
|
-
* @public
|
|
7
|
-
*/
|
|
8
|
-
interface CssExtractWebpackPluginOptions extends MiniCssExtractPlugin.PluginOptions {
|
|
9
|
-
}
|
|
10
|
-
/**
|
|
11
|
-
* @public
|
|
12
|
-
*
|
|
13
|
-
* CssExtractWebpackPlugin is the CSS extract plugin for Lynx.
|
|
14
|
-
* It works just like the {@link https://github.com/webpack-contrib/mini-css-extract-plugin | MiniCssExtractPlugin} in Web.
|
|
15
|
-
*
|
|
16
|
-
* @example
|
|
17
|
-
* ```js
|
|
18
|
-
* import { CssExtractWebpackPlugin } from '@lynx-js/css-extract-webpack-plugin'
|
|
19
|
-
* export default {
|
|
20
|
-
* plugins: [new CssExtractWebpackPlugin()],
|
|
21
|
-
* module: {
|
|
22
|
-
* rules: [
|
|
23
|
-
* {
|
|
24
|
-
* test: /\.css$/,
|
|
25
|
-
* uses: [CssExtractWebpackPlugin.loader, 'css-loader'],
|
|
26
|
-
* },
|
|
27
|
-
* ],
|
|
28
|
-
* },
|
|
29
|
-
* }
|
|
30
|
-
* ```
|
|
31
|
-
*/
|
|
32
|
-
declare class CssExtractWebpackPlugin {
|
|
33
|
-
private readonly options?;
|
|
34
|
-
constructor(options?: CssExtractWebpackPluginOptions | undefined);
|
|
35
|
-
/**
|
|
36
|
-
* The loader to extract CSS.
|
|
37
|
-
*
|
|
38
|
-
* @remarks
|
|
39
|
-
* It should be used with the {@link https://github.com/webpack-contrib/css-loader | 'css-loader'}.
|
|
40
|
-
*
|
|
41
|
-
* @example
|
|
42
|
-
*
|
|
43
|
-
* ```js
|
|
44
|
-
* import { CssExtractWebpackPlugin } from '@lynx-js/css-extract-webpack-plugin'
|
|
45
|
-
* export default {
|
|
46
|
-
* plugins: [new CssExtractWebpackPlugin()],
|
|
47
|
-
* module: {
|
|
48
|
-
* rules: [
|
|
49
|
-
* {
|
|
50
|
-
* test: /\.css$/,
|
|
51
|
-
* uses: [CssExtractWebpackPlugin.loader, 'css-loader'],
|
|
52
|
-
* },
|
|
53
|
-
* ],
|
|
54
|
-
* },
|
|
55
|
-
* }
|
|
56
|
-
* ```
|
|
57
|
-
*
|
|
58
|
-
* @public
|
|
59
|
-
*/
|
|
60
|
-
static loader: string;
|
|
61
|
-
/**
|
|
62
|
-
* `defaultOptions` is the default options that the {@link CssExtractWebpackPlugin} uses.
|
|
63
|
-
*
|
|
64
|
-
* @public
|
|
65
|
-
*/
|
|
66
|
-
static defaultOptions: Readonly<Required<CssExtractWebpackPluginOptions>>;
|
|
67
|
-
/**
|
|
68
|
-
* The entry point of a webpack plugin.
|
|
69
|
-
* @param compiler - the webpack compiler
|
|
70
|
-
*/
|
|
71
|
-
apply(compiler: Compiler): void;
|
|
72
|
-
}
|
|
73
|
-
export { CssExtractWebpackPlugin };
|
|
74
|
-
export type { CssExtractWebpackPluginOptions };
|
|
@@ -1,99 +0,0 @@
|
|
|
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 { createRequire } from 'node:module';
|
|
5
|
-
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
|
|
6
|
-
const require = createRequire(import.meta.url);
|
|
7
|
-
/**
|
|
8
|
-
* @public
|
|
9
|
-
*
|
|
10
|
-
* CssExtractWebpackPlugin is the CSS extract plugin for Lynx.
|
|
11
|
-
* It works just like the {@link https://github.com/webpack-contrib/mini-css-extract-plugin | MiniCssExtractPlugin} in Web.
|
|
12
|
-
*
|
|
13
|
-
* @example
|
|
14
|
-
* ```js
|
|
15
|
-
* import { CssExtractWebpackPlugin } from '@lynx-js/css-extract-webpack-plugin'
|
|
16
|
-
* export default {
|
|
17
|
-
* plugins: [new CssExtractWebpackPlugin()],
|
|
18
|
-
* module: {
|
|
19
|
-
* rules: [
|
|
20
|
-
* {
|
|
21
|
-
* test: /\.css$/,
|
|
22
|
-
* uses: [CssExtractWebpackPlugin.loader, 'css-loader'],
|
|
23
|
-
* },
|
|
24
|
-
* ],
|
|
25
|
-
* },
|
|
26
|
-
* }
|
|
27
|
-
* ```
|
|
28
|
-
*/
|
|
29
|
-
class CssExtractWebpackPlugin {
|
|
30
|
-
constructor(options) {
|
|
31
|
-
this.options = options;
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* The loader to extract CSS.
|
|
35
|
-
*
|
|
36
|
-
* @remarks
|
|
37
|
-
* It should be used with the {@link https://github.com/webpack-contrib/css-loader | 'css-loader'}.
|
|
38
|
-
*
|
|
39
|
-
* @example
|
|
40
|
-
*
|
|
41
|
-
* ```js
|
|
42
|
-
* import { CssExtractWebpackPlugin } from '@lynx-js/css-extract-webpack-plugin'
|
|
43
|
-
* export default {
|
|
44
|
-
* plugins: [new CssExtractWebpackPlugin()],
|
|
45
|
-
* module: {
|
|
46
|
-
* rules: [
|
|
47
|
-
* {
|
|
48
|
-
* test: /\.css$/,
|
|
49
|
-
* uses: [CssExtractWebpackPlugin.loader, 'css-loader'],
|
|
50
|
-
* },
|
|
51
|
-
* ],
|
|
52
|
-
* },
|
|
53
|
-
* }
|
|
54
|
-
* ```
|
|
55
|
-
*
|
|
56
|
-
* @public
|
|
57
|
-
*/
|
|
58
|
-
static { this.loader = require.resolve('./loader.js'); }
|
|
59
|
-
/**
|
|
60
|
-
* `defaultOptions` is the default options that the {@link CssExtractWebpackPlugin} uses.
|
|
61
|
-
*
|
|
62
|
-
* @public
|
|
63
|
-
*/
|
|
64
|
-
static { this.defaultOptions = Object.freeze({
|
|
65
|
-
filename: '[name].css',
|
|
66
|
-
chunkFilename: undefined,
|
|
67
|
-
ignoreOrder: undefined,
|
|
68
|
-
insert: undefined,
|
|
69
|
-
attributes: undefined,
|
|
70
|
-
linkType: undefined,
|
|
71
|
-
runtime: undefined,
|
|
72
|
-
experimentalUseImportModule: undefined,
|
|
73
|
-
}); }
|
|
74
|
-
/**
|
|
75
|
-
* The entry point of a webpack plugin.
|
|
76
|
-
* @param compiler - the webpack compiler
|
|
77
|
-
*/
|
|
78
|
-
apply(compiler) {
|
|
79
|
-
new CssExtractWebpackPluginImpl(compiler, Object.assign({}, CssExtractWebpackPlugin.defaultOptions, this.options));
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
export { CssExtractWebpackPlugin };
|
|
83
|
-
class CssExtractWebpackPluginImpl {
|
|
84
|
-
constructor(compiler, options) {
|
|
85
|
-
this.options = options;
|
|
86
|
-
this.name = 'CssExtractWebpackPlugin';
|
|
87
|
-
new MiniCssExtractPlugin({
|
|
88
|
-
filename: options.filename,
|
|
89
|
-
chunkFilename: options.chunkFilename,
|
|
90
|
-
ignoreOrder: options.ignoreOrder,
|
|
91
|
-
insert: options.insert,
|
|
92
|
-
attributes: options.attributes,
|
|
93
|
-
linkType: options.linkType,
|
|
94
|
-
runtime: options.runtime,
|
|
95
|
-
experimentalUseImportModule: options.experimentalUseImportModule,
|
|
96
|
-
}).apply(compiler);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
//# sourceMappingURL=CssExtractWebpackPlugin.js.map
|
package/lib/loader.d.ts
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import type { LoaderContext } from 'webpack';
|
|
2
|
-
/**
|
|
3
|
-
* The options of CSS extract loader.
|
|
4
|
-
*
|
|
5
|
-
* @public
|
|
6
|
-
*/
|
|
7
|
-
export interface LoaderOptions {
|
|
8
|
-
/**
|
|
9
|
-
* The same as {@link https://github.com/webpack-contrib/mini-css-extract-plugin/tree/master?tab=readme-ov-file#emit | mini-css-extract-plugin}.
|
|
10
|
-
* Control whether emit the CSS to filesystem.
|
|
11
|
-
*
|
|
12
|
-
* - If `true`(default), emits a file (writes a file to the filesystem).
|
|
13
|
-
*
|
|
14
|
-
* - If `false`, the plugin will extract the CSS but will not emit the file.
|
|
15
|
-
*
|
|
16
|
-
* It is often useful to disable this option for server-side packages.
|
|
17
|
-
*
|
|
18
|
-
* @defaultValue true
|
|
19
|
-
* @public
|
|
20
|
-
*/
|
|
21
|
-
emit?: boolean;
|
|
22
|
-
/**
|
|
23
|
-
* {@inheritdoc @lynx-js/rspeedy#CssExtractRspackLoaderOptions.esModule}
|
|
24
|
-
*/
|
|
25
|
-
esModule?: boolean | undefined;
|
|
26
|
-
/**
|
|
27
|
-
* The layer of the CSS execution.
|
|
28
|
-
*
|
|
29
|
-
* @remarks
|
|
30
|
-
*
|
|
31
|
-
* This should be combined with `experiments.layers`.
|
|
32
|
-
*/
|
|
33
|
-
layer?: string | undefined;
|
|
34
|
-
}
|
|
35
|
-
interface DependencySourceMap {
|
|
36
|
-
mappings?: string | undefined;
|
|
37
|
-
[key: string]: unknown;
|
|
38
|
-
}
|
|
39
|
-
export interface Dep {
|
|
40
|
-
identifier: string;
|
|
41
|
-
context: string | null;
|
|
42
|
-
content: Buffer;
|
|
43
|
-
media: string;
|
|
44
|
-
identifierIndex?: number;
|
|
45
|
-
supports?: string | undefined;
|
|
46
|
-
layer?: string | undefined;
|
|
47
|
-
sourceMap?: Buffer | undefined;
|
|
48
|
-
}
|
|
49
|
-
export declare function load(this: LoaderContext<LoaderOptions>, request: string, addDependencies: (deps: Dep[]) => void): Promise<string>;
|
|
50
|
-
export declare function offsetSourceMapLines<T extends DependencySourceMap>(sourceMap: T, lineOffset: number): T;
|
|
51
|
-
export declare function pitch(this: LoaderContext<LoaderOptions>, request: string): Promise<string | undefined>;
|
|
52
|
-
export default function loader(this: LoaderContext<LoaderOptions>, content: string): string | undefined;
|
|
53
|
-
export {};
|
package/lib/loader.js
DELETED
|
@@ -1,241 +0,0 @@
|
|
|
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 path from 'node:path';
|
|
5
|
-
import { fileURLToPath } from 'node:url';
|
|
6
|
-
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
|
|
7
|
-
import { extractPathFromIdentifier, stringifyRequest } from './util.js';
|
|
8
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
9
|
-
const BASE_URI = 'webpack://';
|
|
10
|
-
export async function load(request, addDependencies) {
|
|
11
|
-
/** TODO: schema */
|
|
12
|
-
const options = this.getOptions();
|
|
13
|
-
const emit = options.emit ?? true;
|
|
14
|
-
const esModule = options.esModule ?? true;
|
|
15
|
-
const moduleExports = await new Promise((resolve, reject) => {
|
|
16
|
-
this.importModule(`${this.resourcePath}.webpack[javascript/auto]!=!!!${request}`, {
|
|
17
|
-
baseUri: `${BASE_URI}/`,
|
|
18
|
-
layer: options.layer,
|
|
19
|
-
}, (err, exports) => {
|
|
20
|
-
if (err) {
|
|
21
|
-
return reject(err);
|
|
22
|
-
}
|
|
23
|
-
return resolve(exports);
|
|
24
|
-
});
|
|
25
|
-
});
|
|
26
|
-
let locals;
|
|
27
|
-
if (isNamedExports(moduleExports)) {
|
|
28
|
-
Object.keys(moduleExports).forEach((key) => {
|
|
29
|
-
if (key !== 'default') {
|
|
30
|
-
locals ??= {};
|
|
31
|
-
locals[key] = moduleExports[key];
|
|
32
|
-
}
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
else {
|
|
36
|
-
locals =
|
|
37
|
-
(isCJSExports(moduleExports) ? moduleExports : moduleExports.default)
|
|
38
|
-
?.locals;
|
|
39
|
-
}
|
|
40
|
-
let dependencies;
|
|
41
|
-
const exportContent = isCJSExports(moduleExports)
|
|
42
|
-
? moduleExports
|
|
43
|
-
: moduleExports.default;
|
|
44
|
-
const { cssId: rawCssId } = parseQuery(this.resourceQuery);
|
|
45
|
-
const cssId = rawCssId ?? '';
|
|
46
|
-
const identifierCountMap = new Map();
|
|
47
|
-
if (Array.isArray(exportContent)) {
|
|
48
|
-
dependencies = exportContent.map(([identifier, content, media, sourceMap, supports, layer]) => {
|
|
49
|
-
const count = identifierCountMap.get(identifier) ?? 0;
|
|
50
|
-
const rawResourcePath = extractPathFromIdentifier(identifier, true);
|
|
51
|
-
const [resourcePath, resourceQuery] = rawResourcePath.split('?');
|
|
52
|
-
const params = new URLSearchParams(resourceQuery ? `?${resourceQuery}` : '');
|
|
53
|
-
if (params.get('cssId') === null) {
|
|
54
|
-
params.set('cssId', cssId);
|
|
55
|
-
}
|
|
56
|
-
const filePath = path.relative(this.rootContext, extractPathFromIdentifier(identifier));
|
|
57
|
-
const shouldWrapCSSId = Boolean(cssId)
|
|
58
|
-
&& (params.get('common') === null
|
|
59
|
-
|| params.get('common') === 'false');
|
|
60
|
-
identifierCountMap.set(identifier, count + 1);
|
|
61
|
-
return {
|
|
62
|
-
identifier: identifier.replace(rawResourcePath, `${resourcePath}?${params.toString()}`),
|
|
63
|
-
context: this.rootContext,
|
|
64
|
-
content: Buffer.from(shouldWrapCSSId
|
|
65
|
-
/**
|
|
66
|
-
* Given the following source code:
|
|
67
|
-
*
|
|
68
|
-
* ```css foo.css?cssId=1001
|
|
69
|
-
* @import 'bar.css'
|
|
70
|
-
* .foo {
|
|
71
|
-
* color: red;
|
|
72
|
-
* }
|
|
73
|
-
* ```
|
|
74
|
-
*
|
|
75
|
-
* ```css bar.css
|
|
76
|
-
* .bar {
|
|
77
|
-
* color: blue;
|
|
78
|
-
* }
|
|
79
|
-
* ```
|
|
80
|
-
*
|
|
81
|
-
* The output should be:
|
|
82
|
-
*
|
|
83
|
-
* ```css
|
|
84
|
-
* @cssId "1001" "bar.css" {
|
|
85
|
-
* .bar {
|
|
86
|
-
* color: blue;
|
|
87
|
-
* }
|
|
88
|
-
* }
|
|
89
|
-
* @cssId "1001" "foo.css" {
|
|
90
|
-
* .foo {
|
|
91
|
-
* color: red;
|
|
92
|
-
* }
|
|
93
|
-
* }
|
|
94
|
-
* ```
|
|
95
|
-
*/
|
|
96
|
-
? `@cssId "${cssId}" "${filePath}" {
|
|
97
|
-
${content}
|
|
98
|
-
}
|
|
99
|
-
`
|
|
100
|
-
: content),
|
|
101
|
-
media,
|
|
102
|
-
supports,
|
|
103
|
-
layer,
|
|
104
|
-
identifierIndex: count,
|
|
105
|
-
sourceMap: sourceMap
|
|
106
|
-
? Buffer.from(JSON.stringify(shouldWrapCSSId ? offsetSourceMapLines(sourceMap, 1) : sourceMap))
|
|
107
|
-
: undefined,
|
|
108
|
-
};
|
|
109
|
-
});
|
|
110
|
-
addDependencies(dependencies);
|
|
111
|
-
}
|
|
112
|
-
else {
|
|
113
|
-
dependencies = [[null, exportContent]];
|
|
114
|
-
}
|
|
115
|
-
const result = (function makeResult() {
|
|
116
|
-
if (locals) {
|
|
117
|
-
if (isNamedExports(moduleExports)) {
|
|
118
|
-
const identifiers = Array.from((function* generateIdentifiers() {
|
|
119
|
-
let identifierId = 0;
|
|
120
|
-
for (const key of Object.keys(locals)) {
|
|
121
|
-
identifierId += 1;
|
|
122
|
-
yield [`_${identifierId.toString(16)}`, key];
|
|
123
|
-
}
|
|
124
|
-
})());
|
|
125
|
-
const localsString = identifiers
|
|
126
|
-
.map(
|
|
127
|
-
// TODO: support function locals
|
|
128
|
-
([id, key]) => `\nvar ${id} = ${JSON.stringify(locals[key])};`)
|
|
129
|
-
.join('');
|
|
130
|
-
const exportsString = `export { ${identifiers
|
|
131
|
-
.map(([id, key]) => `${id} as ${JSON.stringify(key)}`)
|
|
132
|
-
.join(', ')} }`;
|
|
133
|
-
return `${localsString}\n${exportsString}\n`;
|
|
134
|
-
}
|
|
135
|
-
return `\n${esModule ? 'export default' : 'module.exports = '} ${JSON.stringify(locals)};`;
|
|
136
|
-
}
|
|
137
|
-
else if (esModule) {
|
|
138
|
-
return '\nexport {};';
|
|
139
|
-
}
|
|
140
|
-
return '';
|
|
141
|
-
})();
|
|
142
|
-
let resultSource = `// extracted by ${MiniCssExtractPlugin.pluginName}`;
|
|
143
|
-
// only attempt hot reloading if the css is actually used for something other than hash values
|
|
144
|
-
resultSource += this.hot && emit
|
|
145
|
-
? hotLoader(result, {
|
|
146
|
-
loaderContext: this,
|
|
147
|
-
options,
|
|
148
|
-
locals,
|
|
149
|
-
cssId,
|
|
150
|
-
})
|
|
151
|
-
: result;
|
|
152
|
-
return resultSource;
|
|
153
|
-
}
|
|
154
|
-
export function offsetSourceMapLines(sourceMap, lineOffset) {
|
|
155
|
-
if (lineOffset <= 0 || !sourceMap.mappings) {
|
|
156
|
-
return sourceMap;
|
|
157
|
-
}
|
|
158
|
-
return {
|
|
159
|
-
...sourceMap,
|
|
160
|
-
mappings: `${';'.repeat(lineOffset)}${sourceMap.mappings}`,
|
|
161
|
-
};
|
|
162
|
-
}
|
|
163
|
-
export async function pitch(request) {
|
|
164
|
-
if (this._compiler?.options?.experiments?.css
|
|
165
|
-
&& this._module
|
|
166
|
-
&& (this._module.type === 'css'
|
|
167
|
-
|| this._module.type === 'css/auto'
|
|
168
|
-
|| this._module.type === 'css/global'
|
|
169
|
-
|| this._module.type === 'css/module')) {
|
|
170
|
-
this.emitWarning(new Error('You can\'t use `experiments.css` (`experiments.futureDefaults` enable built-in CSS support by default) and `@lynx-js/css-extract-webpack-plugin` together, please set `experiments.css` to `false` or set `{ type: "javascript/auto" }` for rules with `@lynx-js/css-extract-webpack-plugin` in your webpack config (now `@lynx-js/css-extract-webpack-plugin` does nothing).'));
|
|
171
|
-
return;
|
|
172
|
-
}
|
|
173
|
-
/** TODO: schema */
|
|
174
|
-
const options = this.getOptions();
|
|
175
|
-
const emit = options.emit ?? true;
|
|
176
|
-
const addDependencies = (dependencies) => {
|
|
177
|
-
const { webpack } = this._compiler;
|
|
178
|
-
if (!Array.isArray(dependencies) && dependencies !== null) {
|
|
179
|
-
throw new Error(`Exported value was not extracted as an array: ${JSON.stringify(dependencies)}`);
|
|
180
|
-
}
|
|
181
|
-
const identifierCountMap = new Map();
|
|
182
|
-
for (const dependency of dependencies) {
|
|
183
|
-
if (!('identifier' in dependency) || !emit) {
|
|
184
|
-
continue;
|
|
185
|
-
}
|
|
186
|
-
const CssDependency = MiniCssExtractPlugin.getCssDependency(webpack);
|
|
187
|
-
const count = identifierCountMap.get(dependency.identifier) ?? 0;
|
|
188
|
-
this._module.addDependency(new CssDependency(dependency, dependency.context, count));
|
|
189
|
-
identifierCountMap.set(dependency.identifier, count + 1);
|
|
190
|
-
}
|
|
191
|
-
};
|
|
192
|
-
return await load.call(this, request, addDependencies);
|
|
193
|
-
}
|
|
194
|
-
export default function loader(content) {
|
|
195
|
-
if (this._compiler?.options?.experiments?.css
|
|
196
|
-
&& this._module
|
|
197
|
-
&& (this._module.type === 'css'
|
|
198
|
-
|| this._module.type === 'css/auto'
|
|
199
|
-
|| this._module.type === 'css/global'
|
|
200
|
-
|| this._module.type === 'css/module')) {
|
|
201
|
-
return content;
|
|
202
|
-
}
|
|
203
|
-
return;
|
|
204
|
-
}
|
|
205
|
-
function hotLoader(content, context) {
|
|
206
|
-
const localsJsonString = JSON.stringify(JSON.stringify(context.locals));
|
|
207
|
-
return `${content}
|
|
208
|
-
if (module.hot) {
|
|
209
|
-
(function() {
|
|
210
|
-
var localsJsonString = ${localsJsonString};
|
|
211
|
-
// ${Date.now()}
|
|
212
|
-
var cssReload = require(${stringifyRequest(context.loaderContext, path.resolve(__dirname, '../runtime/hotModuleReplacement.cjs'))})(module.id, ${JSON.stringify(context.options)}, "${context.cssId ?? '0'}");
|
|
213
|
-
// only invalidate when locals change
|
|
214
|
-
if (
|
|
215
|
-
module.hot.data &&
|
|
216
|
-
module.hot.data.value &&
|
|
217
|
-
module.hot.data.value !== localsJsonString
|
|
218
|
-
) {
|
|
219
|
-
module.hot.invalidate();
|
|
220
|
-
} else {
|
|
221
|
-
module.hot.accept();
|
|
222
|
-
}
|
|
223
|
-
module.hot.dispose(function(data) {
|
|
224
|
-
data.value = localsJsonString;
|
|
225
|
-
cssReload();
|
|
226
|
-
});
|
|
227
|
-
})();
|
|
228
|
-
}`;
|
|
229
|
-
}
|
|
230
|
-
function isCJSExports(exports) {
|
|
231
|
-
return !exports.__esModule;
|
|
232
|
-
}
|
|
233
|
-
function isNamedExports(exports) {
|
|
234
|
-
return !isCJSExports(exports)
|
|
235
|
-
&& (!exports.default || !('locals' in exports.default));
|
|
236
|
-
}
|
|
237
|
-
function parseQuery(query) {
|
|
238
|
-
const params = new URLSearchParams(query);
|
|
239
|
-
return Object.fromEntries(params);
|
|
240
|
-
}
|
|
241
|
-
//# sourceMappingURL=loader.js.map
|