@griffel/transform 3.0.5 → 3.0.6
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/LICENSE.md +21 -0
- package/package.json +6 -5
- package/src/constants.d.mts +2 -0
- package/src/{constants.mts → constants.mjs} +1 -0
- package/src/constants.mjs.map +1 -0
- package/src/evaluation/astEvaluator.d.mts +20 -0
- package/src/evaluation/astEvaluator.mjs +90 -0
- package/src/evaluation/astEvaluator.mjs.map +1 -0
- package/src/evaluation/batchEvaluator.d.mts +13 -0
- package/src/evaluation/batchEvaluator.mjs +54 -0
- package/src/evaluation/batchEvaluator.mjs.map +1 -0
- package/src/evaluation/evalCache.d.mts +9 -0
- package/src/evaluation/evalCache.mjs +65 -0
- package/src/evaluation/evalCache.mjs.map +1 -0
- package/src/evaluation/fluentTokensPlugin.d.mts +2 -0
- package/src/evaluation/fluentTokensPlugin.mjs +70 -0
- package/src/evaluation/fluentTokensPlugin.mjs.map +1 -0
- package/src/evaluation/module.d.mts +44 -0
- package/src/evaluation/module.mjs +207 -0
- package/src/evaluation/module.mjs.map +1 -0
- package/src/evaluation/process.d.mts +24 -0
- package/src/evaluation/{process.mts → process.mjs} +7 -12
- package/src/evaluation/process.mjs.map +1 -0
- package/src/evaluation/types.d.mts +34 -0
- package/src/evaluation/types.mjs +2 -0
- package/src/evaluation/types.mjs.map +1 -0
- package/src/evaluation/vmEvaluator.d.mts +3 -0
- package/src/evaluation/vmEvaluator.mjs +33 -0
- package/src/evaluation/vmEvaluator.mjs.map +1 -0
- package/src/{index.mts → index.d.mts} +0 -4
- package/src/index.mjs +9 -0
- package/src/index.mjs.map +1 -0
- package/src/transformSync.d.mts +41 -0
- package/src/transformSync.mjs +253 -0
- package/src/transformSync.mjs.map +1 -0
- package/src/types.d.mts +12 -0
- package/src/types.mjs +2 -0
- package/src/types.mjs.map +1 -0
- package/src/utils/convertESMtoCJS.d.mts +6 -0
- package/src/utils/convertESMtoCJS.mjs +203 -0
- package/src/utils/convertESMtoCJS.mjs.map +1 -0
- package/src/utils/dedupeCSSRules.d.mts +6 -0
- package/src/utils/dedupeCSSRules.mjs +19 -0
- package/src/utils/dedupeCSSRules.mjs.map +1 -0
- package/CHANGELOG.json +0 -404
- package/CHANGELOG.md +0 -130
- package/__fixtures__/assets/blank.jpg +0 -0
- package/__fixtures__/assets/code.ts +0 -12
- package/__fixtures__/assets/empty.jpg +0 -0
- package/__fixtures__/assets/output.meta.json +0 -12
- package/__fixtures__/assets/output.ts +0 -12
- package/__fixtures__/assets-multiple-declarations/blank.jpg +0 -0
- package/__fixtures__/assets-multiple-declarations/code.ts +0 -8
- package/__fixtures__/assets-multiple-declarations/empty.jpg +0 -0
- package/__fixtures__/assets-multiple-declarations/output.meta.json +0 -9
- package/__fixtures__/assets-multiple-declarations/output.ts +0 -6
- package/__fixtures__/assets-reset-styles/blank.jpg +0 -0
- package/__fixtures__/assets-reset-styles/code.ts +0 -11
- package/__fixtures__/assets-reset-styles/empty.jpg +0 -0
- package/__fixtures__/assets-reset-styles/output.meta.json +0 -11
- package/__fixtures__/assets-reset-styles/output.ts +0 -7
- package/__fixtures__/assets-urls/code.ts +0 -13
- package/__fixtures__/assets-urls/output.meta.json +0 -14
- package/__fixtures__/assets-urls/output.ts +0 -10
- package/__fixtures__/at-rules/code.ts +0 -14
- package/__fixtures__/at-rules/output.meta.json +0 -15
- package/__fixtures__/at-rules/output.ts +0 -10
- package/__fixtures__/config-classname-hash-salt/code.ts +0 -5
- package/__fixtures__/config-classname-hash-salt/output.meta.json +0 -7
- package/__fixtures__/config-classname-hash-salt/output.ts +0 -3
- package/__fixtures__/config-evaluation-rules/code.ts +0 -8
- package/__fixtures__/config-evaluation-rules/consts.ts +0 -1
- package/__fixtures__/config-evaluation-rules/output.meta.json +0 -7
- package/__fixtures__/config-evaluation-rules/output.ts +0 -4
- package/__fixtures__/config-evaluation-rules/sampleEvaluator.cjs +0 -12
- package/__fixtures__/error-argument-count/fixture.js +0 -4
- package/__fixtures__/error-cjs/fixture.js +0 -4
- package/__fixtures__/error-on-undefined/fixture.ts +0 -7
- package/__fixtures__/error-on-undefined/tokens.ts +0 -1
- package/__fixtures__/export-default/code.ts +0 -6
- package/__fixtures__/export-default/output.meta.json +0 -14
- package/__fixtures__/export-default/output.ts +0 -6
- package/__fixtures__/function-mixin/code.ts +0 -6
- package/__fixtures__/function-mixin/mixins.ts +0 -7
- package/__fixtures__/function-mixin/output.meta.json +0 -7
- package/__fixtures__/function-mixin/output.ts +0 -4
- package/__fixtures__/function-mixin/tokens.ts +0 -3
- package/__fixtures__/import-alias/code.ts +0 -5
- package/__fixtures__/import-alias/output.meta.json +0 -7
- package/__fixtures__/import-alias/output.ts +0 -3
- package/__fixtures__/import-custom-module/code.ts +0 -6
- package/__fixtures__/import-custom-module/output.meta.json +0 -7
- package/__fixtures__/import-custom-module/output.ts +0 -4
- package/__fixtures__/keyframes/code.ts +0 -22
- package/__fixtures__/keyframes/output.meta.json +0 -17
- package/__fixtures__/keyframes/output.ts +0 -6
- package/__fixtures__/multiple-declarations/code.ts +0 -8
- package/__fixtures__/multiple-declarations/output.meta.json +0 -7
- package/__fixtures__/multiple-declarations/output.ts +0 -4
- package/__fixtures__/non-existing-module-call/code.ts +0 -10
- package/__fixtures__/non-existing-module-call/module.ts +0 -13
- package/__fixtures__/non-existing-module-call/output.meta.json +0 -7
- package/__fixtures__/non-existing-module-call/output.ts +0 -6
- package/__fixtures__/object/code.ts +0 -6
- package/__fixtures__/object/output.meta.json +0 -14
- package/__fixtures__/object/output.ts +0 -6
- package/__fixtures__/object-computed-keys/code.ts +0 -8
- package/__fixtures__/object-computed-keys/output.meta.json +0 -14
- package/__fixtures__/object-computed-keys/output.ts +0 -8
- package/__fixtures__/object-imported-keys/code.ts +0 -9
- package/__fixtures__/object-imported-keys/consts.ts +0 -2
- package/__fixtures__/object-imported-keys/output.meta.json +0 -7
- package/__fixtures__/object-imported-keys/output.ts +0 -4
- package/__fixtures__/object-mixins/code.ts +0 -11
- package/__fixtures__/object-mixins/mixins.ts +0 -17
- package/__fixtures__/object-mixins/output.meta.json +0 -16
- package/__fixtures__/object-mixins/output.ts +0 -10
- package/__fixtures__/object-mixins/tokens.ts +0 -3
- package/__fixtures__/object-nesting/code.ts +0 -13
- package/__fixtures__/object-nesting/consts.ts +0 -1
- package/__fixtures__/object-nesting/output.meta.json +0 -9
- package/__fixtures__/object-nesting/output.ts +0 -6
- package/__fixtures__/object-reset/code.ts +0 -8
- package/__fixtures__/object-reset/output.meta.json +0 -7
- package/__fixtures__/object-reset/output.ts +0 -5
- package/__fixtures__/object-sequence-expr/code.ts +0 -16
- package/__fixtures__/object-sequence-expr/output.meta.json +0 -7
- package/__fixtures__/object-sequence-expr/output.ts +0 -7
- package/__fixtures__/object-shorthands/code.ts +0 -8
- package/__fixtures__/object-shorthands/output.meta.json +0 -20
- package/__fixtures__/object-shorthands/output.ts +0 -5
- package/__fixtures__/object-variables/code.ts +0 -9
- package/__fixtures__/object-variables/output.meta.json +0 -15
- package/__fixtures__/object-variables/output.ts +0 -9
- package/__fixtures__/object-variables/vars.ts +0 -5
- package/__fixtures__/reset-styles/code.ts +0 -6
- package/__fixtures__/reset-styles/output.meta.json +0 -7
- package/__fixtures__/reset-styles/output.ts +0 -3
- package/__fixtures__/reset-styles-at-rules/code.ts +0 -7
- package/__fixtures__/reset-styles-at-rules/output.meta.json +0 -8
- package/__fixtures__/reset-styles-at-rules/output.ts +0 -3
- package/__fixtures__/rules-with-metadata/code.ts +0 -9
- package/__fixtures__/rules-with-metadata/output.meta.json +0 -14
- package/__fixtures__/rules-with-metadata/output.ts +0 -3
- package/__fixtures__/shared-mixins/code.ts +0 -7
- package/__fixtures__/shared-mixins/mixins.ts +0 -6
- package/__fixtures__/shared-mixins/output.meta.json +0 -7
- package/__fixtures__/shared-mixins/output.ts +0 -8
- package/__fixtures__/static-styles/code.ts +0 -7
- package/__fixtures__/static-styles/output.meta.json +0 -7
- package/__fixtures__/static-styles/output.ts +0 -3
- package/__fixtures__/static-styles-array/code.ts +0 -10
- package/__fixtures__/static-styles-array/output.meta.json +0 -7
- package/__fixtures__/static-styles-array/output.ts +0 -3
- package/__fixtures__/static-styles-string/code.ts +0 -3
- package/__fixtures__/static-styles-string/output.meta.json +0 -7
- package/__fixtures__/static-styles-string/output.ts +0 -3
- package/__fixtures__/tokens/code.ts +0 -11
- package/__fixtures__/tokens/output.meta.json +0 -12
- package/__fixtures__/tokens/output.ts +0 -7
- package/__fixtures__/tokens/tokens.ts +0 -4
- package/__fixtures__/unsupported-css-properties/fixture.ts +0 -16
- package/__fixtures__/unsupported-css-properties/output.meta.json +0 -5
- package/__fixtures__/unsupported-css-properties/output.ts +0 -3
- package/eslint.config.mjs +0 -31
- package/project.json +0 -51
- package/src/evaluation/astEvaluator.mts +0 -109
- package/src/evaluation/astEvaluator.test.mts +0 -126
- package/src/evaluation/batchEvaluator.mts +0 -79
- package/src/evaluation/evalCache.mts +0 -84
- package/src/evaluation/fluentTokensPlugin.mts +0 -82
- package/src/evaluation/fluentTokensPlugin.test.mts +0 -130
- package/src/evaluation/module.mts +0 -271
- package/src/evaluation/module.test.mts +0 -133
- package/src/evaluation/types.mts +0 -49
- package/src/evaluation/vmEvaluator.mts +0 -45
- package/src/evaluation/vmEvaluator.test.mts +0 -30
- package/src/transformSync.mts +0 -425
- package/src/transformSync.test.mts +0 -429
- package/src/types.mts +0 -13
- package/src/utils/convertESMtoCJS.mts +0 -226
- package/src/utils/convertESMtoCJS.test.mts +0 -159
- package/src/utils/dedupeCSSRules.mts +0 -25
- package/src/utils/dedupeCSSRules.test.mts +0 -39
- package/tsconfig.json +0 -19
- package/tsconfig.lib.json +0 -30
- package/tsconfig.spec.json +0 -24
- package/vitest.config.mts +0 -18
|
@@ -1,271 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Custom module system for evaluating code in a sandboxed VM context.
|
|
3
|
-
* Copied from @linaria/babel-preset v3.0.0-beta.19, adapted to use `debug` package
|
|
4
|
-
* and local imports instead of @linaria/* packages.
|
|
5
|
-
*
|
|
6
|
-
* This serves 2 purposes:
|
|
7
|
-
* - Avoid leakage from evaluated code to module cache in current context, e.g. `babel-register`
|
|
8
|
-
* - Allow us to invalidate the module cache without affecting other stuff, necessary for rebuilds
|
|
9
|
-
*
|
|
10
|
-
* We also use it to transpile the code with Babel by default.
|
|
11
|
-
* We also store source maps for it to provide correct error stacktraces.
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
import fs from 'node:fs';
|
|
15
|
-
import NativeModule from 'node:module';
|
|
16
|
-
import path from 'node:path';
|
|
17
|
-
import vm from 'node:vm';
|
|
18
|
-
import createDebug from 'debug';
|
|
19
|
-
|
|
20
|
-
import { ASSET_TAG_OPEN, ASSET_TAG_CLOSE } from '../constants.mjs';
|
|
21
|
-
import { convertESMtoCJS } from '../utils/convertESMtoCJS.mjs';
|
|
22
|
-
import * as EvalCache from './evalCache.mjs';
|
|
23
|
-
import * as mockProcess from './process.mjs';
|
|
24
|
-
import type { EvalRule } from './types.mjs';
|
|
25
|
-
|
|
26
|
-
export type TransformResolver = (
|
|
27
|
-
id: string,
|
|
28
|
-
options: { filename: string; paths: readonly string[] },
|
|
29
|
-
) => { path: string; builtin: boolean };
|
|
30
|
-
|
|
31
|
-
const debug = createDebug('griffel:module');
|
|
32
|
-
|
|
33
|
-
// Separate cache for evaluated modules
|
|
34
|
-
let cache: Record<string, Module> = {};
|
|
35
|
-
|
|
36
|
-
const NOOP = () => { /* noop */ };
|
|
37
|
-
|
|
38
|
-
/** Checks if a value is an Error-like object (works across VM contexts where `instanceof Error` fails). */
|
|
39
|
-
function isError(e: unknown): e is Error {
|
|
40
|
-
return e !== null && e !== undefined && typeof e === 'object' && 'message' in e && 'stack' in e;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const createCustomDebug =
|
|
44
|
-
(depth: number) =>
|
|
45
|
-
(namespaces: string, arg1: unknown, ...args: unknown[]) => {
|
|
46
|
-
const modulePrefix = depth === 0 ? 'module' : `sub-module-${depth}`;
|
|
47
|
-
debug(`${modulePrefix}:${namespaces}`, arg1, ...args);
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
export class Module {
|
|
51
|
-
readonly id: string;
|
|
52
|
-
readonly filename: string;
|
|
53
|
-
declare readonly paths: readonly string[];
|
|
54
|
-
rules: EvalRule[];
|
|
55
|
-
imports: Map<string, string[]> | null = null;
|
|
56
|
-
dependencies: string[] | null = null;
|
|
57
|
-
transform: ((code: string, filename: string) => string) | null = null;
|
|
58
|
-
static readonly extensions = new Set(['.json', '.js', '.jsx', '.ts', '.tsx', '.cjs', '.mjs', '.mts', '.cts']);
|
|
59
|
-
|
|
60
|
-
exports: unknown = {};
|
|
61
|
-
|
|
62
|
-
private readonly resolveFilename: TransformResolver;
|
|
63
|
-
private debug: (namespaces: string, arg1: unknown, ...args: unknown[]) => void;
|
|
64
|
-
private debuggerDepth: number;
|
|
65
|
-
|
|
66
|
-
constructor(filename: string, rules: EvalRule[], resolveFilename: TransformResolver, debuggerDepth = 0) {
|
|
67
|
-
this.id = filename;
|
|
68
|
-
this.filename = filename;
|
|
69
|
-
this.rules = rules;
|
|
70
|
-
this.resolveFilename = resolveFilename;
|
|
71
|
-
this.debuggerDepth = debuggerDepth;
|
|
72
|
-
this.debug = createCustomDebug(debuggerDepth);
|
|
73
|
-
|
|
74
|
-
Object.defineProperties(this, {
|
|
75
|
-
id: {
|
|
76
|
-
value: filename,
|
|
77
|
-
writable: false,
|
|
78
|
-
},
|
|
79
|
-
filename: {
|
|
80
|
-
value: filename,
|
|
81
|
-
writable: false,
|
|
82
|
-
},
|
|
83
|
-
paths: {
|
|
84
|
-
value: Object.freeze(
|
|
85
|
-
(NativeModule as unknown as { _nodeModulePaths: (dir: string) => string[] })._nodeModulePaths(
|
|
86
|
-
path.dirname(filename),
|
|
87
|
-
),
|
|
88
|
-
),
|
|
89
|
-
writable: false,
|
|
90
|
-
},
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
this.exports = {};
|
|
94
|
-
this.debug('prepare', filename);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
require: ((id: string) => unknown) & {
|
|
98
|
-
ensure: () => void;
|
|
99
|
-
cache: Record<string, Module>;
|
|
100
|
-
resolve: (id: string) => string;
|
|
101
|
-
} = Object.assign(
|
|
102
|
-
(id: string): unknown => {
|
|
103
|
-
this.debug('require', id);
|
|
104
|
-
|
|
105
|
-
// Resolve module id (and filename) relatively to parent module
|
|
106
|
-
const resolved = this.resolveFilename(id, this);
|
|
107
|
-
|
|
108
|
-
if (resolved.builtin) {
|
|
109
|
-
throw new Error(`Unable to import "${id}". Importing Node builtins is not supported in the sandbox.`);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
const filename = resolved.path;
|
|
113
|
-
|
|
114
|
-
this.dependencies?.push(id);
|
|
115
|
-
let cacheKey = filename;
|
|
116
|
-
let only: string[] = [];
|
|
117
|
-
|
|
118
|
-
if (this.imports?.has(id)) {
|
|
119
|
-
// We know what exactly we need from this module. Let's shake it!
|
|
120
|
-
only = this.imports.get(id)!.sort();
|
|
121
|
-
|
|
122
|
-
if (only.length === 0) {
|
|
123
|
-
// Probably the module is used as a value itself
|
|
124
|
-
// like `'The answer is ' + require('./module')`
|
|
125
|
-
only = ['default'];
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
cacheKey += `:${only.join(',')}`;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
let m = cache[cacheKey];
|
|
132
|
-
|
|
133
|
-
if (!m) {
|
|
134
|
-
this.debug('cached:not-exist', id);
|
|
135
|
-
|
|
136
|
-
// Create the module if cached module is not available
|
|
137
|
-
m = new Module(filename, this.rules, this.resolveFilename, this.debuggerDepth + 1);
|
|
138
|
-
m.transform = this.transform;
|
|
139
|
-
// Store it in cache at this point, otherwise
|
|
140
|
-
// we would end up in infinite loop with cyclic dependencies
|
|
141
|
-
cache[cacheKey] = m;
|
|
142
|
-
|
|
143
|
-
const ext = path.extname(filename).toLowerCase();
|
|
144
|
-
|
|
145
|
-
if (Module.extensions.has(ext)) {
|
|
146
|
-
// To evaluate the file, we need to read it first
|
|
147
|
-
const code = fs.readFileSync(filename, 'utf-8');
|
|
148
|
-
|
|
149
|
-
if (ext === '.json') {
|
|
150
|
-
// For JSON files, parse it to a JS object similar to Node
|
|
151
|
-
m.exports = JSON.parse(code);
|
|
152
|
-
} else {
|
|
153
|
-
// For JS/TS files, evaluate the module
|
|
154
|
-
// The module will be transpiled using provided transform
|
|
155
|
-
m.evaluate(code, only.includes('*') ? ['*'] : only);
|
|
156
|
-
}
|
|
157
|
-
} else {
|
|
158
|
-
// For non JS/JSON requires, export the resolved absolute path wrapped in asset tags.
|
|
159
|
-
// This allows downstream tools (e.g. webpack plugin) to resolve the path correctly
|
|
160
|
-
// when CSS is extracted to a different location.
|
|
161
|
-
m.exports = ASSET_TAG_OPEN + filename + ASSET_TAG_CLOSE;
|
|
162
|
-
}
|
|
163
|
-
} else {
|
|
164
|
-
this.debug('cached:exist', id);
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
return m.exports;
|
|
168
|
-
},
|
|
169
|
-
{
|
|
170
|
-
ensure: NOOP,
|
|
171
|
-
cache,
|
|
172
|
-
resolve: (id: string) => this.resolveFilename(id, this).path,
|
|
173
|
-
},
|
|
174
|
-
);
|
|
175
|
-
|
|
176
|
-
evaluate(text: string, only: string[] | null = null, useEvalCache = true): void {
|
|
177
|
-
const { filename } = this;
|
|
178
|
-
// Find last matching rule (iterate backwards, break on first match)
|
|
179
|
-
let action: EvalRule['action'] = 'ignore';
|
|
180
|
-
|
|
181
|
-
for (let i = this.rules.length - 1; i >= 0; i--) {
|
|
182
|
-
const { test } = this.rules[i];
|
|
183
|
-
|
|
184
|
-
if (!test || (typeof test === 'function' ? test(filename) : test.test(filename))) {
|
|
185
|
-
action = this.rules[i].action;
|
|
186
|
-
break;
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
const cacheKey = [this.filename, ...(only ?? [])];
|
|
191
|
-
|
|
192
|
-
if (useEvalCache && EvalCache.has(cacheKey, text)) {
|
|
193
|
-
this.exports = EvalCache.get(cacheKey, text);
|
|
194
|
-
return;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
let code: string;
|
|
198
|
-
|
|
199
|
-
if (action === 'ignore') {
|
|
200
|
-
this.debug('ignore', `${filename}`);
|
|
201
|
-
code = text;
|
|
202
|
-
} else {
|
|
203
|
-
// For JavaScript files, we need to transpile it and to get the exports of the module
|
|
204
|
-
this.debug('prepare-evaluation', this.filename, 'using', action.name);
|
|
205
|
-
|
|
206
|
-
const result = action(this.filename, text, only);
|
|
207
|
-
|
|
208
|
-
code = result.code;
|
|
209
|
-
this.imports = result.imports;
|
|
210
|
-
|
|
211
|
-
// Convert ESM syntax to CJS so it can run inside a function wrapper in vm.Script
|
|
212
|
-
if (result.moduleKind === 'esm') {
|
|
213
|
-
code = convertESMtoCJS(code, this.filename);
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
this.debug('evaluate', `${this.filename} (only ${(only || []).join(', ')}):\n${code}`);
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
const script = new vm.Script(`(function (exports) { ${code}\n})(exports);`, {
|
|
220
|
-
filename: this.filename,
|
|
221
|
-
});
|
|
222
|
-
|
|
223
|
-
try {
|
|
224
|
-
script.runInContext(
|
|
225
|
-
vm.createContext({
|
|
226
|
-
clearImmediate: NOOP,
|
|
227
|
-
clearInterval: NOOP,
|
|
228
|
-
clearTimeout: NOOP,
|
|
229
|
-
setImmediate: NOOP,
|
|
230
|
-
setInterval: NOOP,
|
|
231
|
-
setTimeout: NOOP,
|
|
232
|
-
fetch: NOOP,
|
|
233
|
-
global,
|
|
234
|
-
process: mockProcess,
|
|
235
|
-
module: this,
|
|
236
|
-
exports: this.exports,
|
|
237
|
-
require: this.require,
|
|
238
|
-
__filename: this.filename,
|
|
239
|
-
__dirname: path.dirname(this.filename),
|
|
240
|
-
}),
|
|
241
|
-
);
|
|
242
|
-
} catch (vmError: unknown) {
|
|
243
|
-
// Errors thrown inside vm.runInContext() use the VM context's Error constructor,
|
|
244
|
-
// so they fail `instanceof Error` in the host context (e.g. webpack wraps them as NonErrorEmittedError).
|
|
245
|
-
// Re-create as a host Error with filename context.
|
|
246
|
-
const message = isError(vmError) ? vmError.message : String(vmError);
|
|
247
|
-
const hostError = new Error(message);
|
|
248
|
-
|
|
249
|
-
if (isError(vmError)) {
|
|
250
|
-
hostError.stack = vmError.stack;
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
throw hostError;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
if (useEvalCache) {
|
|
257
|
-
EvalCache.set(cacheKey, text, this.exports);
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
static invalidate = (): void => {
|
|
262
|
-
cache = {};
|
|
263
|
-
};
|
|
264
|
-
|
|
265
|
-
static invalidateEvalCache = (): void => {
|
|
266
|
-
EvalCache.clear();
|
|
267
|
-
};
|
|
268
|
-
|
|
269
|
-
static _nodeModulePaths = (filename: string): string[] =>
|
|
270
|
-
(NativeModule as unknown as { _nodeModulePaths: (dir: string) => string[] })._nodeModulePaths(filename);
|
|
271
|
-
}
|
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
import * as fs from 'node:fs';
|
|
2
|
-
import NativeModule from 'node:module';
|
|
3
|
-
import * as os from 'node:os';
|
|
4
|
-
import * as path from 'node:path';
|
|
5
|
-
import { afterEach, describe, expect, it } from 'vitest';
|
|
6
|
-
|
|
7
|
-
import { ASSET_TAG_OPEN, ASSET_TAG_CLOSE } from '../constants.mjs';
|
|
8
|
-
import { Module } from './module.mjs';
|
|
9
|
-
import type { TransformResolver } from './module.mjs';
|
|
10
|
-
|
|
11
|
-
const defaultRules = [{ action: 'ignore' as const }];
|
|
12
|
-
const defaultResolve: TransformResolver = (id, opts) => ({
|
|
13
|
-
path: (NativeModule as unknown as { _resolveFilename: (id: string, options: unknown) => string })._resolveFilename(
|
|
14
|
-
id,
|
|
15
|
-
opts,
|
|
16
|
-
),
|
|
17
|
-
builtin: false,
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
describe('Module', () => {
|
|
21
|
-
let tmpDir: string;
|
|
22
|
-
|
|
23
|
-
afterEach(() => {
|
|
24
|
-
Module.invalidate();
|
|
25
|
-
|
|
26
|
-
if (tmpDir) {
|
|
27
|
-
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
28
|
-
}
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
describe('evaluate', () => {
|
|
32
|
-
it('wraps VM errors as host Error with filename context', () => {
|
|
33
|
-
tmpDir = fs.realpathSync(fs.mkdtempSync(path.join(os.tmpdir(), 'griffel-module-test-')));
|
|
34
|
-
|
|
35
|
-
const childFile = path.join(tmpDir, 'child.js');
|
|
36
|
-
fs.writeFileSync(childFile, 'const x = undefined;\nx.foo;');
|
|
37
|
-
|
|
38
|
-
const entryFile = path.join(tmpDir, 'entry.js');
|
|
39
|
-
fs.writeFileSync(entryFile, '');
|
|
40
|
-
|
|
41
|
-
const m = new Module(entryFile, defaultRules, defaultResolve);
|
|
42
|
-
|
|
43
|
-
try {
|
|
44
|
-
m.evaluate(`const child = require("./child.js");`, ['child']);
|
|
45
|
-
expect.unreachable('should have thrown');
|
|
46
|
-
} catch (e) {
|
|
47
|
-
// Must be a proper host Error instance (not a VM context Error that webpack wraps as NonErrorEmittedError)
|
|
48
|
-
expect(e).toBeInstanceOf(Error);
|
|
49
|
-
|
|
50
|
-
const err = e as Error;
|
|
51
|
-
// Replace machine-specific paths and line numbers so snapshots are stable across environments
|
|
52
|
-
const repoRoot = path.resolve(__dirname, '../../../..');
|
|
53
|
-
const normalize = (s: string) =>
|
|
54
|
-
s
|
|
55
|
-
.split(tmpDir).join('<tmpDir>')
|
|
56
|
-
.split(repoRoot).join('<repo>')
|
|
57
|
-
.replace(/:\d+(:\d+)?/g, ':<line>');
|
|
58
|
-
|
|
59
|
-
expect(normalize(err.message)).toMatchInlineSnapshot(
|
|
60
|
-
`"Cannot read properties of undefined (reading 'foo')"`,
|
|
61
|
-
);
|
|
62
|
-
expect(normalize(err.stack!)).toMatchInlineSnapshot(`
|
|
63
|
-
"<repo>/packages/transform/src/evaluation/module.mts:<line>
|
|
64
|
-
throw hostError;
|
|
65
|
-
^
|
|
66
|
-
|
|
67
|
-
<tmpDir>/child.js:<line>
|
|
68
|
-
x.foo;
|
|
69
|
-
^
|
|
70
|
-
|
|
71
|
-
TypeError: Cannot read properties of undefined (reading 'foo')
|
|
72
|
-
at <tmpDir>/child.js:<line>
|
|
73
|
-
at <tmpDir>/child.js:<line>
|
|
74
|
-
at Script.runInContext (node:vm:<line>)
|
|
75
|
-
at Module.evaluate (<repo>/packages/transform/src/evaluation/module.mts:<line>)
|
|
76
|
-
at require.Object.assign.ensure (<repo>/packages/transform/src/evaluation/module.mts:<line>)
|
|
77
|
-
at <tmpDir>/entry.js:<line>
|
|
78
|
-
at <tmpDir>/entry.js:<line>
|
|
79
|
-
at Script.runInContext (node:vm:<line>)
|
|
80
|
-
at Module.evaluate (<repo>/packages/transform/src/evaluation/module.mts:<line>)
|
|
81
|
-
at <repo>/packages/transform/src/evaluation/module.test.mts:<line>"
|
|
82
|
-
`);
|
|
83
|
-
}
|
|
84
|
-
});
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
describe('require (asset handling)', () => {
|
|
88
|
-
it('wraps non-JS/JSON requires with asset tags containing absolute path', () => {
|
|
89
|
-
tmpDir = fs.realpathSync(fs.mkdtempSync(path.join(os.tmpdir(), 'griffel-module-test-')));
|
|
90
|
-
|
|
91
|
-
const jpgFile = path.join(tmpDir, 'test.jpg');
|
|
92
|
-
fs.writeFileSync(jpgFile, '');
|
|
93
|
-
|
|
94
|
-
const entryFile = path.join(tmpDir, 'entry.js');
|
|
95
|
-
fs.writeFileSync(entryFile, '');
|
|
96
|
-
|
|
97
|
-
const m = new Module(entryFile, defaultRules, defaultResolve);
|
|
98
|
-
const result = m.require('./test.jpg');
|
|
99
|
-
|
|
100
|
-
expect(result).toBe(ASSET_TAG_OPEN + jpgFile + ASSET_TAG_CLOSE);
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
it('wraps .png requires with asset tags', () => {
|
|
104
|
-
tmpDir = fs.realpathSync(fs.mkdtempSync(path.join(os.tmpdir(), 'griffel-module-test-')));
|
|
105
|
-
|
|
106
|
-
const pngFile = path.join(tmpDir, 'icon.png');
|
|
107
|
-
fs.writeFileSync(pngFile, '');
|
|
108
|
-
|
|
109
|
-
const entryFile = path.join(tmpDir, 'entry.js');
|
|
110
|
-
fs.writeFileSync(entryFile, '');
|
|
111
|
-
|
|
112
|
-
const m = new Module(entryFile, defaultRules, defaultResolve);
|
|
113
|
-
const result = m.require('./icon.png');
|
|
114
|
-
|
|
115
|
-
expect(result).toBe(ASSET_TAG_OPEN + pngFile + ASSET_TAG_CLOSE);
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
it('does not wrap .json requires with asset tags', () => {
|
|
119
|
-
tmpDir = fs.realpathSync(fs.mkdtempSync(path.join(os.tmpdir(), 'griffel-module-test-')));
|
|
120
|
-
|
|
121
|
-
const jsonFile = path.join(tmpDir, 'data.json');
|
|
122
|
-
fs.writeFileSync(jsonFile, '{"key": "value"}');
|
|
123
|
-
|
|
124
|
-
const entryFile = path.join(tmpDir, 'entry.js');
|
|
125
|
-
fs.writeFileSync(entryFile, '');
|
|
126
|
-
|
|
127
|
-
const m = new Module(entryFile, defaultRules, defaultResolve);
|
|
128
|
-
const result = m.require('./data.json');
|
|
129
|
-
|
|
130
|
-
expect(result).toEqual({ key: 'value' });
|
|
131
|
-
});
|
|
132
|
-
});
|
|
133
|
-
});
|
package/src/evaluation/types.mts
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import type { Node, Program } from 'oxc-parser';
|
|
2
|
-
|
|
3
|
-
// Types from @linaria/babel-preset, internalized to remove the dependency
|
|
4
|
-
|
|
5
|
-
export type EvaluatorResult = {
|
|
6
|
-
code: string;
|
|
7
|
-
imports: Map<string, string[]> | null;
|
|
8
|
-
moduleKind: 'esm' | 'cjs';
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
export type EvalRule = {
|
|
12
|
-
test?: RegExp | ((path: string) => boolean);
|
|
13
|
-
action: Evaluator | 'ignore';
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export type Evaluator = (
|
|
17
|
-
filename: string,
|
|
18
|
-
text: string,
|
|
19
|
-
only: string[] | null,
|
|
20
|
-
) => EvaluatorResult;
|
|
21
|
-
|
|
22
|
-
// Griffel-specific types
|
|
23
|
-
|
|
24
|
-
export interface TransformPerfIssue {
|
|
25
|
-
type: 'cjs-module' | 'barrel-export-star';
|
|
26
|
-
/** The dependency file that caused the issue */
|
|
27
|
-
dependencyFilename: string;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export interface EvaluationResult {
|
|
31
|
-
confident: boolean;
|
|
32
|
-
value?: unknown;
|
|
33
|
-
error?: Error;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export interface AstEvaluatorContext {
|
|
37
|
-
/** Full program AST */
|
|
38
|
-
programAst: Program;
|
|
39
|
-
/** Recursive evaluator callback (goes through base + all plugins) */
|
|
40
|
-
evaluateNode: (node: Node) => unknown;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export interface AstEvaluatorPlugin {
|
|
44
|
-
name: string;
|
|
45
|
-
/**
|
|
46
|
-
* Evaluate an AST node. Return DEOPT symbol to signal "can't handle this".
|
|
47
|
-
*/
|
|
48
|
-
evaluateNode: (node: Node, context: AstEvaluatorContext) => unknown;
|
|
49
|
-
}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { Module } from './module.mjs';
|
|
2
|
-
import type { TransformResolver } from './module.mjs';
|
|
3
|
-
import type { EvalRule, EvaluationResult } from './types.mjs';
|
|
4
|
-
|
|
5
|
-
function isError(e: unknown): e is Error {
|
|
6
|
-
return Object.prototype.toString.call(e) === '[object Error]';
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export function vmEvaluator(
|
|
10
|
-
sourceCode: string,
|
|
11
|
-
filename: string,
|
|
12
|
-
expressionCode: string,
|
|
13
|
-
evaluationRules: EvalRule[],
|
|
14
|
-
resolveFilename: TransformResolver,
|
|
15
|
-
): EvaluationResult {
|
|
16
|
-
// Create a simple wrapper program for evaluation
|
|
17
|
-
const codeForEvaluation = `
|
|
18
|
-
${sourceCode}
|
|
19
|
-
|
|
20
|
-
export const __mkPreval = (() => {
|
|
21
|
-
try {
|
|
22
|
-
return ([${expressionCode}]);
|
|
23
|
-
} catch (e) {
|
|
24
|
-
return e;
|
|
25
|
-
}
|
|
26
|
-
})();
|
|
27
|
-
`;
|
|
28
|
-
|
|
29
|
-
try {
|
|
30
|
-
const mod = new Module(filename, evaluationRules, resolveFilename);
|
|
31
|
-
// useEvalCache=false: each source file produces unique codeForEvaluation (different sourceCode +
|
|
32
|
-
// expressionCode), so the eval cache would never hit — skip the unnecessary hashing and map storage.
|
|
33
|
-
mod.evaluate(codeForEvaluation, ['__mkPreval'], /* useEvalCache */ false);
|
|
34
|
-
|
|
35
|
-
const result = (mod.exports as { __mkPreval: unknown }).__mkPreval;
|
|
36
|
-
|
|
37
|
-
if (isError(result)) {
|
|
38
|
-
return { confident: false, error: result };
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
return { confident: true, value: result };
|
|
42
|
-
} catch (err) {
|
|
43
|
-
return { confident: false, error: err as Error };
|
|
44
|
-
}
|
|
45
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import NativeModule from 'node:module';
|
|
2
|
-
import { describe, expect, it } from 'vitest';
|
|
3
|
-
import shakerEvaluator from '@griffel/transform-shaker';
|
|
4
|
-
import { vmEvaluator } from './vmEvaluator.mjs';
|
|
5
|
-
import type { TransformResolver } from './module.mjs';
|
|
6
|
-
|
|
7
|
-
const evaluationRules = [
|
|
8
|
-
{
|
|
9
|
-
test: /[/\\]node_modules[/\\]/,
|
|
10
|
-
action: 'ignore' as const,
|
|
11
|
-
},
|
|
12
|
-
{
|
|
13
|
-
action: shakerEvaluator,
|
|
14
|
-
},
|
|
15
|
-
];
|
|
16
|
-
|
|
17
|
-
const defaultResolve: TransformResolver = (id, opts) => ({
|
|
18
|
-
path: (NativeModule as unknown as { _resolveFilename: (id: string, options: unknown) => string })._resolveFilename(id, opts),
|
|
19
|
-
builtin: false,
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
describe('evaluateStyleExpression', () => {
|
|
23
|
-
it('evaluates expressions with source code context', () => {
|
|
24
|
-
const sourceCode = 'const color = "blue"; const size = 16;';
|
|
25
|
-
const result = vmEvaluator(sourceCode, '/test.ts', '{ color, fontSize: size }', evaluationRules, defaultResolve);
|
|
26
|
-
|
|
27
|
-
expect(result.confident).toBe(true);
|
|
28
|
-
expect(result.value).toEqual([{ color: 'blue', fontSize: 16 }]);
|
|
29
|
-
});
|
|
30
|
-
});
|