next-yak 9.0.0 → 9.1.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/dist/loaders/vite-plugin.d.ts +15 -0
- package/dist/loaders/vite-plugin.js +1068 -0
- package/dist/loaders/vite-plugin.js.map +1 -0
- package/dist/withYak/index.cjs +14 -4
- package/dist/withYak/index.cjs.map +1 -1
- package/dist/withYak/index.d.cts +10 -1
- package/dist/withYak/index.d.ts +10 -1
- package/dist/withYak/index.js +13 -4
- package/dist/withYak/index.js.map +1 -1
- package/loaders/vite-plugin.ts +405 -0
- package/package.json +5 -4
- package/withYak/index.ts +34 -6
|
@@ -0,0 +1,1068 @@
|
|
|
1
|
+
// loaders/vite-plugin.ts
|
|
2
|
+
import { transform as swcTransform } from "@swc/core";
|
|
3
|
+
import { readFileSync } from "fs";
|
|
4
|
+
import { createRequire } from "module";
|
|
5
|
+
import { dirname as dirname2, relative, resolve } from "path";
|
|
6
|
+
import { createContext, runInContext } from "vm";
|
|
7
|
+
|
|
8
|
+
// cross-file-resolver/parseModule.ts
|
|
9
|
+
async function parseModule(context, modulePath) {
|
|
10
|
+
try {
|
|
11
|
+
const isYak = modulePath.endsWith(".yak.ts") || modulePath.endsWith(".yak.tsx") || modulePath.endsWith(".yak.js") || modulePath.endsWith(".yak.jsx");
|
|
12
|
+
if (isYak && context.evaluateYakModule) {
|
|
13
|
+
const yakModule = await context.evaluateYakModule(modulePath);
|
|
14
|
+
const yakExports = objectToModuleExport(yakModule);
|
|
15
|
+
return {
|
|
16
|
+
type: "yak",
|
|
17
|
+
exports: { importYak: false, named: yakExports, all: [] },
|
|
18
|
+
path: modulePath
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
if (context.cache?.parse === void 0) {
|
|
22
|
+
return uncachedParseModule(context, modulePath);
|
|
23
|
+
}
|
|
24
|
+
const cached = context.cache.parse.get(modulePath);
|
|
25
|
+
if (cached === void 0) {
|
|
26
|
+
const parsedModule = await uncachedParseModule(context, modulePath);
|
|
27
|
+
context.cache.parse.set(modulePath, parsedModule);
|
|
28
|
+
if (context.cache.parse.addDependency) {
|
|
29
|
+
context.cache.parse.addDependency(modulePath, modulePath);
|
|
30
|
+
}
|
|
31
|
+
return parsedModule;
|
|
32
|
+
}
|
|
33
|
+
return cached;
|
|
34
|
+
} catch (error) {
|
|
35
|
+
throw new Error(
|
|
36
|
+
`Error parsing file ${modulePath}: ${error.message}`
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
async function uncachedParseModule(context, modulePath) {
|
|
41
|
+
const exports = await context.extractExports(modulePath);
|
|
42
|
+
if (!exports.importYak) {
|
|
43
|
+
return {
|
|
44
|
+
type: "regular",
|
|
45
|
+
path: modulePath,
|
|
46
|
+
exports
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
const transformed = await context.getTransformed(modulePath);
|
|
50
|
+
const mixins = parseMixins(transformed.code);
|
|
51
|
+
const styledComponents = parseStyledComponents(
|
|
52
|
+
transformed.code,
|
|
53
|
+
context.transpilationMode
|
|
54
|
+
);
|
|
55
|
+
return {
|
|
56
|
+
type: "regular",
|
|
57
|
+
path: modulePath,
|
|
58
|
+
js: transformed,
|
|
59
|
+
exports,
|
|
60
|
+
styledComponents,
|
|
61
|
+
mixins
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
function parseMixins(sourceContents) {
|
|
65
|
+
const mixinParts = sourceContents.split("/*YAK EXPORTED MIXIN:");
|
|
66
|
+
let mixins = {};
|
|
67
|
+
for (let i = 1; i < mixinParts.length; i++) {
|
|
68
|
+
const [comment] = mixinParts[i].split("*/", 1);
|
|
69
|
+
const position = comment.indexOf("\n");
|
|
70
|
+
const name = comment.slice(0, position);
|
|
71
|
+
const value = comment.slice(position + 1);
|
|
72
|
+
mixins[name] = {
|
|
73
|
+
type: "mixin",
|
|
74
|
+
value,
|
|
75
|
+
nameParts: name.split(":").map((part) => decodeURIComponent(part))
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
return mixins;
|
|
79
|
+
}
|
|
80
|
+
function parseStyledComponents(sourceContents, transpilationMode) {
|
|
81
|
+
const styledParts = sourceContents.split("/*YAK EXPORTED STYLED:");
|
|
82
|
+
let styledComponents = {};
|
|
83
|
+
for (let i = 1; i < styledParts.length; i++) {
|
|
84
|
+
const [comment] = styledParts[i].split("*/", 1);
|
|
85
|
+
const [componentName, className] = comment.split(":");
|
|
86
|
+
styledComponents[componentName] = {
|
|
87
|
+
type: "styled-component",
|
|
88
|
+
nameParts: componentName.split("."),
|
|
89
|
+
value: transpilationMode === "Css" ? `.${className}` : `:global(.${className})`
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
return styledComponents;
|
|
93
|
+
}
|
|
94
|
+
function objectToModuleExport(object) {
|
|
95
|
+
return Object.fromEntries(
|
|
96
|
+
Object.entries(object).map(([key, value]) => {
|
|
97
|
+
if (typeof value === "string" || typeof value === "number") {
|
|
98
|
+
return [key, { type: "constant", value }];
|
|
99
|
+
} else if (value && (typeof value === "object" || Array.isArray(value))) {
|
|
100
|
+
return [
|
|
101
|
+
key,
|
|
102
|
+
{ type: "record", value: objectToModuleExport(value) }
|
|
103
|
+
];
|
|
104
|
+
} else {
|
|
105
|
+
return [key, { type: "unsupported", hint: String(value) }];
|
|
106
|
+
}
|
|
107
|
+
})
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// cross-file-resolver/Errors.ts
|
|
112
|
+
var CauseError = class _CauseError extends Error {
|
|
113
|
+
constructor(message, options) {
|
|
114
|
+
super(
|
|
115
|
+
`${message}${options?.cause ? `
|
|
116
|
+
Caused by: ${typeof options.cause === "object" && options.cause !== null && "message" in options.cause ? options.cause.message : String(options.cause)}` : ""}`
|
|
117
|
+
);
|
|
118
|
+
if (options?.cause instanceof _CauseError && options.cause.circular) {
|
|
119
|
+
this.circular = true;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
var ResolveError = class extends CauseError {
|
|
124
|
+
};
|
|
125
|
+
var CircularDependencyError = class extends CauseError {
|
|
126
|
+
constructor(message, options) {
|
|
127
|
+
super(message, options);
|
|
128
|
+
this.circular = true;
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
// cross-file-resolver/resolveCrossFileConstant.ts
|
|
133
|
+
var yakCssImportRegex = (
|
|
134
|
+
// Make mixin and selector non optional once we dropped support for the babel plugin
|
|
135
|
+
/--yak-css-import\:\s*url\("([^"]+)",?(|mixin|selector)\)(;?)/g
|
|
136
|
+
);
|
|
137
|
+
async function resolveCrossFileConstant(context, filePath, css) {
|
|
138
|
+
const resolveCrossFileConstant2 = context.cache?.resolveCrossFileConstant;
|
|
139
|
+
if (resolveCrossFileConstant2 === void 0) {
|
|
140
|
+
return uncachedResolveCrossFileConstant(context, filePath, css);
|
|
141
|
+
}
|
|
142
|
+
const cacheKey = await sha1(filePath + ":" + css);
|
|
143
|
+
const cached = resolveCrossFileConstant2.get(cacheKey);
|
|
144
|
+
if (cached === void 0) {
|
|
145
|
+
const resolvedCrossFilConstantPromise = uncachedResolveCrossFileConstant(
|
|
146
|
+
context,
|
|
147
|
+
filePath,
|
|
148
|
+
css
|
|
149
|
+
);
|
|
150
|
+
resolveCrossFileConstant2.set(cacheKey, resolvedCrossFilConstantPromise);
|
|
151
|
+
if (resolveCrossFileConstant2.addDependency) {
|
|
152
|
+
resolveCrossFileConstant2.addDependency(cacheKey, filePath);
|
|
153
|
+
resolvedCrossFilConstantPromise.then((value) => {
|
|
154
|
+
for (const dep of value.dependencies) {
|
|
155
|
+
resolveCrossFileConstant2.addDependency(cacheKey, dep);
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
return resolvedCrossFilConstantPromise;
|
|
160
|
+
}
|
|
161
|
+
return cached;
|
|
162
|
+
}
|
|
163
|
+
async function uncachedResolveCrossFileConstant(context, filePath, css) {
|
|
164
|
+
const yakImports = await parseYakCssImport(context, filePath, css);
|
|
165
|
+
if (yakImports.length === 0) {
|
|
166
|
+
return { resolved: css, dependencies: [] };
|
|
167
|
+
}
|
|
168
|
+
try {
|
|
169
|
+
const dependencies = /* @__PURE__ */ new Set();
|
|
170
|
+
const resolvedValues = await Promise.all(
|
|
171
|
+
yakImports.map(async ({ moduleSpecifier, specifier }) => {
|
|
172
|
+
const { resolved: resolvedModule } = await resolveModule(
|
|
173
|
+
context,
|
|
174
|
+
moduleSpecifier
|
|
175
|
+
);
|
|
176
|
+
const resolvedValue = await resolveModuleSpecifierRecursively(
|
|
177
|
+
context,
|
|
178
|
+
resolvedModule,
|
|
179
|
+
specifier
|
|
180
|
+
);
|
|
181
|
+
for (const dependency of resolvedValue.from) {
|
|
182
|
+
dependencies.add(dependency);
|
|
183
|
+
}
|
|
184
|
+
return resolvedValue;
|
|
185
|
+
})
|
|
186
|
+
);
|
|
187
|
+
let result = css;
|
|
188
|
+
for (let i = yakImports.length - 1; i >= 0; i--) {
|
|
189
|
+
const { position, size, importKind, specifier, semicolon } = yakImports[i];
|
|
190
|
+
const resolved = resolvedValues[i];
|
|
191
|
+
let replacement;
|
|
192
|
+
if (resolved.type === "unresolved-tag") {
|
|
193
|
+
replacement = importKind === "mixin" ? "" : "undefined";
|
|
194
|
+
} else {
|
|
195
|
+
if (importKind === "selector") {
|
|
196
|
+
if (resolved.type !== "styled-component" && resolved.type !== "constant") {
|
|
197
|
+
throw new Error(
|
|
198
|
+
`Found "${resolved.type}" but expected a selector - did you forget a semicolon after "${specifier.join(
|
|
199
|
+
"."
|
|
200
|
+
)}"?`
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
replacement = resolved.type === "styled-component" ? resolved.value : resolved.value + // resolved.value can be of two different types:
|
|
205
|
+
// - mixin:
|
|
206
|
+
// ${mixinName};
|
|
207
|
+
// - constant:
|
|
208
|
+
// color: ${value};
|
|
209
|
+
// For mixins the semicolon is already included in the value
|
|
210
|
+
// but for constants it has to be added manually
|
|
211
|
+
(["}", ";"].includes(String(resolved.value).trimEnd().slice(-1)) ? "" : semicolon);
|
|
212
|
+
}
|
|
213
|
+
result = result.slice(0, position) + String(replacement) + result.slice(position + size);
|
|
214
|
+
}
|
|
215
|
+
return { resolved: result, dependencies: Array.from(dependencies) };
|
|
216
|
+
} catch (error) {
|
|
217
|
+
throw new CauseError(
|
|
218
|
+
`Error while resolving cross-file selectors in file "${filePath}"`,
|
|
219
|
+
{ cause: error }
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
async function parseYakCssImport(context, filePath, css) {
|
|
224
|
+
const yakImports = [];
|
|
225
|
+
for (const match of css.matchAll(yakCssImportRegex)) {
|
|
226
|
+
const [fullMatch, encodedArguments, importKind, semicolon] = match;
|
|
227
|
+
const [moduleSpecifier, ...specifier] = encodedArguments.split(":").map((entry) => decodeURIComponent(entry));
|
|
228
|
+
yakImports.push({
|
|
229
|
+
encodedArguments,
|
|
230
|
+
moduleSpecifier: await context.resolve(moduleSpecifier, filePath),
|
|
231
|
+
specifier,
|
|
232
|
+
importKind,
|
|
233
|
+
semicolon,
|
|
234
|
+
position: match.index,
|
|
235
|
+
size: fullMatch.length
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
return yakImports;
|
|
239
|
+
}
|
|
240
|
+
async function resolveModule(context, filePath) {
|
|
241
|
+
if (context.cache?.resolve === void 0) {
|
|
242
|
+
return uncachedResolveModule(context, filePath);
|
|
243
|
+
}
|
|
244
|
+
const cached = context.cache.resolve.get(filePath);
|
|
245
|
+
if (cached === void 0) {
|
|
246
|
+
const resolvedPromise = uncachedResolveModule(context, filePath);
|
|
247
|
+
context.cache.resolve.set(filePath, resolvedPromise);
|
|
248
|
+
if (context.cache.resolve.addDependency) {
|
|
249
|
+
context.cache.resolve.addDependency(filePath, filePath);
|
|
250
|
+
resolvedPromise.then((value) => {
|
|
251
|
+
for (const dep of value.dependencies) {
|
|
252
|
+
context.cache.resolve.addDependency(filePath, dep);
|
|
253
|
+
}
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
return resolvedPromise;
|
|
257
|
+
}
|
|
258
|
+
return cached;
|
|
259
|
+
}
|
|
260
|
+
async function uncachedResolveModule(context, filePath) {
|
|
261
|
+
const parsedModule = await context.parse(filePath);
|
|
262
|
+
const exports = parsedModule.exports;
|
|
263
|
+
if (parsedModule.type !== "regular") {
|
|
264
|
+
return {
|
|
265
|
+
resolved: {
|
|
266
|
+
path: parsedModule.path,
|
|
267
|
+
exports
|
|
268
|
+
},
|
|
269
|
+
dependencies: []
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
const dependencies = /* @__PURE__ */ new Set();
|
|
273
|
+
if (parsedModule.styledComponents) {
|
|
274
|
+
Object.values(parsedModule.styledComponents).map((styledComponent) => {
|
|
275
|
+
if (styledComponent.nameParts.length === 1) {
|
|
276
|
+
exports.named[styledComponent.nameParts[0]] = {
|
|
277
|
+
type: "styled-component",
|
|
278
|
+
className: styledComponent.value
|
|
279
|
+
};
|
|
280
|
+
} else {
|
|
281
|
+
let exportEntry = exports.named[styledComponent.nameParts[0]];
|
|
282
|
+
if (!exportEntry) {
|
|
283
|
+
exportEntry = { type: "record", value: {} };
|
|
284
|
+
exports.named[styledComponent.nameParts[0]] = exportEntry;
|
|
285
|
+
} else if (exportEntry.type !== "record") {
|
|
286
|
+
throw new CauseError(`Error parsing file "${parsedModule.path}"`, {
|
|
287
|
+
cause: `"${styledComponent.nameParts[0]}" is not a record`
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
let current = exportEntry.value;
|
|
291
|
+
for (let i = 1; i < styledComponent.nameParts.length - 1; i++) {
|
|
292
|
+
let next = current[styledComponent.nameParts[i]];
|
|
293
|
+
if (!next) {
|
|
294
|
+
next = { type: "record", value: {} };
|
|
295
|
+
current[styledComponent.nameParts[i]] = next;
|
|
296
|
+
} else if (next.type !== "record") {
|
|
297
|
+
throw new CauseError(`Error parsing file "${parsedModule.path}"`, {
|
|
298
|
+
cause: `"${styledComponent.nameParts.slice(0, i + 1).join(".")}" is not a record`
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
current = next.value;
|
|
302
|
+
}
|
|
303
|
+
current[styledComponent.nameParts[styledComponent.nameParts.length - 1]] = {
|
|
304
|
+
type: "styled-component",
|
|
305
|
+
className: styledComponent.value
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
if (parsedModule.mixins) {
|
|
311
|
+
await Promise.all(
|
|
312
|
+
Object.values(parsedModule.mixins).map(async (mixin) => {
|
|
313
|
+
const { resolved, dependencies: deps } = await resolveCrossFileConstant(
|
|
314
|
+
context,
|
|
315
|
+
parsedModule.path,
|
|
316
|
+
mixin.value
|
|
317
|
+
);
|
|
318
|
+
for (const dep of deps) {
|
|
319
|
+
dependencies.add(dep);
|
|
320
|
+
}
|
|
321
|
+
if (mixin.nameParts.length === 1) {
|
|
322
|
+
exports.named[mixin.nameParts[0]] = {
|
|
323
|
+
type: "mixin",
|
|
324
|
+
value: resolved
|
|
325
|
+
};
|
|
326
|
+
} else {
|
|
327
|
+
let exportEntry = exports.named[mixin.nameParts[0]];
|
|
328
|
+
if (!exportEntry) {
|
|
329
|
+
exportEntry = { type: "record", value: {} };
|
|
330
|
+
exports.named[mixin.nameParts[0]] = exportEntry;
|
|
331
|
+
} else if (exportEntry.type !== "record") {
|
|
332
|
+
throw new CauseError(`Error parsing file "${parsedModule.path}"`, {
|
|
333
|
+
cause: `"${mixin.nameParts[0]}" is not a record`
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
let current = exportEntry.value;
|
|
337
|
+
for (let i = 1; i < mixin.nameParts.length - 1; i++) {
|
|
338
|
+
let next = current[mixin.nameParts[i]];
|
|
339
|
+
if (!next) {
|
|
340
|
+
next = { type: "record", value: {} };
|
|
341
|
+
current[mixin.nameParts[i]] = next;
|
|
342
|
+
} else if (next.type !== "record") {
|
|
343
|
+
throw new CauseError(
|
|
344
|
+
`Error parsing file "${parsedModule.path}"`,
|
|
345
|
+
{
|
|
346
|
+
cause: `"${mixin.nameParts.slice(0, i + 1).join(".")}" is not a record`
|
|
347
|
+
}
|
|
348
|
+
);
|
|
349
|
+
}
|
|
350
|
+
current = next.value;
|
|
351
|
+
}
|
|
352
|
+
current[mixin.nameParts[mixin.nameParts.length - 1]] = {
|
|
353
|
+
type: "mixin",
|
|
354
|
+
value: resolved
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
})
|
|
358
|
+
);
|
|
359
|
+
}
|
|
360
|
+
return {
|
|
361
|
+
resolved: {
|
|
362
|
+
path: parsedModule.path,
|
|
363
|
+
exports
|
|
364
|
+
},
|
|
365
|
+
dependencies: Array.from(dependencies)
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
async function resolveModuleSpecifierRecursively(context, resolvedModule, specifiers, seen = /* @__PURE__ */ new Set()) {
|
|
369
|
+
const exportName = specifiers[0];
|
|
370
|
+
const exportValue = resolvedModule.exports.named[exportName];
|
|
371
|
+
if (exportValue !== void 0) {
|
|
372
|
+
if (seen.has(resolvedModule.path + ":" + exportName)) {
|
|
373
|
+
throw new CircularDependencyError(
|
|
374
|
+
`Unable to resolve "${specifiers.join(".")}" in module "${resolvedModule.path}"`,
|
|
375
|
+
{ cause: "Circular dependency detected" }
|
|
376
|
+
);
|
|
377
|
+
}
|
|
378
|
+
seen.add(resolvedModule.path + ":" + exportName);
|
|
379
|
+
return resolveModuleExport(
|
|
380
|
+
context,
|
|
381
|
+
resolvedModule.path,
|
|
382
|
+
exportValue,
|
|
383
|
+
specifiers,
|
|
384
|
+
seen
|
|
385
|
+
);
|
|
386
|
+
}
|
|
387
|
+
let i = 1;
|
|
388
|
+
for (const from of resolvedModule.exports.all) {
|
|
389
|
+
if (context.exportAllLimit && i++ > context.exportAllLimit) {
|
|
390
|
+
throw new ResolveError(
|
|
391
|
+
`Unable to resolve "${specifiers.join(".")}" in module "${resolvedModule.path}"`,
|
|
392
|
+
{
|
|
393
|
+
cause: `More than ${context.exportAllLimit} star exports are not supported for performance reasons`
|
|
394
|
+
}
|
|
395
|
+
);
|
|
396
|
+
}
|
|
397
|
+
try {
|
|
398
|
+
const resolved = await resolveModuleExport(
|
|
399
|
+
context,
|
|
400
|
+
resolvedModule.path,
|
|
401
|
+
{
|
|
402
|
+
type: "re-export",
|
|
403
|
+
from,
|
|
404
|
+
name: exportName
|
|
405
|
+
},
|
|
406
|
+
specifiers,
|
|
407
|
+
seen
|
|
408
|
+
);
|
|
409
|
+
if (seen.has(resolvedModule.path + ":*")) {
|
|
410
|
+
throw new CircularDependencyError(
|
|
411
|
+
`Unable to resolve "${specifiers.join(".")}" in module "${resolvedModule.path}"`,
|
|
412
|
+
{ cause: "Circular dependency detected" }
|
|
413
|
+
);
|
|
414
|
+
}
|
|
415
|
+
seen.add(resolvedModule.path + ":*");
|
|
416
|
+
return resolved;
|
|
417
|
+
} catch (error) {
|
|
418
|
+
if (!(error instanceof ResolveError)) {
|
|
419
|
+
throw error;
|
|
420
|
+
}
|
|
421
|
+
if (error.circular) {
|
|
422
|
+
throw error;
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
throw new ResolveError(`Unable to resolve "${specifiers.join(".")}"`, {
|
|
427
|
+
cause: `no matching export found in module "${resolvedModule.path}"`
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
async function resolveModuleExport(context, filePath, moduleExport, specifiers, seen) {
|
|
431
|
+
try {
|
|
432
|
+
switch (moduleExport.type) {
|
|
433
|
+
case "re-export": {
|
|
434
|
+
const { resolved: reExportedModule } = await resolveModule(
|
|
435
|
+
context,
|
|
436
|
+
await context.resolve(moduleExport.from, filePath)
|
|
437
|
+
);
|
|
438
|
+
const resolved = await resolveModuleSpecifierRecursively(
|
|
439
|
+
context,
|
|
440
|
+
reExportedModule,
|
|
441
|
+
[moduleExport.name, ...specifiers.slice(1)],
|
|
442
|
+
seen
|
|
443
|
+
);
|
|
444
|
+
if (resolved) {
|
|
445
|
+
resolved.from.push(filePath);
|
|
446
|
+
}
|
|
447
|
+
return resolved;
|
|
448
|
+
}
|
|
449
|
+
case "namespace-re-export": {
|
|
450
|
+
const { resolved: reExportedModule } = await resolveModule(
|
|
451
|
+
context,
|
|
452
|
+
await context.resolve(moduleExport.from, filePath)
|
|
453
|
+
);
|
|
454
|
+
const resolved = await resolveModuleSpecifierRecursively(
|
|
455
|
+
context,
|
|
456
|
+
reExportedModule,
|
|
457
|
+
specifiers.slice(1),
|
|
458
|
+
seen
|
|
459
|
+
);
|
|
460
|
+
if (resolved) {
|
|
461
|
+
resolved.from.push(filePath);
|
|
462
|
+
}
|
|
463
|
+
return resolved;
|
|
464
|
+
}
|
|
465
|
+
case "styled-component": {
|
|
466
|
+
return {
|
|
467
|
+
type: "styled-component",
|
|
468
|
+
from: [filePath],
|
|
469
|
+
source: filePath,
|
|
470
|
+
name: specifiers[specifiers.length - 1],
|
|
471
|
+
value: moduleExport.className
|
|
472
|
+
};
|
|
473
|
+
}
|
|
474
|
+
// usually at this point `tag-template` exports where already resolved to
|
|
475
|
+
// styled-components if a matching styled-component comment was generated
|
|
476
|
+
// by yak-swc. So resolving a value to a `tag-template` at this stage
|
|
477
|
+
// would mean that the user tried to use the result of a call to a
|
|
478
|
+
// different tag-template than yak's styled in a template. This is usually
|
|
479
|
+
// invalid.
|
|
480
|
+
//
|
|
481
|
+
// But there is an issue with Nextjs. Next build in two passes, once for
|
|
482
|
+
// the server bundle, once for the client bundle. During the server-side
|
|
483
|
+
// build, each module with the `"use client"` directive is transformed to
|
|
484
|
+
// throw errors if the exported symbol are used. This transformation
|
|
485
|
+
// removes the comments generated by `yak-swc`, so instead of the expected
|
|
486
|
+
// `styled-component`, calls to `styled` resolve to a `tag-template`
|
|
487
|
+
// (because no classname was found in the now absent comments).
|
|
488
|
+
//
|
|
489
|
+
// To summarize, if a "use client" bundle exports a styled component that
|
|
490
|
+
// is used in a "standard" module, the resolve logic would throw with
|
|
491
|
+
// "unknown type tag-template".
|
|
492
|
+
//
|
|
493
|
+
// To avoid this error, the resolve logic must handle those `tag-template`
|
|
494
|
+
// with a special type `unresolved-tag`. Those will be interpolated to
|
|
495
|
+
// valid CSS with minimal effect (to avoid CSS syntax error in the case of
|
|
496
|
+
// Nextjs server build)
|
|
497
|
+
case "tag-template": {
|
|
498
|
+
return {
|
|
499
|
+
type: "unresolved-tag",
|
|
500
|
+
from: [filePath],
|
|
501
|
+
source: filePath,
|
|
502
|
+
name: specifiers[specifiers.length - 1]
|
|
503
|
+
};
|
|
504
|
+
}
|
|
505
|
+
case "constant": {
|
|
506
|
+
return {
|
|
507
|
+
type: "constant",
|
|
508
|
+
from: [filePath],
|
|
509
|
+
source: filePath,
|
|
510
|
+
value: moduleExport.value
|
|
511
|
+
};
|
|
512
|
+
}
|
|
513
|
+
case "record": {
|
|
514
|
+
const resolvedInRecord = resolveSpecifierInRecord(
|
|
515
|
+
moduleExport,
|
|
516
|
+
specifiers[0],
|
|
517
|
+
specifiers.slice(1)
|
|
518
|
+
);
|
|
519
|
+
return resolveModuleExport(
|
|
520
|
+
context,
|
|
521
|
+
filePath,
|
|
522
|
+
resolvedInRecord,
|
|
523
|
+
specifiers,
|
|
524
|
+
seen
|
|
525
|
+
);
|
|
526
|
+
}
|
|
527
|
+
case "mixin": {
|
|
528
|
+
return {
|
|
529
|
+
type: "mixin",
|
|
530
|
+
from: [filePath],
|
|
531
|
+
source: filePath,
|
|
532
|
+
value: moduleExport.value
|
|
533
|
+
};
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
} catch (error) {
|
|
537
|
+
throw new ResolveError(
|
|
538
|
+
`Unable to resolve "${specifiers.join(".")}" in module "${filePath}"`,
|
|
539
|
+
{ cause: error }
|
|
540
|
+
);
|
|
541
|
+
}
|
|
542
|
+
throw new ResolveError(
|
|
543
|
+
`Unable to resolve "${specifiers.join(".")}" in module "${filePath}"`,
|
|
544
|
+
{ cause: `unknown type "${moduleExport.type}"` }
|
|
545
|
+
);
|
|
546
|
+
}
|
|
547
|
+
function resolveSpecifierInRecord(record, name, specifiers) {
|
|
548
|
+
if (specifiers.length === 0) {
|
|
549
|
+
throw new ResolveError("did not expect an object");
|
|
550
|
+
}
|
|
551
|
+
let depth = 0;
|
|
552
|
+
let current = record;
|
|
553
|
+
while (current && current.type === "record" && depth < specifiers.length) {
|
|
554
|
+
current = current.value[specifiers[depth]];
|
|
555
|
+
depth += 1;
|
|
556
|
+
}
|
|
557
|
+
if (current === void 0 || depth !== specifiers.length) {
|
|
558
|
+
throw new ResolveError(
|
|
559
|
+
`Unable to resolve "${specifiers.join(".")}" in object/array "${name}"`,
|
|
560
|
+
{ cause: "path not found" }
|
|
561
|
+
);
|
|
562
|
+
}
|
|
563
|
+
if (current.type === "constant" || current.type === "styled-component" || current.type === "mixin") {
|
|
564
|
+
return current;
|
|
565
|
+
}
|
|
566
|
+
if (current.type === "record" && "__yak" in current.value && current.value.__yak.type === "constant") {
|
|
567
|
+
return { type: "mixin", value: String(current.value.__yak.value) };
|
|
568
|
+
}
|
|
569
|
+
throw new ResolveError(
|
|
570
|
+
`Unable to resolve "${specifiers.join(".")}" in object/array "${name}"`,
|
|
571
|
+
{ cause: "only string and numbers are supported" }
|
|
572
|
+
);
|
|
573
|
+
}
|
|
574
|
+
async function sha1(message) {
|
|
575
|
+
const resultBuffer = await globalThis.crypto.subtle.digest(
|
|
576
|
+
"SHA-1",
|
|
577
|
+
new TextEncoder().encode(message)
|
|
578
|
+
);
|
|
579
|
+
return Array.from(
|
|
580
|
+
new Uint8Array(resultBuffer),
|
|
581
|
+
(byte) => byte.toString(16).padStart(2, "0")
|
|
582
|
+
).join("");
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
// withYak/index.ts
|
|
586
|
+
import { existsSync } from "fs";
|
|
587
|
+
import path, { dirname } from "path";
|
|
588
|
+
import { fileURLToPath } from "url";
|
|
589
|
+
var currentDir = typeof __dirname !== "undefined" ? __dirname : dirname(fileURLToPath(import.meta.url));
|
|
590
|
+
function resolveYakContext(contextPath, cwd) {
|
|
591
|
+
const yakContext = contextPath ? path.resolve(cwd, contextPath) : path.resolve(cwd, "yak.context");
|
|
592
|
+
const extensions = ["", ".ts", ".tsx", ".js", ".jsx"];
|
|
593
|
+
for (const extension in extensions) {
|
|
594
|
+
const fileName = yakContext + extensions[extension];
|
|
595
|
+
if (existsSync(fileName)) {
|
|
596
|
+
return fileName;
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
if (contextPath) {
|
|
600
|
+
throw new Error(`Could not find yak context file at ${yakContext}`);
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
// loaders/lib/extractCss.ts
|
|
605
|
+
function extractCss(code, transpilationMode) {
|
|
606
|
+
let codeString;
|
|
607
|
+
if (typeof code === "string") {
|
|
608
|
+
codeString = code;
|
|
609
|
+
} else if (code instanceof Buffer) {
|
|
610
|
+
codeString = code.toString("utf-8");
|
|
611
|
+
} else if (code instanceof ArrayBuffer) {
|
|
612
|
+
codeString = new TextDecoder("utf-8").decode(code);
|
|
613
|
+
} else {
|
|
614
|
+
throw new Error(
|
|
615
|
+
"Invalid input type: code must be string, Buffer, or ArrayBuffer"
|
|
616
|
+
);
|
|
617
|
+
}
|
|
618
|
+
const codeParts = codeString.split("/*YAK Extracted CSS:\n");
|
|
619
|
+
let result = "";
|
|
620
|
+
for (let i = 1; i < codeParts.length; i++) {
|
|
621
|
+
const codeUntilEnd = codeParts[i].split("*/")[0];
|
|
622
|
+
result += codeUntilEnd;
|
|
623
|
+
}
|
|
624
|
+
if (result && transpilationMode !== "Css") {
|
|
625
|
+
result = "/* cssmodules-pure-no-check */\n" + result;
|
|
626
|
+
}
|
|
627
|
+
return result;
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
// loaders/lib/resolveCrossFileSelectors.ts
|
|
631
|
+
import { parse } from "@babel/parser";
|
|
632
|
+
import traverse from "@babel/traverse";
|
|
633
|
+
async function parseExports(sourceContents) {
|
|
634
|
+
const moduleExports = {
|
|
635
|
+
importYak: true,
|
|
636
|
+
named: {},
|
|
637
|
+
all: []
|
|
638
|
+
};
|
|
639
|
+
const variableDeclarations = {};
|
|
640
|
+
let defaultIdentifier = null;
|
|
641
|
+
try {
|
|
642
|
+
const ast = parse(sourceContents, {
|
|
643
|
+
sourceType: "module",
|
|
644
|
+
plugins: ["jsx", "typescript"]
|
|
645
|
+
});
|
|
646
|
+
traverse.default(ast, {
|
|
647
|
+
// Track all variable declarations in the file
|
|
648
|
+
VariableDeclarator({ node }) {
|
|
649
|
+
if (node.id.type === "Identifier" && node.init) {
|
|
650
|
+
variableDeclarations[node.id.name] = node.init;
|
|
651
|
+
}
|
|
652
|
+
},
|
|
653
|
+
ExportNamedDeclaration({ node }) {
|
|
654
|
+
if (node.source) {
|
|
655
|
+
node.specifiers.forEach((specifier) => {
|
|
656
|
+
if (specifier.type === "ExportSpecifier" && specifier.exported.type === "Identifier" && specifier.local.type === "Identifier") {
|
|
657
|
+
moduleExports.named[specifier.exported.name] = {
|
|
658
|
+
type: "re-export",
|
|
659
|
+
from: node.source.value,
|
|
660
|
+
name: specifier.local.name
|
|
661
|
+
};
|
|
662
|
+
}
|
|
663
|
+
});
|
|
664
|
+
} else if (node.declaration?.type === "VariableDeclaration") {
|
|
665
|
+
node.declaration.declarations.forEach((declaration) => {
|
|
666
|
+
if (declaration.id.type === "Identifier" && declaration.init) {
|
|
667
|
+
const parsed = parseExportValueExpression(declaration.init);
|
|
668
|
+
if (parsed) {
|
|
669
|
+
moduleExports.named[declaration.id.name] = parsed;
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
});
|
|
673
|
+
}
|
|
674
|
+
},
|
|
675
|
+
ExportDeclaration({ node }) {
|
|
676
|
+
if ("specifiers" in node && node.source) {
|
|
677
|
+
const { specifiers, source } = node;
|
|
678
|
+
specifiers.forEach((specifier) => {
|
|
679
|
+
if (specifier.type === "ExportNamespaceSpecifier" && specifier.exported.type === "Identifier") {
|
|
680
|
+
moduleExports.named[specifier.exported.name] = {
|
|
681
|
+
type: "namespace-re-export",
|
|
682
|
+
from: source.value
|
|
683
|
+
};
|
|
684
|
+
}
|
|
685
|
+
});
|
|
686
|
+
}
|
|
687
|
+
},
|
|
688
|
+
ExportDefaultDeclaration({ node }) {
|
|
689
|
+
if (node.declaration.type === "Identifier") {
|
|
690
|
+
defaultIdentifier = node.declaration.name;
|
|
691
|
+
} else if (node.declaration.type === "FunctionDeclaration" || node.declaration.type === "ClassDeclaration") {
|
|
692
|
+
moduleExports.named["default"] = {
|
|
693
|
+
type: "unsupported",
|
|
694
|
+
hint: node.declaration.type
|
|
695
|
+
};
|
|
696
|
+
} else {
|
|
697
|
+
moduleExports.named["default"] = parseExportValueExpression(
|
|
698
|
+
node.declaration
|
|
699
|
+
);
|
|
700
|
+
}
|
|
701
|
+
},
|
|
702
|
+
ExportAllDeclaration({ node }) {
|
|
703
|
+
moduleExports.all.push(node.source.value);
|
|
704
|
+
}
|
|
705
|
+
});
|
|
706
|
+
if (defaultIdentifier && variableDeclarations[defaultIdentifier]) {
|
|
707
|
+
moduleExports.named["default"] = parseExportValueExpression(
|
|
708
|
+
variableDeclarations[defaultIdentifier]
|
|
709
|
+
);
|
|
710
|
+
}
|
|
711
|
+
return moduleExports;
|
|
712
|
+
} catch (error) {
|
|
713
|
+
throw new Error(`Error parsing exports: ${error.message}`);
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
function unpackTSAsExpression(node) {
|
|
717
|
+
if (node.type === "TSAsExpression") {
|
|
718
|
+
return unpackTSAsExpression(node.expression);
|
|
719
|
+
}
|
|
720
|
+
return node;
|
|
721
|
+
}
|
|
722
|
+
function parseExportValueExpression(node) {
|
|
723
|
+
const expression = unpackTSAsExpression(node);
|
|
724
|
+
if (expression.type === "CallExpression" || expression.type === "TaggedTemplateExpression") {
|
|
725
|
+
return { type: "tag-template" };
|
|
726
|
+
} else if (expression.type === "StringLiteral" || expression.type === "NumericLiteral") {
|
|
727
|
+
return { type: "constant", value: expression.value };
|
|
728
|
+
} else if (expression.type === "UnaryExpression" && expression.operator === "-" && expression.argument.type === "NumericLiteral") {
|
|
729
|
+
return { type: "constant", value: -expression.argument.value };
|
|
730
|
+
} else if (expression.type === "TemplateLiteral" && expression.quasis.length === 1) {
|
|
731
|
+
return { type: "constant", value: expression.quasis[0].value.raw };
|
|
732
|
+
} else if (expression.type === "ObjectExpression") {
|
|
733
|
+
return { type: "record", value: parseObjectExpression(expression) };
|
|
734
|
+
}
|
|
735
|
+
return { type: "unsupported", hint: expression.type };
|
|
736
|
+
}
|
|
737
|
+
function parseObjectExpression(node) {
|
|
738
|
+
let result = {};
|
|
739
|
+
for (const property of node.properties) {
|
|
740
|
+
if (property.type === "ObjectProperty" && property.key.type === "Identifier") {
|
|
741
|
+
const key = property.key.name;
|
|
742
|
+
const parsed = parseExportValueExpression(
|
|
743
|
+
property.value
|
|
744
|
+
);
|
|
745
|
+
if (parsed) {
|
|
746
|
+
result[key] = parsed;
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
return result;
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
// loaders/vite-plugin.ts
|
|
754
|
+
var require2 = createRequire(import.meta.url);
|
|
755
|
+
var defaultSwcOptions = {
|
|
756
|
+
jsc: {
|
|
757
|
+
parser: {
|
|
758
|
+
syntax: "typescript",
|
|
759
|
+
tsx: true,
|
|
760
|
+
decorators: false,
|
|
761
|
+
dynamicImport: true
|
|
762
|
+
},
|
|
763
|
+
transform: {
|
|
764
|
+
react: {
|
|
765
|
+
runtime: "preserve"
|
|
766
|
+
}
|
|
767
|
+
},
|
|
768
|
+
target: "es2022",
|
|
769
|
+
loose: false,
|
|
770
|
+
minify: {
|
|
771
|
+
compress: false,
|
|
772
|
+
mangle: false
|
|
773
|
+
},
|
|
774
|
+
preserveAllComments: true
|
|
775
|
+
},
|
|
776
|
+
minify: false,
|
|
777
|
+
isModule: true
|
|
778
|
+
};
|
|
779
|
+
async function viteYak(userOptions = {}) {
|
|
780
|
+
const yakOptions = {
|
|
781
|
+
experiments: {
|
|
782
|
+
transpilationMode: "Css",
|
|
783
|
+
suppressDeprecationWarnings: false,
|
|
784
|
+
...userOptions.experiments
|
|
785
|
+
},
|
|
786
|
+
minify: userOptions.minify ?? process.env.NODE_ENV === "production",
|
|
787
|
+
prefix: userOptions.prefix,
|
|
788
|
+
contextPath: userOptions.contextPath,
|
|
789
|
+
swcOptions: deepMerge(defaultSwcOptions, userOptions.swcOptions ?? {})
|
|
790
|
+
};
|
|
791
|
+
yakOptions.displayNames = userOptions.displayNames ?? yakOptions.displayNames ?? !yakOptions.minify;
|
|
792
|
+
let root = process.cwd();
|
|
793
|
+
const debugLog = createDebugLogger(yakOptions.experiments?.debug, root);
|
|
794
|
+
const sourceFileRegex = /\.(tsx?|m?jsx?)\??/;
|
|
795
|
+
const virtualModuleRegex = /^virtual:yak-css:/;
|
|
796
|
+
const virtualCssModuleRegex = /^\0virtual:yak-css:/;
|
|
797
|
+
const yakSwcPath = await findYakSwcPlugin();
|
|
798
|
+
return {
|
|
799
|
+
name: "vite-plugin-yak:css:pre",
|
|
800
|
+
enforce: "pre",
|
|
801
|
+
config: (config) => {
|
|
802
|
+
const context = resolveYakContext(
|
|
803
|
+
yakOptions.contextPath,
|
|
804
|
+
config.root ?? root
|
|
805
|
+
);
|
|
806
|
+
if (!context) {
|
|
807
|
+
return;
|
|
808
|
+
}
|
|
809
|
+
config.resolve ||= {};
|
|
810
|
+
if (Array.isArray(config.resolve.alias)) {
|
|
811
|
+
config.resolve.alias.push({
|
|
812
|
+
find: "next-yak/context/baseContext",
|
|
813
|
+
replacement: context
|
|
814
|
+
});
|
|
815
|
+
} else {
|
|
816
|
+
config.resolve.alias = {
|
|
817
|
+
...config.resolve.alias,
|
|
818
|
+
"next-yak/context/baseContext": context
|
|
819
|
+
};
|
|
820
|
+
}
|
|
821
|
+
},
|
|
822
|
+
configResolved(config) {
|
|
823
|
+
root = config.root;
|
|
824
|
+
},
|
|
825
|
+
resolveId: {
|
|
826
|
+
filter: {
|
|
827
|
+
id: virtualModuleRegex
|
|
828
|
+
},
|
|
829
|
+
handler(id) {
|
|
830
|
+
return "\0" + id;
|
|
831
|
+
}
|
|
832
|
+
},
|
|
833
|
+
load: {
|
|
834
|
+
filter: {
|
|
835
|
+
id: virtualCssModuleRegex
|
|
836
|
+
},
|
|
837
|
+
async handler(id) {
|
|
838
|
+
const originalId = id.slice(17, -4);
|
|
839
|
+
this.addWatchFile(originalId);
|
|
840
|
+
const sourceContent = await this.fs.readFile(originalId, {
|
|
841
|
+
encoding: "utf8"
|
|
842
|
+
});
|
|
843
|
+
const code = await transform(
|
|
844
|
+
sourceContent,
|
|
845
|
+
originalId,
|
|
846
|
+
root,
|
|
847
|
+
yakSwcPath,
|
|
848
|
+
yakOptions
|
|
849
|
+
);
|
|
850
|
+
const extractedCss = extractCss(code.code, "Css");
|
|
851
|
+
debugLog("css", extractedCss, originalId);
|
|
852
|
+
const { resolved } = await resolveCrossFileConstant(
|
|
853
|
+
{
|
|
854
|
+
parse: (modulePath) => {
|
|
855
|
+
return parseModule(
|
|
856
|
+
{
|
|
857
|
+
transpilationMode: "Css",
|
|
858
|
+
extractExports: async (modulePath2) => {
|
|
859
|
+
const sourceContent2 = await this.fs.readFile(modulePath2, {
|
|
860
|
+
encoding: "utf8"
|
|
861
|
+
});
|
|
862
|
+
this.addWatchFile(modulePath2);
|
|
863
|
+
return parseExports(sourceContent2);
|
|
864
|
+
},
|
|
865
|
+
getTransformed: async (modulePath2) => {
|
|
866
|
+
const sourceContent2 = await this.fs.readFile(modulePath2, {
|
|
867
|
+
encoding: "utf8"
|
|
868
|
+
});
|
|
869
|
+
return transform(
|
|
870
|
+
sourceContent2,
|
|
871
|
+
modulePath2,
|
|
872
|
+
root,
|
|
873
|
+
yakSwcPath,
|
|
874
|
+
yakOptions
|
|
875
|
+
);
|
|
876
|
+
},
|
|
877
|
+
evaluateYakModule: async (modulePath2) => {
|
|
878
|
+
this.addWatchFile(modulePath2);
|
|
879
|
+
const sourceContent2 = await this.fs.readFile(modulePath2, {
|
|
880
|
+
encoding: "utf8"
|
|
881
|
+
});
|
|
882
|
+
const transformed = await swcTransform(sourceContent2, {
|
|
883
|
+
filename: modulePath2,
|
|
884
|
+
sourceFileName: modulePath2,
|
|
885
|
+
...yakOptions.swcOptions,
|
|
886
|
+
jsc: {
|
|
887
|
+
...yakOptions.swcOptions?.jsc,
|
|
888
|
+
experimental: {
|
|
889
|
+
plugins: [
|
|
890
|
+
[
|
|
891
|
+
yakSwcPath,
|
|
892
|
+
{
|
|
893
|
+
minify: yakOptions.minify,
|
|
894
|
+
basePath: root,
|
|
895
|
+
prefix: yakOptions.prefix,
|
|
896
|
+
displayNames: yakOptions.displayNames,
|
|
897
|
+
suppressDeprecationWarnings: yakOptions.experiments?.suppressDeprecationWarnings,
|
|
898
|
+
importMode: {
|
|
899
|
+
value: "virtual:yak-css:{{__MODULE_PATH__}}.css",
|
|
900
|
+
transpilation: "Css",
|
|
901
|
+
encoding: "None"
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
]
|
|
905
|
+
]
|
|
906
|
+
}
|
|
907
|
+
},
|
|
908
|
+
module: {
|
|
909
|
+
type: "commonjs"
|
|
910
|
+
}
|
|
911
|
+
});
|
|
912
|
+
const moduleObject = { exports: {} };
|
|
913
|
+
const context = createContext({
|
|
914
|
+
require: (path2) => {
|
|
915
|
+
throw new Error(
|
|
916
|
+
`Yak files cannot have imports in vite.
|
|
917
|
+
Found require/import usage in: ${modulePath2} to import: ${path2}.
|
|
918
|
+
Yak files should be self-contained and only export constants or styled components.
|
|
919
|
+
`
|
|
920
|
+
);
|
|
921
|
+
},
|
|
922
|
+
__filename: modulePath2,
|
|
923
|
+
__dirname: dirname2(modulePath2),
|
|
924
|
+
global: {},
|
|
925
|
+
console,
|
|
926
|
+
Buffer,
|
|
927
|
+
process,
|
|
928
|
+
setTimeout,
|
|
929
|
+
clearTimeout,
|
|
930
|
+
setInterval,
|
|
931
|
+
clearInterval,
|
|
932
|
+
setImmediate,
|
|
933
|
+
clearImmediate,
|
|
934
|
+
exports: moduleObject.exports,
|
|
935
|
+
module: moduleObject
|
|
936
|
+
});
|
|
937
|
+
runInContext(transformed.code, context);
|
|
938
|
+
return moduleObject.exports;
|
|
939
|
+
}
|
|
940
|
+
},
|
|
941
|
+
modulePath
|
|
942
|
+
);
|
|
943
|
+
},
|
|
944
|
+
resolve: async (moduleSpecifier, context) => {
|
|
945
|
+
let importer = context;
|
|
946
|
+
const resolved2 = await this.resolve(moduleSpecifier, importer);
|
|
947
|
+
if (!resolved2) {
|
|
948
|
+
throw new Error(
|
|
949
|
+
`Could not resolve ${moduleSpecifier} from ${context}`
|
|
950
|
+
);
|
|
951
|
+
}
|
|
952
|
+
return resolved2.id;
|
|
953
|
+
}
|
|
954
|
+
},
|
|
955
|
+
originalId,
|
|
956
|
+
extractedCss
|
|
957
|
+
);
|
|
958
|
+
debugLog("css-resolved", resolved, originalId);
|
|
959
|
+
return resolved;
|
|
960
|
+
}
|
|
961
|
+
},
|
|
962
|
+
transform: {
|
|
963
|
+
filter: {
|
|
964
|
+
id: {
|
|
965
|
+
include: sourceFileRegex,
|
|
966
|
+
exclude: [/packages\/next-yak/]
|
|
967
|
+
},
|
|
968
|
+
code: "next-yak"
|
|
969
|
+
},
|
|
970
|
+
async handler(code, id) {
|
|
971
|
+
try {
|
|
972
|
+
const result = await transform(
|
|
973
|
+
code,
|
|
974
|
+
id.split("?")[0],
|
|
975
|
+
root,
|
|
976
|
+
yakSwcPath,
|
|
977
|
+
yakOptions
|
|
978
|
+
);
|
|
979
|
+
debugLog("ts", result.code, id);
|
|
980
|
+
return {
|
|
981
|
+
code: result.code,
|
|
982
|
+
map: result.map
|
|
983
|
+
};
|
|
984
|
+
} catch (error) {
|
|
985
|
+
this.error(
|
|
986
|
+
`[YAK Plugin] Error transforming ${id}: ${error.message}`
|
|
987
|
+
);
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
};
|
|
992
|
+
}
|
|
993
|
+
async function findYakSwcPlugin() {
|
|
994
|
+
try {
|
|
995
|
+
const packageJsonPath = require2.resolve("yak-swc/package.json");
|
|
996
|
+
const packageRoot = dirname2(packageJsonPath);
|
|
997
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
|
|
998
|
+
const wasmPath = resolve(packageRoot, packageJson.main);
|
|
999
|
+
return wasmPath;
|
|
1000
|
+
} catch (e) {
|
|
1001
|
+
throw new Error(`Could not resolve yak-swc plugin: ${e}`);
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
function transform(data, modulePath, rootPath, yakSwcPath, yakOptions) {
|
|
1005
|
+
return swcTransform(data, {
|
|
1006
|
+
filename: modulePath,
|
|
1007
|
+
inputSourceMap: void 0,
|
|
1008
|
+
sourceMaps: true,
|
|
1009
|
+
sourceFileName: modulePath,
|
|
1010
|
+
sourceRoot: rootPath,
|
|
1011
|
+
...yakOptions.swcOptions,
|
|
1012
|
+
jsc: {
|
|
1013
|
+
...yakOptions.swcOptions?.jsc,
|
|
1014
|
+
experimental: {
|
|
1015
|
+
plugins: [
|
|
1016
|
+
[
|
|
1017
|
+
yakSwcPath,
|
|
1018
|
+
{
|
|
1019
|
+
minify: yakOptions.minify,
|
|
1020
|
+
basePath: rootPath,
|
|
1021
|
+
prefix: yakOptions.prefix,
|
|
1022
|
+
displayNames: yakOptions.displayNames,
|
|
1023
|
+
suppressDeprecationWarnings: yakOptions.experiments?.suppressDeprecationWarnings,
|
|
1024
|
+
importMode: {
|
|
1025
|
+
value: "virtual:yak-css:{{__MODULE_PATH__}}.css",
|
|
1026
|
+
transpilation: "Css",
|
|
1027
|
+
encoding: "None"
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
]
|
|
1031
|
+
]
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
});
|
|
1035
|
+
}
|
|
1036
|
+
function createDebugLogger(debugOptions, root) {
|
|
1037
|
+
if (!debugOptions) {
|
|
1038
|
+
return () => {
|
|
1039
|
+
};
|
|
1040
|
+
}
|
|
1041
|
+
return (messageType, message, filePath) => {
|
|
1042
|
+
const pathWithExtension = messageType !== "ts" ? filePath + `.${messageType}` : filePath;
|
|
1043
|
+
if (debugOptions === true || new RegExp(debugOptions).test(pathWithExtension)) {
|
|
1044
|
+
console.log("\u{1F42E} Yak", relative(root, pathWithExtension), "\n\n", message);
|
|
1045
|
+
}
|
|
1046
|
+
};
|
|
1047
|
+
}
|
|
1048
|
+
function deepMerge(target, source) {
|
|
1049
|
+
const result = { ...target };
|
|
1050
|
+
for (const key of Object.keys(source)) {
|
|
1051
|
+
const sourceValue = source[key];
|
|
1052
|
+
const targetValue = target[key];
|
|
1053
|
+
if (sourceValue !== void 0 && typeof sourceValue === "object" && sourceValue !== null && !Array.isArray(sourceValue) && typeof targetValue === "object" && targetValue !== null && !Array.isArray(targetValue)) {
|
|
1054
|
+
result[key] = deepMerge(
|
|
1055
|
+
targetValue,
|
|
1056
|
+
sourceValue
|
|
1057
|
+
);
|
|
1058
|
+
} else if (sourceValue !== void 0) {
|
|
1059
|
+
result[key] = sourceValue;
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
return result;
|
|
1063
|
+
}
|
|
1064
|
+
export {
|
|
1065
|
+
createDebugLogger,
|
|
1066
|
+
viteYak
|
|
1067
|
+
};
|
|
1068
|
+
//# sourceMappingURL=vite-plugin.js.map
|