@griffel/webpack-plugin 2.0.0 → 3.0.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 +16 -2
- package/GriffelPlugin.d.mts +2 -1
- package/constants.d.mts +3 -1
- package/package.json +2 -2
- package/resolver/createResolverFactory.d.mts +3 -1
- package/webpack-loader.js +11 -13
- package/webpack-plugin.js +58 -16
- package/webpackLoader.d.mts +1 -1
- package/resolver/types.d.mts +0 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,12 +1,26 @@
|
|
|
1
1
|
# Change Log - @griffel/webpack-plugin
|
|
2
2
|
|
|
3
|
-
This log was last generated on
|
|
3
|
+
This log was last generated on Wed, 11 Mar 2026 13:31:20 GMT and should not be manually modified.
|
|
4
4
|
|
|
5
5
|
<!-- Start content -->
|
|
6
6
|
|
|
7
|
+
## 3.0.0
|
|
8
|
+
|
|
9
|
+
Wed, 11 Mar 2026 13:31:20 GMT
|
|
10
|
+
|
|
11
|
+
### Major changes
|
|
12
|
+
|
|
13
|
+
- BREAKING: Remove babelOptions from WebpackLoaderOptions. Uses @griffel/transform-shaker instead of @linaria/shaker. (olfedias@microsoft.com)
|
|
14
|
+
- Bump @griffel/transform to v2.0.0
|
|
15
|
+
|
|
16
|
+
### Patches
|
|
17
|
+
|
|
18
|
+
- fix: make CJS the default resolver, ESM the clone (olfedias@microsoft.com)
|
|
19
|
+
- feat: add collectPerfIssues option to report CJS modules and barrel re-exports (olfedias@microsoft.com)
|
|
20
|
+
|
|
7
21
|
## 2.0.0
|
|
8
22
|
|
|
9
|
-
Fri, 06 Mar 2026 15:
|
|
23
|
+
Fri, 06 Mar 2026 15:56:28 GMT
|
|
10
24
|
|
|
11
25
|
### Major changes
|
|
12
26
|
|
package/GriffelPlugin.d.mts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { GriffelRenderer } from '@griffel/core';
|
|
2
2
|
import { Compilation, Compiler } from 'webpack';
|
|
3
|
-
import { TransformResolverFactory } from './resolver/
|
|
3
|
+
import { TransformResolverFactory } from './resolver/createResolverFactory.mjs';
|
|
4
4
|
type EntryPoint = Compilation['entrypoints'] extends Map<unknown, infer I> ? I : never;
|
|
5
5
|
export type GriffelCSSExtractionPluginOptions = {
|
|
6
6
|
collectStats?: boolean;
|
|
7
|
+
collectPerfIssues?: boolean;
|
|
7
8
|
compareMediaQueries?: GriffelRenderer['compareMediaQueries'];
|
|
8
9
|
/** Allows to override resolver used to resolve imports inside evaluated modules. */
|
|
9
10
|
resolverFactory?: TransformResolverFactory;
|
package/constants.d.mts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { LoaderContext } from 'webpack';
|
|
2
|
-
import { TransformResolver } from '
|
|
2
|
+
import { TransformResolver, TransformPerfIssue } from '@griffel/transform';
|
|
3
3
|
export declare const PLUGIN_NAME = "GriffelExtractPlugin";
|
|
4
4
|
export declare const GriffelCssLoaderContextKey: unique symbol;
|
|
5
5
|
export interface GriffelLoaderContextSupplement {
|
|
6
|
+
collectPerfIssues: boolean;
|
|
6
7
|
resolveModule: TransformResolver;
|
|
7
8
|
registerExtractedCss(css: string): void;
|
|
8
9
|
getExtractedCss(): string;
|
|
@@ -12,6 +13,7 @@ export interface GriffelLoaderContextSupplement {
|
|
|
12
13
|
filename: string;
|
|
13
14
|
step: 'transform';
|
|
14
15
|
evaluationMode: 'ast' | 'vm';
|
|
16
|
+
perfIssues?: TransformPerfIssue[];
|
|
15
17
|
};
|
|
16
18
|
}): T;
|
|
17
19
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@griffel/webpack-plugin",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "Webpack plugin that performs CSS extraction for Griffel",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
"./package.json": "./package.json"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@griffel/transform": "^1.2.1",
|
|
24
23
|
"@griffel/core": "^1.20.1",
|
|
24
|
+
"@griffel/transform": "^2.0.0",
|
|
25
25
|
"oxc-resolver": "^11.19.1",
|
|
26
26
|
"stylis": "^4.2.0"
|
|
27
27
|
},
|
|
@@ -1,2 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { TransformResolver } from '@griffel/transform';
|
|
2
|
+
import { Compilation } from 'webpack';
|
|
3
|
+
export type TransformResolverFactory = (compilation: Compilation) => TransformResolver;
|
|
2
4
|
export declare function createResolverFactory(): TransformResolverFactory;
|
package/webpack-loader.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ASSET_TAG_OPEN, ASSET_TAG_CLOSE, EvalCache,
|
|
1
|
+
import { ASSET_TAG_OPEN, ASSET_TAG_CLOSE, EvalCache, transformSync } from "@griffel/transform";
|
|
2
2
|
import * as path from "node:path";
|
|
3
3
|
import { G as GriffelCssLoaderContextKey } from "./constants-aY3k4vvW.js";
|
|
4
4
|
import { normalizeCSSBucketEntry } from "@griffel/core";
|
|
@@ -86,36 +86,34 @@ function webpackLoader(sourceCode, inputSourceMap) {
|
|
|
86
86
|
throw new Error("GriffelCSSExtractionPlugin is not configured, please check your webpack config");
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
|
-
const { classNameHashSalt, modules, evaluationRules
|
|
89
|
+
const { classNameHashSalt, modules, evaluationRules } = this.getOptions();
|
|
90
90
|
this[GriffelCssLoaderContextKey].runWithTimer(() => {
|
|
91
91
|
EvalCache.clearForFile(this.resourcePath);
|
|
92
|
-
const originalResolveFilename = Module._resolveFilename;
|
|
93
92
|
let result = null;
|
|
94
93
|
let error = null;
|
|
95
94
|
try {
|
|
96
|
-
Module._resolveFilename = (id, params) => {
|
|
97
|
-
const resolvedPath = this[GriffelCssLoaderContextKey].resolveModule(id, params);
|
|
98
|
-
this.addDependency(resolvedPath);
|
|
99
|
-
return resolvedPath;
|
|
100
|
-
};
|
|
101
95
|
result = transformSync(sourceCode, {
|
|
102
96
|
filename: this.resourcePath,
|
|
97
|
+
resolveModule: (id, params) => {
|
|
98
|
+
const resolved = this[GriffelCssLoaderContextKey].resolveModule(id, params);
|
|
99
|
+
this.addDependency(resolved.path);
|
|
100
|
+
return resolved;
|
|
101
|
+
},
|
|
103
102
|
classNameHashSalt,
|
|
104
103
|
modules,
|
|
105
104
|
evaluationRules,
|
|
106
|
-
|
|
105
|
+
collectPerfIssues: this[GriffelCssLoaderContextKey]?.collectPerfIssues
|
|
107
106
|
});
|
|
108
107
|
} catch (err) {
|
|
109
108
|
error = err;
|
|
110
|
-
} finally {
|
|
111
|
-
Module._resolveFilename = originalResolveFilename;
|
|
112
109
|
}
|
|
113
110
|
if (result) {
|
|
114
|
-
const { code, cssRulesByBucket, usedVMForEvaluation } = result;
|
|
111
|
+
const { code, cssRulesByBucket, usedVMForEvaluation, perfIssues } = result;
|
|
115
112
|
const meta = {
|
|
116
113
|
filename: this.resourcePath,
|
|
117
114
|
step: "transform",
|
|
118
|
-
evaluationMode: usedVMForEvaluation ? "vm" : "ast"
|
|
115
|
+
evaluationMode: usedVMForEvaluation ? "vm" : "ast",
|
|
116
|
+
perfIssues
|
|
119
117
|
};
|
|
120
118
|
if (cssRulesByBucket) {
|
|
121
119
|
const resolvedCssRulesByBucket = resolveAssetPathsInCSSRules(cssRulesByBucket, this.resourcePath);
|
package/webpack-plugin.js
CHANGED
|
@@ -7,22 +7,22 @@ function isCJSOnlyPackage(id) {
|
|
|
7
7
|
return id === "tslib" || id.startsWith("@babel/runtime") || id.startsWith("@swc/helpers");
|
|
8
8
|
}
|
|
9
9
|
const RESOLVE_OPTIONS_DEFAULTS = {
|
|
10
|
-
conditionNames: ["
|
|
10
|
+
conditionNames: ["require"],
|
|
11
11
|
extensions: [".js", ".jsx", ".cjs", ".mjs", ".ts", ".tsx", ".json"]
|
|
12
12
|
};
|
|
13
13
|
function createResolverFactory() {
|
|
14
14
|
return function(compilation) {
|
|
15
|
-
const
|
|
15
|
+
const cjsResolver = new ResolverFactory({
|
|
16
16
|
...RESOLVE_OPTIONS_DEFAULTS
|
|
17
17
|
// ...resolveOptionsFromWebpackConfig,
|
|
18
18
|
});
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
const esmResolver = cjsResolver.cloneWithOptions({
|
|
20
|
+
...RESOLVE_OPTIONS_DEFAULTS,
|
|
21
|
+
conditionNames: ["import"],
|
|
22
22
|
mainFields: ["module", "main"]
|
|
23
23
|
});
|
|
24
24
|
return function resolveModule(id, { filename }) {
|
|
25
|
-
const resolver = isCJSOnlyPackage(id) ? cjsResolver :
|
|
25
|
+
const resolver = isCJSOnlyPackage(id) ? cjsResolver : esmResolver;
|
|
26
26
|
const resolved = resolver.sync(path.dirname(filename), id);
|
|
27
27
|
if (resolved.error) {
|
|
28
28
|
throw resolved.error;
|
|
@@ -30,7 +30,10 @@ function createResolverFactory() {
|
|
|
30
30
|
if (!resolved.path) {
|
|
31
31
|
throw new Error(`oxc-resolver: Failed to resolve module "${id}"`);
|
|
32
32
|
}
|
|
33
|
-
return
|
|
33
|
+
return {
|
|
34
|
+
path: resolved.path,
|
|
35
|
+
builtin: !!resolved.builtin
|
|
36
|
+
};
|
|
34
37
|
};
|
|
35
38
|
};
|
|
36
39
|
}
|
|
@@ -152,12 +155,15 @@ function moveCSSModulesToGriffelChunk(compilation) {
|
|
|
152
155
|
class GriffelPlugin {
|
|
153
156
|
#attachToEntryPoint;
|
|
154
157
|
#collectStats;
|
|
158
|
+
#collectPerfIssues;
|
|
155
159
|
#compareMediaQueries;
|
|
156
160
|
#resolverFactory;
|
|
157
161
|
#stats = {};
|
|
162
|
+
#perfIssues = /* @__PURE__ */ new Map();
|
|
158
163
|
constructor(options = {}) {
|
|
159
164
|
this.#attachToEntryPoint = options.unstable_attachToEntryPoint;
|
|
160
165
|
this.#collectStats = options.collectStats ?? false;
|
|
166
|
+
this.#collectPerfIssues = options.collectPerfIssues ?? false;
|
|
161
167
|
this.#compareMediaQueries = options.compareMediaQueries ?? defaultCompareMediaQueries;
|
|
162
168
|
this.#resolverFactory = options.resolverFactory ?? createResolverFactory();
|
|
163
169
|
}
|
|
@@ -196,6 +202,7 @@ class GriffelPlugin {
|
|
|
196
202
|
NormalModule.getCompilationHooks(compilation).loader.tap(PLUGIN_NAME, (loaderContext, module) => {
|
|
197
203
|
const resourcePath = module.resource;
|
|
198
204
|
loaderContext[GriffelCssLoaderContextKey] = {
|
|
205
|
+
collectPerfIssues: this.#collectPerfIssues,
|
|
199
206
|
resolveModule,
|
|
200
207
|
registerExtractedCss(css) {
|
|
201
208
|
cssByModuleMap.set(resourcePath, css);
|
|
@@ -206,17 +213,34 @@ class GriffelPlugin {
|
|
|
206
213
|
return css;
|
|
207
214
|
},
|
|
208
215
|
runWithTimer: (cb) => {
|
|
216
|
+
if (!this.#collectStats && !this.#collectPerfIssues) {
|
|
217
|
+
return cb().result;
|
|
218
|
+
}
|
|
219
|
+
const start = this.#collectStats ? process.hrtime.bigint() : 0n;
|
|
220
|
+
const { meta, result } = cb();
|
|
209
221
|
if (this.#collectStats) {
|
|
210
|
-
const start = process.hrtime.bigint();
|
|
211
|
-
const { meta, result } = cb();
|
|
212
222
|
const end = process.hrtime.bigint();
|
|
213
223
|
this.#stats[meta.filename] = {
|
|
214
224
|
time: end - start,
|
|
215
225
|
evaluationMode: meta.evaluationMode
|
|
216
226
|
};
|
|
217
|
-
return result;
|
|
218
227
|
}
|
|
219
|
-
|
|
228
|
+
if (this.#collectPerfIssues && meta.perfIssues) {
|
|
229
|
+
for (const issue of meta.perfIssues) {
|
|
230
|
+
const key = `${issue.type}:${issue.dependencyFilename}`;
|
|
231
|
+
const existing = this.#perfIssues.get(key);
|
|
232
|
+
if (existing) {
|
|
233
|
+
existing.sourceFilenames.add(meta.filename);
|
|
234
|
+
} else {
|
|
235
|
+
this.#perfIssues.set(key, {
|
|
236
|
+
type: issue.type,
|
|
237
|
+
dependencyFilename: issue.dependencyFilename,
|
|
238
|
+
sourceFilenames: /* @__PURE__ */ new Set([meta.filename])
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
return result;
|
|
220
244
|
}
|
|
221
245
|
};
|
|
222
246
|
});
|
|
@@ -290,15 +314,17 @@ class GriffelPlugin {
|
|
|
290
314
|
return time.toString() + "ns";
|
|
291
315
|
};
|
|
292
316
|
const entries = Object.entries(this.#stats).sort(([, a], [, b]) => Number(b.time - a.time));
|
|
317
|
+
const totalTime = entries.reduce((acc, cur) => acc + cur[1].time, 0n);
|
|
318
|
+
const fileCount = entries.length;
|
|
319
|
+
const avgTime = fileCount > 0 ? totalTime / BigInt(fileCount) : 0n;
|
|
293
320
|
console.log("\nGriffel CSS extraction stats:");
|
|
294
321
|
console.log("------------------------------------");
|
|
295
|
-
console.log(
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
);
|
|
322
|
+
console.log("Total time spent in Griffel loader:", logTime(totalTime));
|
|
323
|
+
console.log("Files processed:", fileCount);
|
|
324
|
+
console.log("Average time per file:", logTime(avgTime));
|
|
299
325
|
console.log(
|
|
300
326
|
"AST evaluation hit: ",
|
|
301
|
-
(entries.filter((s) => s[1].evaluationMode === "ast").length /
|
|
327
|
+
(entries.filter((s) => s[1].evaluationMode === "ast").length / fileCount * 100).toFixed(2) + "%"
|
|
302
328
|
);
|
|
303
329
|
console.log("------------------------------------");
|
|
304
330
|
for (const [filename, info] of entries) {
|
|
@@ -306,6 +332,22 @@ class GriffelPlugin {
|
|
|
306
332
|
}
|
|
307
333
|
console.log();
|
|
308
334
|
}
|
|
335
|
+
if (this.#collectPerfIssues && this.#perfIssues.size > 0) {
|
|
336
|
+
const issues = Array.from(this.#perfIssues.values());
|
|
337
|
+
const cjsCount = issues.filter((i) => i.type === "cjs-module").length;
|
|
338
|
+
const barrelCount = issues.filter((i) => i.type === "barrel-export-star").length;
|
|
339
|
+
console.log("\nGriffel performance issues:");
|
|
340
|
+
console.log("------------------------------------");
|
|
341
|
+
console.log(`CJS modules (no tree-shaking): ${cjsCount}`);
|
|
342
|
+
console.log(`Barrel files with remaining export *: ${barrelCount}`);
|
|
343
|
+
console.log("------------------------------------");
|
|
344
|
+
for (const issue of issues) {
|
|
345
|
+
const tag = issue.type === "cjs-module" ? "cjs" : "barrel";
|
|
346
|
+
const sources = Array.from(issue.sourceFilenames).join(", ");
|
|
347
|
+
console.log(` [${tag}] ${issue.dependencyFilename} (source: ${sources})`);
|
|
348
|
+
}
|
|
349
|
+
console.log();
|
|
350
|
+
}
|
|
309
351
|
}
|
|
310
352
|
);
|
|
311
353
|
});
|
package/webpackLoader.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { TransformOptions } from '@griffel/transform';
|
|
2
2
|
import { SupplementedLoaderContext } from './constants.mjs';
|
|
3
3
|
import type * as webpack from 'webpack';
|
|
4
|
-
export type WebpackLoaderOptions = Omit<TransformOptions, 'filename' | 'generateMetadata'>;
|
|
4
|
+
export type WebpackLoaderOptions = Omit<TransformOptions, 'filename' | 'generateMetadata' | 'resolveModule'>;
|
|
5
5
|
type WebpackLoaderParams = Parameters<webpack.LoaderDefinitionFunction<WebpackLoaderOptions>>;
|
|
6
6
|
declare function webpackLoader(this: SupplementedLoaderContext<WebpackLoaderOptions>, sourceCode: WebpackLoaderParams[0], inputSourceMap: WebpackLoaderParams[1]): void;
|
|
7
7
|
export default webpackLoader;
|
package/resolver/types.d.mts
DELETED