@voidzero-dev/vite-plus-core 0.2.0 → 0.2.2
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 +175 -30
- package/dist/rolldown/cli.mjs +25 -14
- package/dist/rolldown/config.d.mts +1 -1
- package/dist/rolldown/config.mjs +2 -2
- package/dist/rolldown/experimental-index.d.mts +15 -5
- package/dist/rolldown/experimental-index.mjs +23 -17
- package/dist/rolldown/filter-index.d.mts +1 -1
- package/dist/rolldown/index.d.mts +2 -2
- package/dist/rolldown/index.mjs +4 -4
- package/dist/rolldown/parallel-plugin-worker.mjs +5 -4
- package/dist/rolldown/parallel-plugin.d.mts +1 -1
- package/dist/rolldown/parse-ast-index.d.mts +1 -1
- package/dist/rolldown/parse-ast-index.mjs +1 -1
- package/dist/rolldown/plugins-index.d.mts +3 -3
- package/dist/rolldown/plugins-index.mjs +2 -2
- package/dist/rolldown/shared/{binding-DgGsNpT9.d.mts → binding-B1q9aYT-.d.mts} +65 -142
- package/dist/rolldown/shared/{binding-CfwqjDbP.mjs → binding-BmkJW3Wy.mjs} +39 -35
- package/dist/rolldown/shared/{bindingify-input-options--chmbDhw.mjs → bindingify-input-options-Cmm60vfj.mjs} +1330 -1331
- package/dist/rolldown/shared/{constructors-Bx1tSad6.d.mts → constructors-2i1T9YcF.d.mts} +3 -4
- package/dist/rolldown/shared/{constructors-DnT9y_13.mjs → constructors-CE6zZSUt.mjs} +2 -5
- package/dist/rolldown/shared/{define-config-ChOOV2QZ.d.mts → define-config-BBz954-q.d.mts} +2 -2
- package/dist/rolldown/shared/{error-C0TrL0_H.mjs → error-BlQ0-ek7.mjs} +1 -1
- package/dist/rolldown/shared/{load-config-BXgGQtnA.mjs → load-config-CVVMWSlg.mjs} +1 -1
- package/dist/rolldown/shared/{normalize-string-or-regex-DGbe3BlX.mjs → normalize-string-or-regex-BYkbbGqQ.mjs} +1 -1
- package/dist/rolldown/shared/{parse-26ORR8fZ.mjs → parse-Dphnedsw.mjs} +2 -2
- package/dist/rolldown/shared/{prompt-DV1XbtjC.mjs → prompt-Bgj-uEyc.mjs} +5 -5
- package/dist/rolldown/shared/{resolve-tsconfig-D3YLh9ff.mjs → resolve-tsconfig-CdIAR1Eb.mjs} +2 -2
- package/dist/rolldown/shared/{rolldown-DpXXI00f.mjs → rolldown-Bnp916iM.mjs} +1 -1
- package/dist/rolldown/shared/{rolldown-build-D8R4Zzfy.mjs → rolldown-build-Cs2iVJuw.mjs} +24 -56
- package/dist/rolldown/shared/{transform-C-XSNVrd.d.mts → transform-CEmFsvJW.d.mts} +1 -1
- package/dist/rolldown/shared/{watch-D5Zm0Vsz.mjs → watch-ECGr-_QS.mjs} +4 -4
- package/dist/rolldown/utils-index.d.mts +3 -3
- package/dist/rolldown/utils-index.mjs +6 -6
- package/dist/tsdown/{build-B_nvJe4A-hrVGPLD6.js → build-B_nvJe4A-CcOht0gr.js} +73 -139
- package/dist/tsdown/debug-DLdR-9XB-CDf7D82m.js +250 -0
- package/dist/tsdown/{detect-B97OSl92-B5bcx_Ya.js → detect-B97OSl92-kGHGL-qU.js} +1 -1
- package/dist/tsdown/{dist-Dvzn3mZN.js → dist-580owkGv.js} +30 -25
- package/dist/tsdown/general-Cp4NiJNK-BYPTHEzb.js +97 -0
- package/dist/tsdown/index-types.d.ts +197 -7
- package/dist/tsdown/index.js +3 -3
- package/dist/tsdown/internal-CUXleGMS.js +3 -0
- package/dist/tsdown/{main-BMtwTklr.js → main-BlTcyuFi.js} +2 -341
- package/dist/tsdown/npm_entry_picomatch.cjs +4 -2
- package/dist/tsdown/npm_entry_semver_functions_coerce.cjs +5 -1
- package/dist/tsdown/{resolver-DtsKFXi2-DQOmVgSY.js → resolver-DtsKFXi2-B8Z3WwZh.js} +1 -1
- package/dist/tsdown/run.js +4 -3
- package/dist/tsdown/src-njF8VL4a.js +622 -0
- package/dist/tsdown/target-CqeSqtms-ZU1Gv6-M.js +79 -0
- package/dist/tsdown/{tsc-q0JAW6kD.js → tsc-CsN85f7a.js} +3 -3
- package/dist/tsdown/{tsc-context-DfwSQt2q.js → tsc-context-CX_GXdyS.js} +2 -2
- package/dist/tsdown/tsdown-css.js +874 -0
- package/dist/tsdown/tsdown-exe.js +949 -0
- package/dist/vite/client/client.mjs +7 -9
- package/dist/vite/client.d.ts +3 -0
- package/dist/vite/node/chunks/build.js +27 -34
- package/dist/vite/node/chunks/dist.js +23 -23
- package/dist/vite/node/chunks/dist2.js +3 -3
- package/dist/vite/node/chunks/logger.js +4 -4
- package/dist/vite/node/chunks/node.js +12354 -11629
- package/dist/vite/node/chunks/postcss-import.js +10 -10
- package/dist/vite/node/cli.js +3 -3
- package/dist/vite/node/index.d.ts +139 -14
- package/dist/vite/node/index.js +1 -1
- package/dist/vite/node/module-runner.js +4 -4
- package/dist/vite/types/importGlob.d.ts +48 -6
- package/package.json +15 -21
|
@@ -0,0 +1,874 @@
|
|
|
1
|
+
import { m as __toESM, n as importWithError, s as resolveComma, u as toArray } from "./general-Cp4NiJNK-BYPTHEzb.js";
|
|
2
|
+
import { t as expandBaselineTarget } from "./target-CqeSqtms-ZU1Gv6-M.js";
|
|
3
|
+
import "./internal-CUXleGMS.js";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { readFileSync } from "node:fs";
|
|
6
|
+
import { readFile } from "node:fs/promises";
|
|
7
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
8
|
+
import { ResolverFactory } from "@voidzero-dev/vite-plus-core/rolldown/experimental";
|
|
9
|
+
//#region ../../node_modules/.pnpm/@tsdown+css@0.22.3_jiti@2.7.0_postcss-import@16.1.1_postcss@8.5.16__postcss-modules@6.0_8815f8f9084693f5f3ebee14fa13c42a/node_modules/@tsdown/css/dist/index.mjs
|
|
10
|
+
const defaultCssBundleName = "style.css";
|
|
11
|
+
function resolveCssOptions(options = {}, topLevelTarget, unbundle) {
|
|
12
|
+
let cssTarget;
|
|
13
|
+
if (options.target === false) cssTarget = void 0;
|
|
14
|
+
else if (options.target == null) cssTarget = topLevelTarget;
|
|
15
|
+
else cssTarget = expandBaselineTarget(resolveComma(toArray(options.target)));
|
|
16
|
+
return {
|
|
17
|
+
transformer: options.transformer ?? "lightningcss",
|
|
18
|
+
splitting: options.splitting ?? !!unbundle,
|
|
19
|
+
fileName: options.fileName ?? "style.css",
|
|
20
|
+
minify: options.minify ?? false,
|
|
21
|
+
inject: options.inject ?? false,
|
|
22
|
+
modules: options.modules === false ? false : options.modules ?? {},
|
|
23
|
+
target: cssTarget,
|
|
24
|
+
preprocessorOptions: options.preprocessorOptions,
|
|
25
|
+
lightningcss: options.lightningcss,
|
|
26
|
+
postcss: options.postcss
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function modulesToEsm(modules) {
|
|
30
|
+
const lines = [];
|
|
31
|
+
let index = 0;
|
|
32
|
+
for (const [key, value] of Object.entries(modules)) {
|
|
33
|
+
if (key === "default") continue;
|
|
34
|
+
const binding = `_key${index++}`;
|
|
35
|
+
lines.push(`const ${binding} = ${JSON.stringify(value)};`, `export { ${binding} as ${JSON.stringify(key)} };`);
|
|
36
|
+
}
|
|
37
|
+
lines.push(`export default ${JSON.stringify(modules)};`);
|
|
38
|
+
return lines.join("\n");
|
|
39
|
+
}
|
|
40
|
+
function dashToCamel(str) {
|
|
41
|
+
return str.replaceAll(/-([a-z])/g, (_, c) => c.toUpperCase());
|
|
42
|
+
}
|
|
43
|
+
function applyLocalsConvention(modules, convention) {
|
|
44
|
+
const result = {};
|
|
45
|
+
for (const [key, value] of Object.entries(modules)) {
|
|
46
|
+
const camelized = dashToCamel(key);
|
|
47
|
+
switch (convention) {
|
|
48
|
+
case "camelCase":
|
|
49
|
+
result[key] = value;
|
|
50
|
+
if (camelized !== key) result[camelized] = value;
|
|
51
|
+
break;
|
|
52
|
+
case "camelCaseOnly":
|
|
53
|
+
result[camelized] = value;
|
|
54
|
+
break;
|
|
55
|
+
case "dashes":
|
|
56
|
+
result[key] = value;
|
|
57
|
+
if (key.includes("-")) result[camelized] = value;
|
|
58
|
+
break;
|
|
59
|
+
case "dashesOnly":
|
|
60
|
+
if (key.includes("-")) result[camelized] = value;
|
|
61
|
+
else result[key] = value;
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return result;
|
|
66
|
+
}
|
|
67
|
+
function extractLightningCssModuleExports(exports) {
|
|
68
|
+
const modules = {};
|
|
69
|
+
const sortedEntries = Object.entries(exports).toSorted(([a], [b]) => a.localeCompare(b));
|
|
70
|
+
for (const [key, value] of sortedEntries) {
|
|
71
|
+
let name = value.name;
|
|
72
|
+
for (const c of value.composes) name += ` ${c.name}`;
|
|
73
|
+
modules[key] = name;
|
|
74
|
+
}
|
|
75
|
+
return modules;
|
|
76
|
+
}
|
|
77
|
+
let cssResolver;
|
|
78
|
+
let sassResolver;
|
|
79
|
+
function getCssResolver() {
|
|
80
|
+
return cssResolver ??= new ResolverFactory({ conditionNames: ["style", "default"] });
|
|
81
|
+
}
|
|
82
|
+
function getSassResolver() {
|
|
83
|
+
return sassResolver ??= new ResolverFactory({
|
|
84
|
+
conditionNames: [
|
|
85
|
+
"sass",
|
|
86
|
+
"style",
|
|
87
|
+
"default"
|
|
88
|
+
],
|
|
89
|
+
mainFields: [
|
|
90
|
+
"sass",
|
|
91
|
+
"style",
|
|
92
|
+
"main"
|
|
93
|
+
],
|
|
94
|
+
extensions: [
|
|
95
|
+
".scss",
|
|
96
|
+
".sass",
|
|
97
|
+
".css"
|
|
98
|
+
]
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
function resolveWithResolver(resolver, specifier, from) {
|
|
102
|
+
const dir = path.dirname(from);
|
|
103
|
+
const result = resolver.sync(dir, specifier);
|
|
104
|
+
if (result.error || !result.path) return;
|
|
105
|
+
return result.path;
|
|
106
|
+
}
|
|
107
|
+
const RE_CSS = /\.css$/;
|
|
108
|
+
const RE_INLINE = /[?&]inline\b/;
|
|
109
|
+
const CSS_LANGS_RE = /\.(css|less|sass|scss|styl|stylus)(?:$|\?)/;
|
|
110
|
+
const RE_CSS_INLINE = /\.(?:css|less|sass|scss|styl|stylus)\?(?:.*&)?inline\b/;
|
|
111
|
+
const CSS_MODULE_RE = /\.module\.(?:css|less|sass|scss|styl|stylus)(?:$|\?)/;
|
|
112
|
+
function toCssFileName(jsFileName) {
|
|
113
|
+
return jsFileName.replace(/(?:\.module)?(\.[cm]?js)$/, ".css");
|
|
114
|
+
}
|
|
115
|
+
function getCleanId(id) {
|
|
116
|
+
const queryIndex = id.indexOf("?");
|
|
117
|
+
return queryIndex === -1 ? id : id.slice(0, queryIndex);
|
|
118
|
+
}
|
|
119
|
+
const PREPROCESSOR_LANGS = {
|
|
120
|
+
sass: "sass",
|
|
121
|
+
less: "less",
|
|
122
|
+
scss: "scss",
|
|
123
|
+
styl: "styl",
|
|
124
|
+
stylus: "stylus"
|
|
125
|
+
};
|
|
126
|
+
function getPreprocessorLang(filename) {
|
|
127
|
+
return PREPROCESSOR_LANGS[path.extname(filename).slice(1)];
|
|
128
|
+
}
|
|
129
|
+
function getPreprocessorLangFromId(id) {
|
|
130
|
+
const match = CSS_LANGS_RE.exec(id);
|
|
131
|
+
if (!match) return;
|
|
132
|
+
return PREPROCESSOR_LANGS[match[1]];
|
|
133
|
+
}
|
|
134
|
+
function compilePreprocessor(lang, code, filename, options) {
|
|
135
|
+
switch (lang) {
|
|
136
|
+
case "scss":
|
|
137
|
+
case "sass": return compileSass(lang, code, filename, options);
|
|
138
|
+
case "less": return compileLess(code, filename, options);
|
|
139
|
+
case "styl":
|
|
140
|
+
case "stylus": return compileStylus(code, filename, options);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
const cssUrlRE = /(?<!@import\s+)(?<=^|[^\w\-\u0080-\uFFFF])url\((\s*('[^']+'|"[^"]+")\s*|(?:\\.|[^'")\\])+)\)/;
|
|
144
|
+
const cssDataUriRE = /(?<=^|[^\w\-\u0080-\uFFFF])data-uri\((\s*('[^']+'|"[^"]+")\s*|[^'")]+)\)/;
|
|
145
|
+
const importCssRE = /@import\s+(?:url\()?('[^']+\.css'|"[^"]+\.css"|[^'"\s)]+\.css)/;
|
|
146
|
+
async function rebaseUrls(file, rootFile, ignoreUrl) {
|
|
147
|
+
file = path.resolve(file);
|
|
148
|
+
const fileDir = path.dirname(file);
|
|
149
|
+
const rootDir = path.dirname(rootFile);
|
|
150
|
+
if (fileDir === rootDir) return { file };
|
|
151
|
+
const content = await readFile(file, "utf8");
|
|
152
|
+
const hasUrls = cssUrlRE.test(content);
|
|
153
|
+
const hasDataUris = cssDataUriRE.test(content);
|
|
154
|
+
const hasImportCss = importCssRE.test(content);
|
|
155
|
+
if (!hasUrls && !hasDataUris && !hasImportCss) return { file };
|
|
156
|
+
let rebased;
|
|
157
|
+
const rebaseFn = (unquotedUrl, rawUrl) => {
|
|
158
|
+
if (ignoreUrl?.(unquotedUrl, rawUrl)) return false;
|
|
159
|
+
if (unquotedUrl[0] === "/") return unquotedUrl;
|
|
160
|
+
const absolute = path.resolve(fileDir, unquotedUrl);
|
|
161
|
+
return normalizePath(path.relative(rootDir, absolute));
|
|
162
|
+
};
|
|
163
|
+
if (hasImportCss) rebased = await rewriteImportCss(content, rebaseFn);
|
|
164
|
+
if (hasUrls) rebased = await rewriteCssUrls(rebased || content, rebaseFn);
|
|
165
|
+
if (hasDataUris) rebased = await rewriteCssDataUris(rebased || content, rebaseFn);
|
|
166
|
+
return {
|
|
167
|
+
file,
|
|
168
|
+
contents: rebased
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
async function asyncReplace(input, re, replacer) {
|
|
172
|
+
let match;
|
|
173
|
+
let remaining = input;
|
|
174
|
+
let rewritten = "";
|
|
175
|
+
while (match = re.exec(remaining)) {
|
|
176
|
+
rewritten += remaining.slice(0, match.index);
|
|
177
|
+
rewritten += await replacer(match);
|
|
178
|
+
remaining = remaining.slice(match.index + match[0].length);
|
|
179
|
+
}
|
|
180
|
+
rewritten += remaining;
|
|
181
|
+
return rewritten;
|
|
182
|
+
}
|
|
183
|
+
function rewriteCssUrls(css, replacer) {
|
|
184
|
+
return asyncReplace(css, cssUrlRE, async (match) => {
|
|
185
|
+
const [matched, rawUrl] = match;
|
|
186
|
+
return await doUrlReplace(rawUrl.trim(), matched, replacer);
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
function rewriteCssDataUris(css, replacer) {
|
|
190
|
+
return asyncReplace(css, cssDataUriRE, async (match) => {
|
|
191
|
+
const [matched, rawUrl] = match;
|
|
192
|
+
return await doUrlReplace(rawUrl.trim(), matched, replacer, "data-uri");
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
function rewriteImportCss(css, replacer) {
|
|
196
|
+
return asyncReplace(css, importCssRE, async (match) => {
|
|
197
|
+
const [matched, rawUrl] = match;
|
|
198
|
+
return await doImportCSSReplace(rawUrl, matched, replacer);
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
const externalRE = /^(?:[a-z]+:)?\/\//;
|
|
202
|
+
const dataUrlRE = /^\s*data:/i;
|
|
203
|
+
function skipUrlReplacer(unquotedUrl) {
|
|
204
|
+
return externalRE.test(unquotedUrl) || dataUrlRE.test(unquotedUrl) || unquotedUrl[0] === "#";
|
|
205
|
+
}
|
|
206
|
+
async function doUrlReplace(rawUrl, matched, replacer, funcName = "url") {
|
|
207
|
+
let wrap = "";
|
|
208
|
+
const first = rawUrl[0];
|
|
209
|
+
if (first === `"` || first === `'`) {
|
|
210
|
+
wrap = first;
|
|
211
|
+
rawUrl = rawUrl.slice(1, -1);
|
|
212
|
+
}
|
|
213
|
+
if (skipUrlReplacer(rawUrl)) return matched;
|
|
214
|
+
const newUrl = await replacer(rawUrl, matched);
|
|
215
|
+
if (typeof newUrl === "string") {
|
|
216
|
+
if (wrap === "" && newUrl !== encodeURI(newUrl)) wrap = "\"";
|
|
217
|
+
return `${funcName}(${wrap}${newUrl}${wrap})`;
|
|
218
|
+
}
|
|
219
|
+
return matched;
|
|
220
|
+
}
|
|
221
|
+
async function doImportCSSReplace(rawUrl, matched, replacer) {
|
|
222
|
+
let wrap = "";
|
|
223
|
+
const first = rawUrl[0];
|
|
224
|
+
if (first === `"` || first === `'`) {
|
|
225
|
+
wrap = first;
|
|
226
|
+
rawUrl = rawUrl.slice(1, -1);
|
|
227
|
+
}
|
|
228
|
+
const newUrl = await replacer(rawUrl, matched);
|
|
229
|
+
if (typeof newUrl === "string") return matched.replace(`${wrap}${rawUrl}${wrap}`, `${wrap}${newUrl}${wrap}`);
|
|
230
|
+
return matched;
|
|
231
|
+
}
|
|
232
|
+
function normalizePath(id) {
|
|
233
|
+
return id.replaceAll("\\", "/");
|
|
234
|
+
}
|
|
235
|
+
async function getSource(source, filename, additionalData, sep = "") {
|
|
236
|
+
if (!additionalData) return source;
|
|
237
|
+
if (typeof additionalData === "function") {
|
|
238
|
+
const newContent = await additionalData(source, filename);
|
|
239
|
+
if (typeof newContent === "string") return newContent;
|
|
240
|
+
return newContent.content;
|
|
241
|
+
}
|
|
242
|
+
return additionalData + sep + source;
|
|
243
|
+
}
|
|
244
|
+
async function compileSass(lang, code, filename, options) {
|
|
245
|
+
const sass = await loadSass();
|
|
246
|
+
const preprocessorOpts = options?.scss ?? options?.sass ?? {};
|
|
247
|
+
const data = await getSource(code, filename, preprocessorOpts.additionalData);
|
|
248
|
+
const { additionalData: _, ...sassOptions } = preprocessorOpts;
|
|
249
|
+
const skipRebaseUrls = (unquotedUrl, rawUrl) => {
|
|
250
|
+
if (!(rawUrl[0] === "\"" || rawUrl[0] === "'") && unquotedUrl[0] === "$") return true;
|
|
251
|
+
return unquotedUrl.startsWith("#{");
|
|
252
|
+
};
|
|
253
|
+
const internalImporter = {
|
|
254
|
+
async canonicalize(url, context) {
|
|
255
|
+
const resolved = await tryResolveScss(url, context.containingUrl ? fileURLToPath(context.containingUrl) : filename);
|
|
256
|
+
if (resolved) return pathToFileURL(resolved);
|
|
257
|
+
return null;
|
|
258
|
+
},
|
|
259
|
+
async load(canonicalUrl) {
|
|
260
|
+
const ext = path.extname(canonicalUrl.pathname);
|
|
261
|
+
let syntax = "scss";
|
|
262
|
+
if (ext === ".sass") syntax = "indented";
|
|
263
|
+
else if (ext === ".css") syntax = "css";
|
|
264
|
+
const result = await rebaseUrls(fileURLToPath(canonicalUrl), filename, skipRebaseUrls);
|
|
265
|
+
return {
|
|
266
|
+
contents: result.contents ?? await readFile(result.file, "utf8"),
|
|
267
|
+
syntax,
|
|
268
|
+
sourceMapUrl: canonicalUrl
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
};
|
|
272
|
+
const result = await sass.compileStringAsync(data, {
|
|
273
|
+
url: pathToFileURL(filename),
|
|
274
|
+
sourceMap: false,
|
|
275
|
+
syntax: lang === "sass" ? "indented" : "scss",
|
|
276
|
+
...sassOptions,
|
|
277
|
+
importers: [internalImporter, ...sassOptions.importers ?? []]
|
|
278
|
+
});
|
|
279
|
+
return {
|
|
280
|
+
code: result.css,
|
|
281
|
+
deps: result.loadedUrls.filter((url) => url.protocol === "file:").map((url) => fileURLToPath(url))
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
async function tryResolveScss(url, importer) {
|
|
285
|
+
const dir = path.dirname(importer);
|
|
286
|
+
const { existsSync } = await import("node:fs");
|
|
287
|
+
const extensions = [
|
|
288
|
+
".scss",
|
|
289
|
+
".sass",
|
|
290
|
+
".css"
|
|
291
|
+
];
|
|
292
|
+
const prefixes = ["", "_"];
|
|
293
|
+
if (extensions.some((ext) => url.endsWith(ext))) for (const prefix of prefixes) {
|
|
294
|
+
const file = path.resolve(dir, path.dirname(url), prefix + path.basename(url));
|
|
295
|
+
if (existsSync(file)) return file;
|
|
296
|
+
}
|
|
297
|
+
else {
|
|
298
|
+
for (const ext of extensions) for (const prefix of prefixes) {
|
|
299
|
+
const file = path.resolve(dir, path.dirname(url), prefix + path.basename(url) + ext);
|
|
300
|
+
if (existsSync(file)) return file;
|
|
301
|
+
}
|
|
302
|
+
for (const ext of extensions) for (const prefix of prefixes) {
|
|
303
|
+
const file = path.resolve(dir, url, `${prefix}index${ext}`);
|
|
304
|
+
if (existsSync(file)) return file;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
return resolveWithResolver(getSassResolver(), url, importer);
|
|
308
|
+
}
|
|
309
|
+
let _sass;
|
|
310
|
+
async function loadSass() {
|
|
311
|
+
if (_sass) return _sass;
|
|
312
|
+
try {
|
|
313
|
+
_sass = await import("sass-embedded");
|
|
314
|
+
return _sass;
|
|
315
|
+
} catch {
|
|
316
|
+
try {
|
|
317
|
+
_sass = await import("sass");
|
|
318
|
+
return _sass;
|
|
319
|
+
} catch {
|
|
320
|
+
throw new Error("Preprocessor dependency \"sass\" not found. Did you install it? Try `npm install -D sass`.");
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
async function compileLess(code, filename, options) {
|
|
325
|
+
const less = await loadLess();
|
|
326
|
+
const preprocessorOpts = options?.less ?? {};
|
|
327
|
+
const data = await getSource(code, filename, preprocessorOpts.additionalData);
|
|
328
|
+
const { additionalData: _, plugins = [], ...lessOptions } = preprocessorOpts;
|
|
329
|
+
const result = await less.render(data, {
|
|
330
|
+
paths: ["node_modules"],
|
|
331
|
+
...lessOptions,
|
|
332
|
+
filename,
|
|
333
|
+
plugins
|
|
334
|
+
});
|
|
335
|
+
return {
|
|
336
|
+
code: result.css,
|
|
337
|
+
deps: result.imports || []
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
let _less;
|
|
341
|
+
async function loadLess() {
|
|
342
|
+
if (_less) return _less;
|
|
343
|
+
try {
|
|
344
|
+
_less = (await import("less")).default;
|
|
345
|
+
return _less;
|
|
346
|
+
} catch {
|
|
347
|
+
throw new Error("Preprocessor dependency \"less\" not found. Did you install it? Try `npm install -D less`.");
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
async function compileStylus(code, filename, options) {
|
|
351
|
+
const stylus = await loadStylus();
|
|
352
|
+
const preprocessorOpts = options?.styl ?? options?.stylus ?? {};
|
|
353
|
+
const data = await getSource(code, filename, preprocessorOpts.additionalData, "\n");
|
|
354
|
+
const { additionalData: _, define, ...stylusOptions } = preprocessorOpts;
|
|
355
|
+
const ref = stylus(data, {
|
|
356
|
+
paths: ["node_modules"],
|
|
357
|
+
...stylusOptions,
|
|
358
|
+
filename
|
|
359
|
+
});
|
|
360
|
+
if (define) for (const key of Object.keys(define)) ref.define(key, define[key]);
|
|
361
|
+
return new Promise((resolve, reject) => {
|
|
362
|
+
ref.render((err, css) => {
|
|
363
|
+
if (err) reject(/* @__PURE__ */ new Error(`[stylus] ${err.message}`));
|
|
364
|
+
else resolve({
|
|
365
|
+
code: css,
|
|
366
|
+
deps: ref.deps()
|
|
367
|
+
});
|
|
368
|
+
});
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
let _stylus;
|
|
372
|
+
async function loadStylus() {
|
|
373
|
+
if (_stylus) return _stylus;
|
|
374
|
+
try {
|
|
375
|
+
_stylus = (await import("stylus")).default;
|
|
376
|
+
return _stylus;
|
|
377
|
+
} catch {
|
|
378
|
+
throw new Error("Preprocessor dependency \"stylus\" not found. Did you install it? Try `npm install -D stylus`.");
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
const encoder = new TextEncoder();
|
|
382
|
+
const decoder = new TextDecoder();
|
|
383
|
+
async function transformWithLightningCSS(code, filename, options) {
|
|
384
|
+
const targets = options.lightningcss?.targets ?? (options.target ? esbuildTargetToLightningCSS(options.target) : void 0);
|
|
385
|
+
if (!targets && !options.lightningcss && !options.minify && !options.cssModules) return { code };
|
|
386
|
+
const { transform } = await import("lightningcss");
|
|
387
|
+
const result = transform({
|
|
388
|
+
filename,
|
|
389
|
+
code: encoder.encode(code),
|
|
390
|
+
...options.lightningcss,
|
|
391
|
+
targets,
|
|
392
|
+
minify: options.minify,
|
|
393
|
+
cssModules: options.cssModules
|
|
394
|
+
});
|
|
395
|
+
return {
|
|
396
|
+
code: decoder.decode(result.code),
|
|
397
|
+
modules: result.exports ? extractLightningCssModuleExports(result.exports) : void 0
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
async function bundleWithLightningCSS(filename, options, code) {
|
|
401
|
+
const targets = options.lightningcss?.targets ?? (options.target ? esbuildTargetToLightningCSS(options.target) : void 0);
|
|
402
|
+
const deps = [];
|
|
403
|
+
const { bundleAsync } = await import("lightningcss");
|
|
404
|
+
const result = await bundleAsync({
|
|
405
|
+
filename,
|
|
406
|
+
...options.lightningcss,
|
|
407
|
+
targets,
|
|
408
|
+
minify: options.minify,
|
|
409
|
+
cssModules: options.cssModules,
|
|
410
|
+
resolver: {
|
|
411
|
+
async read(filePath) {
|
|
412
|
+
let fileCode;
|
|
413
|
+
if (code != null && filePath === filename) fileCode = code;
|
|
414
|
+
else fileCode = readFileSync(filePath, "utf8");
|
|
415
|
+
const lang = getPreprocessorLang(filePath);
|
|
416
|
+
if (lang) {
|
|
417
|
+
const preprocessed = await compilePreprocessor(lang, fileCode, filePath, options.preprocessorOptions);
|
|
418
|
+
deps.push(...preprocessed.deps);
|
|
419
|
+
return preprocessed.code;
|
|
420
|
+
}
|
|
421
|
+
return fileCode;
|
|
422
|
+
},
|
|
423
|
+
resolve(specifier, from) {
|
|
424
|
+
const resolved = resolveWithResolver(getCssResolver(), specifier, from);
|
|
425
|
+
if (!resolved) {
|
|
426
|
+
options.logger.warn(`[@tsdown/css] Failed to resolve import '${specifier}' from '${from}'`);
|
|
427
|
+
return path.resolve(path.dirname(from), specifier);
|
|
428
|
+
}
|
|
429
|
+
return resolved;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
});
|
|
433
|
+
return {
|
|
434
|
+
code: new TextDecoder().decode(result.code),
|
|
435
|
+
deps,
|
|
436
|
+
modules: result.exports ? extractLightningCssModuleExports(result.exports) : void 0
|
|
437
|
+
};
|
|
438
|
+
}
|
|
439
|
+
const TARGET_REGEX = /([a-z]+)(\d+(?:\.\d+)*)/g;
|
|
440
|
+
const ESBUILD_LIGHTNINGCSS_MAPPING = {
|
|
441
|
+
chrome: "chrome",
|
|
442
|
+
edge: "edge",
|
|
443
|
+
firefox: "firefox",
|
|
444
|
+
ie: "ie",
|
|
445
|
+
ios: "ios_saf",
|
|
446
|
+
opera: "opera",
|
|
447
|
+
safari: "safari"
|
|
448
|
+
};
|
|
449
|
+
function parseVersion(version) {
|
|
450
|
+
const [major, minor = 0, patch = 0] = version.split("-")[0].split(".").map((v) => Number.parseInt(v, 10));
|
|
451
|
+
if (Number.isNaN(major) || Number.isNaN(minor) || Number.isNaN(patch)) return null;
|
|
452
|
+
return major << 16 | minor << 8 | patch;
|
|
453
|
+
}
|
|
454
|
+
function esbuildTargetToLightningCSS(target) {
|
|
455
|
+
let targets;
|
|
456
|
+
const matches = [...target.join(" ").toLowerCase().matchAll(TARGET_REGEX)];
|
|
457
|
+
for (const match of matches) {
|
|
458
|
+
const browser = ESBUILD_LIGHTNINGCSS_MAPPING[match[1]];
|
|
459
|
+
if (!browser) continue;
|
|
460
|
+
const version = match[2];
|
|
461
|
+
const versionInt = parseVersion(version);
|
|
462
|
+
if (versionInt == null) continue;
|
|
463
|
+
targets = targets || {};
|
|
464
|
+
targets[browser] = versionInt;
|
|
465
|
+
}
|
|
466
|
+
return targets;
|
|
467
|
+
}
|
|
468
|
+
/**
|
|
469
|
+
* Detect and remove "pure CSS chunks" — JS chunks that exist only because
|
|
470
|
+
* they imported CSS files. These chunks have no JS exports and all their
|
|
471
|
+
* modules are CSS. Following Vite's implementation.
|
|
472
|
+
*/
|
|
473
|
+
function removePureCssChunks(bundle, styles) {
|
|
474
|
+
const pureCssChunkNames = [];
|
|
475
|
+
for (const chunk of Object.values(bundle)) {
|
|
476
|
+
if (chunk.type !== "chunk" || chunk.exports.length || !chunk.moduleIds.length) continue;
|
|
477
|
+
if (chunk.moduleIds.every((id) => styles.has(id))) pureCssChunkNames.push(chunk.fileName);
|
|
478
|
+
}
|
|
479
|
+
const strictSet = new Set(pureCssChunkNames);
|
|
480
|
+
for (const chunk of Object.values(bundle)) {
|
|
481
|
+
if (chunk.type !== "chunk" || chunk.exports.length || chunk.isEntry || chunk.isDynamicEntry) continue;
|
|
482
|
+
if (strictSet.has(chunk.fileName)) continue;
|
|
483
|
+
if (chunk.moduleIds.some((id) => styles.has(id)) && isEmptyChunkCode$1(chunk.code)) pureCssChunkNames.push(chunk.fileName);
|
|
484
|
+
}
|
|
485
|
+
if (!pureCssChunkNames.length) return;
|
|
486
|
+
const replaceEmptyChunk = getEmptyChunkReplacer(pureCssChunkNames);
|
|
487
|
+
for (const chunk of Object.values(bundle)) {
|
|
488
|
+
if (chunk.type !== "chunk") continue;
|
|
489
|
+
let chunkImportsPureCssChunk = false;
|
|
490
|
+
chunk.imports = chunk.imports.filter((importFile) => {
|
|
491
|
+
if (pureCssChunkNames.includes(importFile)) {
|
|
492
|
+
chunkImportsPureCssChunk = true;
|
|
493
|
+
return false;
|
|
494
|
+
}
|
|
495
|
+
return true;
|
|
496
|
+
});
|
|
497
|
+
if (chunkImportsPureCssChunk) chunk.code = replaceEmptyChunk(chunk.code);
|
|
498
|
+
}
|
|
499
|
+
for (const fileName of pureCssChunkNames) {
|
|
500
|
+
delete bundle[fileName];
|
|
501
|
+
delete bundle[`${fileName}.map`];
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
/**
|
|
505
|
+
* Create a replacer function that replaces import statements for pure CSS
|
|
506
|
+
* chunks with block comments of the same length, preserving source map offsets.
|
|
507
|
+
*/
|
|
508
|
+
function getEmptyChunkReplacer(pureCssChunkNames) {
|
|
509
|
+
const emptyChunkFiles = pureCssChunkNames.map((file) => escapeRegex(path.basename(file))).join("|");
|
|
510
|
+
const emptyChunkRE = new RegExp(String.raw`\bimport\s*["'][^"']*(?:${emptyChunkFiles})["'];`, "g");
|
|
511
|
+
return (code) => code.replace(emptyChunkRE, (m) => {
|
|
512
|
+
return `/* empty css ${"".padEnd(m.length - 15)}*/`;
|
|
513
|
+
});
|
|
514
|
+
}
|
|
515
|
+
function escapeRegex(str) {
|
|
516
|
+
return str.replaceAll(/[.*+?^${}()|[\]\\]/g, String.raw`\$&`);
|
|
517
|
+
}
|
|
518
|
+
function isEmptyChunkCode$1(code) {
|
|
519
|
+
return !code.replaceAll(/\/\*[\s\S]*?\*\//g, "").replaceAll(/\/\/[^\n]*/g, "").replaceAll(/\bexport\s*\{\s*\};?/g, "").replaceAll(/\bimport\s*["'][^"']*["'];?/g, "").trim();
|
|
520
|
+
}
|
|
521
|
+
function CssPostPlugin(config, styles) {
|
|
522
|
+
const collectedCSS = [];
|
|
523
|
+
async function finalizeCss(css) {
|
|
524
|
+
if (!config.minify) return css;
|
|
525
|
+
let code = (await transformWithLightningCSS(css, defaultCssBundleName, {
|
|
526
|
+
target: config.target,
|
|
527
|
+
lightningcss: config.lightningcss,
|
|
528
|
+
minify: true
|
|
529
|
+
})).code;
|
|
530
|
+
if (code.length && !code.endsWith("\n")) code += "\n";
|
|
531
|
+
return code;
|
|
532
|
+
}
|
|
533
|
+
return {
|
|
534
|
+
name: "tsdown:css-post",
|
|
535
|
+
renderChunk(_code, chunk) {
|
|
536
|
+
if (styles.size === 0) return;
|
|
537
|
+
if (config.splitting) return;
|
|
538
|
+
let chunkCSS = "";
|
|
539
|
+
for (const id of Object.keys(chunk.modules)) {
|
|
540
|
+
const code = styles.get(id);
|
|
541
|
+
if (code) chunkCSS += code;
|
|
542
|
+
}
|
|
543
|
+
if (!chunkCSS) return;
|
|
544
|
+
if (chunkCSS.length > 0 && !chunkCSS.endsWith("\n")) chunkCSS += "\n";
|
|
545
|
+
collectedCSS.push(chunkCSS);
|
|
546
|
+
},
|
|
547
|
+
async generateBundle(_outputOptions, bundle) {
|
|
548
|
+
if (config.splitting) for (const chunk of Object.values(bundle)) {
|
|
549
|
+
if (chunk.type !== "chunk") continue;
|
|
550
|
+
let chunkCSS = "";
|
|
551
|
+
for (const id of chunk.moduleIds) {
|
|
552
|
+
const code = styles.get(id);
|
|
553
|
+
if (code) chunkCSS += code;
|
|
554
|
+
}
|
|
555
|
+
if (!chunkCSS) continue;
|
|
556
|
+
if (!chunkCSS.endsWith("\n")) chunkCSS += "\n";
|
|
557
|
+
chunkCSS = await finalizeCss(chunkCSS);
|
|
558
|
+
const cssAssetFileName = toCssFileName(chunk.fileName);
|
|
559
|
+
this.emitFile({
|
|
560
|
+
type: "asset",
|
|
561
|
+
fileName: cssAssetFileName,
|
|
562
|
+
source: chunkCSS
|
|
563
|
+
});
|
|
564
|
+
}
|
|
565
|
+
else if (collectedCSS.length > 0) {
|
|
566
|
+
let allCSS = collectedCSS.join("");
|
|
567
|
+
if (allCSS) {
|
|
568
|
+
allCSS = await finalizeCss(allCSS);
|
|
569
|
+
this.emitFile({
|
|
570
|
+
type: "asset",
|
|
571
|
+
fileName: config.fileName,
|
|
572
|
+
source: allCSS,
|
|
573
|
+
originalFileName: defaultCssBundleName
|
|
574
|
+
});
|
|
575
|
+
}
|
|
576
|
+
collectedCSS.length = 0;
|
|
577
|
+
}
|
|
578
|
+
removePureCssChunks(bundle, styles);
|
|
579
|
+
}
|
|
580
|
+
};
|
|
581
|
+
}
|
|
582
|
+
const fileConfigCache = /* @__PURE__ */ new Map();
|
|
583
|
+
async function loadFileConfig(searchPath) {
|
|
584
|
+
const cached = fileConfigCache.get(searchPath);
|
|
585
|
+
if (cached !== void 0) return cached;
|
|
586
|
+
const promise = (async () => {
|
|
587
|
+
try {
|
|
588
|
+
const postcssrc = (await import("./src-njF8VL4a.js").then((m) => /* @__PURE__ */ __toESM(m.default, 1))).default;
|
|
589
|
+
const result = await postcssrc({}, searchPath);
|
|
590
|
+
return {
|
|
591
|
+
options: result.options,
|
|
592
|
+
plugins: result.plugins
|
|
593
|
+
};
|
|
594
|
+
} catch (error) {
|
|
595
|
+
if (error.message?.includes("No PostCSS Config found")) return null;
|
|
596
|
+
throw error;
|
|
597
|
+
}
|
|
598
|
+
})();
|
|
599
|
+
fileConfigCache.set(searchPath, promise);
|
|
600
|
+
const result = await promise;
|
|
601
|
+
fileConfigCache.set(searchPath, result);
|
|
602
|
+
return result;
|
|
603
|
+
}
|
|
604
|
+
function resolvePostCSSConfig(postcssOption, cwd) {
|
|
605
|
+
if (typeof postcssOption === "object") {
|
|
606
|
+
const { plugins, ...options } = postcssOption;
|
|
607
|
+
return {
|
|
608
|
+
options,
|
|
609
|
+
plugins: plugins || []
|
|
610
|
+
};
|
|
611
|
+
}
|
|
612
|
+
return loadFileConfig(typeof postcssOption === "string" ? postcssOption : cwd);
|
|
613
|
+
}
|
|
614
|
+
async function processWithPostCSS$1(code, filename, postcssOption, cwd, injectImport, modulesOptions) {
|
|
615
|
+
const config = await resolvePostCSSConfig(postcssOption, cwd);
|
|
616
|
+
const plugins = [];
|
|
617
|
+
let modules;
|
|
618
|
+
if (modulesOptions?.isModule) {
|
|
619
|
+
const postcssModules = await importWithError("postcss-modules");
|
|
620
|
+
const { localsConvention: _, getJSON: userGetJSON, ...rest } = modulesOptions.config ?? {};
|
|
621
|
+
plugins.push((postcssModules.default ?? postcssModules)({
|
|
622
|
+
...rest,
|
|
623
|
+
getJSON(cssFileName, json, outputFileName) {
|
|
624
|
+
modules = json;
|
|
625
|
+
userGetJSON?.(cssFileName, json, outputFileName);
|
|
626
|
+
}
|
|
627
|
+
}));
|
|
628
|
+
}
|
|
629
|
+
if (injectImport) {
|
|
630
|
+
const postcssImport = await importWithError("postcss-import");
|
|
631
|
+
plugins.push((postcssImport.default ?? postcssImport)());
|
|
632
|
+
}
|
|
633
|
+
if (config) plugins.push(...config.plugins);
|
|
634
|
+
if (!plugins.length && !config?.options.parser) return {
|
|
635
|
+
code,
|
|
636
|
+
deps: []
|
|
637
|
+
};
|
|
638
|
+
const result = await (await importWithError("postcss")).default(plugins).process(code, {
|
|
639
|
+
...config?.options,
|
|
640
|
+
from: filename,
|
|
641
|
+
to: filename
|
|
642
|
+
});
|
|
643
|
+
const deps = [];
|
|
644
|
+
for (const message of result.messages) if (message.type === "dependency") deps.push(message.file);
|
|
645
|
+
else if (message.type === "dir-dependency") {
|
|
646
|
+
const { dir } = message;
|
|
647
|
+
if (typeof dir === "string") deps.push(dir);
|
|
648
|
+
}
|
|
649
|
+
return {
|
|
650
|
+
code: result.css,
|
|
651
|
+
deps,
|
|
652
|
+
modules
|
|
653
|
+
};
|
|
654
|
+
}
|
|
655
|
+
function shouldSkipTransform(id, cleanId) {
|
|
656
|
+
const isInline = RE_INLINE.test(id);
|
|
657
|
+
return id !== cleanId && !isInline && CSS_LANGS_RE.test(cleanId);
|
|
658
|
+
}
|
|
659
|
+
function CssPlugin(config, { logger }) {
|
|
660
|
+
const cssConfig = {
|
|
661
|
+
css: resolveCssOptions(config.css, config.target, config.unbundle),
|
|
662
|
+
cwd: config.cwd,
|
|
663
|
+
target: config.target
|
|
664
|
+
};
|
|
665
|
+
const styles = /* @__PURE__ */ new Map();
|
|
666
|
+
const modulesMap = /* @__PURE__ */ new Map();
|
|
667
|
+
const cssCompilePlugin = {
|
|
668
|
+
name: "@tsdown/css",
|
|
669
|
+
buildStart() {
|
|
670
|
+
styles.clear();
|
|
671
|
+
modulesMap.clear();
|
|
672
|
+
},
|
|
673
|
+
resolveId: {
|
|
674
|
+
filter: { id: RE_CSS_INLINE },
|
|
675
|
+
async handler(source, ...args) {
|
|
676
|
+
const cleanSource = getCleanId(source);
|
|
677
|
+
const resolved = await this.resolve(cleanSource, ...args);
|
|
678
|
+
if (resolved) return {
|
|
679
|
+
...resolved,
|
|
680
|
+
id: `${resolved.id}?inline`
|
|
681
|
+
};
|
|
682
|
+
}
|
|
683
|
+
},
|
|
684
|
+
load: {
|
|
685
|
+
filter: { id: RE_CSS_INLINE },
|
|
686
|
+
async handler(id) {
|
|
687
|
+
const cleanId = getCleanId(id);
|
|
688
|
+
if (styles.has(id)) return;
|
|
689
|
+
const code = await readFile(cleanId, "utf8").catch(() => null);
|
|
690
|
+
if (code == null) return;
|
|
691
|
+
this.addWatchFile(cleanId);
|
|
692
|
+
return {
|
|
693
|
+
code,
|
|
694
|
+
moduleType: "js"
|
|
695
|
+
};
|
|
696
|
+
}
|
|
697
|
+
},
|
|
698
|
+
transform: {
|
|
699
|
+
filter: { id: CSS_LANGS_RE },
|
|
700
|
+
async handler(code, id) {
|
|
701
|
+
const cleanId = getCleanId(id);
|
|
702
|
+
if (shouldSkipTransform(id, cleanId)) return;
|
|
703
|
+
const isModule = !RE_INLINE.test(id) && cssConfig.css.modules !== false && CSS_MODULE_RE.test(id);
|
|
704
|
+
const deps = [];
|
|
705
|
+
let modules;
|
|
706
|
+
if (cssConfig.css.transformer === "lightningcss") {
|
|
707
|
+
const result = await processWithLightningCSS(code, id, cleanId, deps, cssConfig, logger, isModule);
|
|
708
|
+
code = result.code;
|
|
709
|
+
modules = result.modules;
|
|
710
|
+
} else {
|
|
711
|
+
const result = await processWithPostCSS(code, id, cleanId, deps, cssConfig, isModule);
|
|
712
|
+
code = result.code;
|
|
713
|
+
modules = result.modules;
|
|
714
|
+
}
|
|
715
|
+
for (const dep of deps) this.addWatchFile(dep);
|
|
716
|
+
if (code.length && !code.endsWith("\n")) code += "\n";
|
|
717
|
+
if (modules) {
|
|
718
|
+
const modulesConfig = typeof cssConfig.css.modules === "object" ? cssConfig.css.modules : void 0;
|
|
719
|
+
if (modulesConfig?.localsConvention) modules = applyLocalsConvention(modules, modulesConfig.localsConvention);
|
|
720
|
+
modulesConfig?.getJSON?.(cleanId, modules, cleanId);
|
|
721
|
+
modulesMap.set(id, modules);
|
|
722
|
+
}
|
|
723
|
+
return { code };
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
};
|
|
727
|
+
const postPlugins = [{
|
|
728
|
+
name: "@tsdown/css:collect",
|
|
729
|
+
transform: {
|
|
730
|
+
filter: { id: CSS_LANGS_RE },
|
|
731
|
+
handler(code, id) {
|
|
732
|
+
if (shouldSkipTransform(id, getCleanId(id))) return;
|
|
733
|
+
const isInline = RE_INLINE.test(id);
|
|
734
|
+
const modules = modulesMap.get(id);
|
|
735
|
+
if (isInline) return {
|
|
736
|
+
code: `export default ${JSON.stringify(code)};`,
|
|
737
|
+
moduleSideEffects: false,
|
|
738
|
+
moduleType: "js"
|
|
739
|
+
};
|
|
740
|
+
if (code.length) styles.set(id, code);
|
|
741
|
+
if (modules) return {
|
|
742
|
+
code: modulesToEsm(modules),
|
|
743
|
+
moduleSideEffects: false,
|
|
744
|
+
moduleType: "js"
|
|
745
|
+
};
|
|
746
|
+
return {
|
|
747
|
+
code: "",
|
|
748
|
+
moduleSideEffects: "no-treeshake",
|
|
749
|
+
moduleType: "js"
|
|
750
|
+
};
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
}];
|
|
754
|
+
if (cssConfig.css.inject) postPlugins.push({
|
|
755
|
+
name: "@tsdown/css:inject",
|
|
756
|
+
generateBundle(_outputOptions, bundle) {
|
|
757
|
+
const chunks = Object.values(bundle);
|
|
758
|
+
const pureCssChunks = /* @__PURE__ */ new Set();
|
|
759
|
+
for (const chunk of chunks) {
|
|
760
|
+
if (chunk.type !== "chunk" || chunk.exports.length || !chunk.moduleIds.length) continue;
|
|
761
|
+
if (chunk.moduleIds.every((id) => styles.has(id))) {
|
|
762
|
+
pureCssChunks.add(chunk.fileName);
|
|
763
|
+
continue;
|
|
764
|
+
}
|
|
765
|
+
if (!chunk.isEntry && !chunk.isDynamicEntry && chunk.moduleIds.some((id) => styles.has(id)) && isEmptyChunkCode(chunk.code)) pureCssChunks.add(chunk.fileName);
|
|
766
|
+
}
|
|
767
|
+
for (const chunk of chunks) {
|
|
768
|
+
if (chunk.type !== "chunk") continue;
|
|
769
|
+
if (pureCssChunks.has(chunk.fileName)) continue;
|
|
770
|
+
if (cssConfig.css.splitting) {
|
|
771
|
+
for (const imp of chunk.imports) {
|
|
772
|
+
if (!pureCssChunks.has(imp)) continue;
|
|
773
|
+
const basename = path.basename(imp);
|
|
774
|
+
const escaped = basename.replaceAll(/[.*+?^${}()|[\]\\]/g, String.raw`\$&`);
|
|
775
|
+
const cssBasename = toCssFileName(basename);
|
|
776
|
+
const importRE = new RegExp(String.raw`(\bimport\s*["'][^"']*)${escaped}(["'];)`);
|
|
777
|
+
chunk.code = chunk.code.replace(importRE, `$1${cssBasename}$2`);
|
|
778
|
+
}
|
|
779
|
+
if (chunk.moduleIds.some((id) => styles.has(id))) {
|
|
780
|
+
const cssFile = toCssFileName(chunk.fileName);
|
|
781
|
+
const relativePath = path.posix.relative(path.posix.dirname(chunk.fileName), cssFile);
|
|
782
|
+
chunk.code = `import '${relativePath[0] === "." ? relativePath : `./${relativePath}`}';\n${chunk.code}`;
|
|
783
|
+
if (chunk.map) chunk.map.mappings = `;${chunk.map.mappings}`;
|
|
784
|
+
}
|
|
785
|
+
} else if (chunk.moduleIds.some((id) => styles.has(id)) || chunk.imports.some((imp) => pureCssChunks.has(imp))) {
|
|
786
|
+
const cssFile = cssConfig.css.fileName;
|
|
787
|
+
const relativePath = path.posix.relative(path.posix.dirname(chunk.fileName), cssFile);
|
|
788
|
+
chunk.code = `import '${relativePath[0] === "." ? relativePath : `./${relativePath}`}';\n${chunk.code}`;
|
|
789
|
+
if (chunk.map) chunk.map.mappings = `;${chunk.map.mappings}`;
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
});
|
|
794
|
+
postPlugins.push(CssPostPlugin(cssConfig.css, styles));
|
|
795
|
+
return {
|
|
796
|
+
pre: [cssCompilePlugin],
|
|
797
|
+
post: postPlugins
|
|
798
|
+
};
|
|
799
|
+
}
|
|
800
|
+
function resolveCssModulesConfig(modulesOptions, isModule, logger) {
|
|
801
|
+
if (!isModule) return void 0;
|
|
802
|
+
const config = typeof modulesOptions === "object" ? modulesOptions : void 0;
|
|
803
|
+
if (!config) return true;
|
|
804
|
+
const cssModulesConfig = {};
|
|
805
|
+
if (typeof config.generateScopedName === "string") cssModulesConfig.pattern = config.generateScopedName;
|
|
806
|
+
else if (typeof config.generateScopedName === "function") logger.warn("[@tsdown/css] `generateScopedName` as a function is not supported with `transformer: \"lightningcss\"`. Use a string pattern or switch to `transformer: \"postcss\"`.");
|
|
807
|
+
if (config.scopeBehaviour === "global") cssModulesConfig.pattern = "[local]";
|
|
808
|
+
return Object.keys(cssModulesConfig).length > 0 ? cssModulesConfig : true;
|
|
809
|
+
}
|
|
810
|
+
async function processWithLightningCSS(code, id, cleanId, deps, config, logger, isModule) {
|
|
811
|
+
const lang = getPreprocessorLangFromId(id);
|
|
812
|
+
const cssModules = resolveCssModulesConfig(config.css.modules, isModule, logger);
|
|
813
|
+
if (lang) {
|
|
814
|
+
const preResult = await compilePreprocessor(lang, code, cleanId, config.css.preprocessorOptions);
|
|
815
|
+
deps.push(...preResult.deps);
|
|
816
|
+
return transformWithLightningCSS(preResult.code, cleanId, {
|
|
817
|
+
target: config.css.target,
|
|
818
|
+
lightningcss: config.css.lightningcss,
|
|
819
|
+
minify: config.css.minify,
|
|
820
|
+
cssModules
|
|
821
|
+
});
|
|
822
|
+
}
|
|
823
|
+
if (id !== cleanId && !RE_INLINE.test(id)) return transformWithLightningCSS(code, cleanId, {
|
|
824
|
+
target: config.css.target,
|
|
825
|
+
lightningcss: config.css.lightningcss,
|
|
826
|
+
minify: config.css.minify,
|
|
827
|
+
cssModules
|
|
828
|
+
});
|
|
829
|
+
if (RE_CSS.test(cleanId)) {
|
|
830
|
+
const bundleResult = await bundleWithLightningCSS(cleanId, {
|
|
831
|
+
target: config.css.target,
|
|
832
|
+
lightningcss: config.css.lightningcss,
|
|
833
|
+
minify: config.css.minify,
|
|
834
|
+
cssModules,
|
|
835
|
+
preprocessorOptions: config.css.preprocessorOptions,
|
|
836
|
+
logger
|
|
837
|
+
}, code);
|
|
838
|
+
deps.push(...bundleResult.deps);
|
|
839
|
+
return {
|
|
840
|
+
code: bundleResult.code,
|
|
841
|
+
modules: bundleResult.modules
|
|
842
|
+
};
|
|
843
|
+
}
|
|
844
|
+
return { code: "" };
|
|
845
|
+
}
|
|
846
|
+
async function processWithPostCSS(code, id, cleanId, deps, config, isModule) {
|
|
847
|
+
const lang = getPreprocessorLangFromId(id);
|
|
848
|
+
if (lang) {
|
|
849
|
+
const preResult = await compilePreprocessor(lang, code, cleanId, config.css.preprocessorOptions);
|
|
850
|
+
code = preResult.code;
|
|
851
|
+
deps.push(...preResult.deps);
|
|
852
|
+
}
|
|
853
|
+
const modulesConfig = typeof config.css.modules === "object" ? config.css.modules : void 0;
|
|
854
|
+
const needInlineImport = code.includes("@import");
|
|
855
|
+
const postcssResult = await processWithPostCSS$1(code, cleanId, config.css.postcss, config.cwd, needInlineImport, isModule ? {
|
|
856
|
+
isModule: true,
|
|
857
|
+
config: modulesConfig
|
|
858
|
+
} : void 0);
|
|
859
|
+
code = postcssResult.code;
|
|
860
|
+
deps.push(...postcssResult.deps);
|
|
861
|
+
return {
|
|
862
|
+
code: (await transformWithLightningCSS(code, cleanId, {
|
|
863
|
+
target: config.css.target,
|
|
864
|
+
lightningcss: config.css.lightningcss,
|
|
865
|
+
minify: config.css.minify
|
|
866
|
+
})).code,
|
|
867
|
+
modules: postcssResult.modules
|
|
868
|
+
};
|
|
869
|
+
}
|
|
870
|
+
function isEmptyChunkCode(code) {
|
|
871
|
+
return !code.replaceAll(/\/\*[\s\S]*?\*\//g, "").replaceAll(/\/\/[^\n]*/g, "").replaceAll(/\bexport\s*\{\s*\};?/g, "").replaceAll(/\bimport\s*["'][^"']*["'];?/g, "").trim();
|
|
872
|
+
}
|
|
873
|
+
//#endregion
|
|
874
|
+
export { CssPlugin, resolveCssOptions };
|