@nasti-toolchain/nasti 1.6.5 → 1.7.1
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/README.md +25 -0
- package/dist/cli.cjs +220 -22
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +220 -22
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +258 -60
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +22 -2
- package/dist/index.d.ts +22 -2
- package/dist/index.js +258 -60
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1567,6 +1567,17 @@ function resolvePlugin(config) {
|
|
|
1567
1567
|
const aliasEntries = Object.entries(alias).sort(
|
|
1568
1568
|
([a], [b]) => b.length - a.length
|
|
1569
1569
|
);
|
|
1570
|
+
let vueRuntimeEntry = null;
|
|
1571
|
+
if (config.framework === "vue") {
|
|
1572
|
+
try {
|
|
1573
|
+
const vuePkgJson = require2.resolve("vue/package.json", { paths: [config.root] });
|
|
1574
|
+
const vueDir = path6.dirname(vuePkgJson);
|
|
1575
|
+
const mod = JSON.parse(fs6.readFileSync(vuePkgJson, "utf-8")).module;
|
|
1576
|
+
const entry = path6.join(vueDir, mod ?? "dist/vue.runtime.esm-bundler.js");
|
|
1577
|
+
if (fs6.existsSync(entry)) vueRuntimeEntry = entry;
|
|
1578
|
+
} catch {
|
|
1579
|
+
}
|
|
1580
|
+
}
|
|
1570
1581
|
return {
|
|
1571
1582
|
name: "nasti:resolve",
|
|
1572
1583
|
enforce: "pre",
|
|
@@ -1597,6 +1608,7 @@ function resolvePlugin(config) {
|
|
|
1597
1608
|
if (resolved) return resolved;
|
|
1598
1609
|
}
|
|
1599
1610
|
if (!source.startsWith("/") && !source.startsWith(".")) {
|
|
1611
|
+
if (vueRuntimeEntry && source === "vue") return vueRuntimeEntry;
|
|
1600
1612
|
try {
|
|
1601
1613
|
const resolved = require2.resolve(source, {
|
|
1602
1614
|
paths: [importer ? path6.dirname(importer) : config.root]
|
|
@@ -1681,15 +1693,15 @@ async function loadTailwind(projectRoot) {
|
|
|
1681
1693
|
async function compileTailwind(css, fromFile, projectRoot) {
|
|
1682
1694
|
const { node, oxide } = await loadTailwind(projectRoot);
|
|
1683
1695
|
const dependencies = [];
|
|
1684
|
-
const
|
|
1696
|
+
const compiler2 = await node.compile(css, {
|
|
1685
1697
|
base: path7.dirname(fromFile),
|
|
1686
1698
|
from: fromFile,
|
|
1687
1699
|
onDependency: (p) => dependencies.push(p)
|
|
1688
1700
|
});
|
|
1689
|
-
const scanner = new oxide.Scanner({ sources:
|
|
1701
|
+
const scanner = new oxide.Scanner({ sources: compiler2.sources });
|
|
1690
1702
|
const candidates = scanner.scan();
|
|
1691
1703
|
return {
|
|
1692
|
-
css:
|
|
1704
|
+
css: compiler2.build(candidates),
|
|
1693
1705
|
dependencies: [...dependencies, ...scanner.files]
|
|
1694
1706
|
};
|
|
1695
1707
|
}
|
|
@@ -1871,6 +1883,178 @@ var init_assets = __esm({
|
|
|
1871
1883
|
}
|
|
1872
1884
|
});
|
|
1873
1885
|
|
|
1886
|
+
// src/plugins/vue.ts
|
|
1887
|
+
import crypto2 from "crypto";
|
|
1888
|
+
async function loadVueCompiler() {
|
|
1889
|
+
if (compiler) return compiler;
|
|
1890
|
+
try {
|
|
1891
|
+
compiler = await import("@vue/compiler-sfc");
|
|
1892
|
+
return compiler;
|
|
1893
|
+
} catch {
|
|
1894
|
+
return null;
|
|
1895
|
+
}
|
|
1896
|
+
}
|
|
1897
|
+
function vuePlugin(config) {
|
|
1898
|
+
const isDev = config.command === "serve";
|
|
1899
|
+
const descriptorCache = /* @__PURE__ */ new Map();
|
|
1900
|
+
return {
|
|
1901
|
+
name: "nasti:vue",
|
|
1902
|
+
enforce: "pre",
|
|
1903
|
+
async resolveId(source) {
|
|
1904
|
+
if (VUE_QUERY_RE.test(source)) {
|
|
1905
|
+
return source;
|
|
1906
|
+
}
|
|
1907
|
+
return null;
|
|
1908
|
+
},
|
|
1909
|
+
async transform(code, id) {
|
|
1910
|
+
if (!VUE_FILE_RE.test(id) && !VUE_QUERY_RE.test(id)) return null;
|
|
1911
|
+
const sfc = await loadVueCompiler();
|
|
1912
|
+
if (!sfc) {
|
|
1913
|
+
console.warn("[nasti:vue] @vue/compiler-sfc not found. Install it: npm install @vue/compiler-sfc");
|
|
1914
|
+
return null;
|
|
1915
|
+
}
|
|
1916
|
+
if (VUE_QUERY_RE.test(id)) {
|
|
1917
|
+
return handleVueSubBlock(id, sfc, descriptorCache, config);
|
|
1918
|
+
}
|
|
1919
|
+
const { descriptor, errors } = sfc.parse(code, { filename: id });
|
|
1920
|
+
if (errors.length) {
|
|
1921
|
+
console.error(`[nasti:vue] Parse error in ${id}:`, errors[0].message);
|
|
1922
|
+
return null;
|
|
1923
|
+
}
|
|
1924
|
+
descriptorCache.set(id, descriptor);
|
|
1925
|
+
const scopeId = hashId(id);
|
|
1926
|
+
let scriptCode = "";
|
|
1927
|
+
if (descriptor.script || descriptor.scriptSetup) {
|
|
1928
|
+
const compiled = sfc.compileScript(descriptor, {
|
|
1929
|
+
id: scopeId,
|
|
1930
|
+
isProd: !isDev,
|
|
1931
|
+
inlineTemplate: true,
|
|
1932
|
+
// 让 compileScript 产出 `const __sfc__ = ...`(而非默认的 `export default {...}`)。
|
|
1933
|
+
// 否则下方追加的 `__sfc__.render` / `__sfc__.__scopeId` / HMR 记录会引用一个
|
|
1934
|
+
// 不存在的 `__sfc__`,并与 compileScript 自带的 `export default` 形成双重默认导出。
|
|
1935
|
+
genDefaultAs: "__sfc__"
|
|
1936
|
+
});
|
|
1937
|
+
scriptCode = compiled.content;
|
|
1938
|
+
}
|
|
1939
|
+
let templateCode = "";
|
|
1940
|
+
if (descriptor.template && !descriptor.scriptSetup) {
|
|
1941
|
+
const compiled = sfc.compileTemplate({
|
|
1942
|
+
source: descriptor.template.content,
|
|
1943
|
+
filename: id,
|
|
1944
|
+
id: scopeId,
|
|
1945
|
+
compilerOptions: { scopeId: `data-v-${scopeId}` }
|
|
1946
|
+
});
|
|
1947
|
+
templateCode = compiled.code;
|
|
1948
|
+
}
|
|
1949
|
+
let output = scriptCode || "const __sfc__ = {}";
|
|
1950
|
+
if (templateCode) {
|
|
1951
|
+
output += `
|
|
1952
|
+
${templateCode}
|
|
1953
|
+
`;
|
|
1954
|
+
output += `
|
|
1955
|
+
__sfc__.render = render
|
|
1956
|
+
`;
|
|
1957
|
+
}
|
|
1958
|
+
if (descriptor.styles.length > 0) {
|
|
1959
|
+
for (let i = 0; i < descriptor.styles.length; i++) {
|
|
1960
|
+
const style = descriptor.styles[i];
|
|
1961
|
+
const lang2 = style.lang ?? "css";
|
|
1962
|
+
output += `
|
|
1963
|
+
import "${id}?vue&type=style&index=${i}&lang=${lang2}"
|
|
1964
|
+
`;
|
|
1965
|
+
}
|
|
1966
|
+
}
|
|
1967
|
+
output += `
|
|
1968
|
+
__sfc__.__scopeId = "data-v-${scopeId}"
|
|
1969
|
+
`;
|
|
1970
|
+
if (isDev) {
|
|
1971
|
+
output += `
|
|
1972
|
+
__sfc__.__hmrId = ${JSON.stringify(scopeId)}
|
|
1973
|
+
if (typeof __VUE_HMR_RUNTIME__ !== 'undefined') {
|
|
1974
|
+
__VUE_HMR_RUNTIME__.createRecord(__sfc__.__hmrId, __sfc__)
|
|
1975
|
+
}
|
|
1976
|
+
if (import.meta.hot) {
|
|
1977
|
+
import.meta.hot.accept((mod) => {
|
|
1978
|
+
if (!mod) return
|
|
1979
|
+
const { default: updated } = mod
|
|
1980
|
+
if (typeof __VUE_HMR_RUNTIME__ !== 'undefined') {
|
|
1981
|
+
__VUE_HMR_RUNTIME__.rerender(updated.__hmrId, updated.render)
|
|
1982
|
+
}
|
|
1983
|
+
})
|
|
1984
|
+
}
|
|
1985
|
+
`;
|
|
1986
|
+
}
|
|
1987
|
+
output += `
|
|
1988
|
+
export default __sfc__
|
|
1989
|
+
`;
|
|
1990
|
+
const lang = descriptor.scriptSetup?.lang ?? descriptor.script?.lang;
|
|
1991
|
+
if (lang === "ts") {
|
|
1992
|
+
const transpiled = transformCode(`${id}.ts`, output, { sourcemap: false });
|
|
1993
|
+
return { code: transpiled.code };
|
|
1994
|
+
}
|
|
1995
|
+
return { code: output };
|
|
1996
|
+
},
|
|
1997
|
+
handleHotUpdate(ctx) {
|
|
1998
|
+
const { file, modules } = ctx;
|
|
1999
|
+
if (VUE_FILE_RE.test(file)) {
|
|
2000
|
+
for (const mod of modules) {
|
|
2001
|
+
mod.isSelfAccepting = true;
|
|
2002
|
+
}
|
|
2003
|
+
descriptorCache.delete(file);
|
|
2004
|
+
}
|
|
2005
|
+
return modules;
|
|
2006
|
+
}
|
|
2007
|
+
};
|
|
2008
|
+
}
|
|
2009
|
+
async function handleVueSubBlock(id, sfc, cache, config) {
|
|
2010
|
+
const match = id.match(/(.+\.vue)\?vue&type=(\w+)(?:&index=(\d+))?(?:&lang=(\w+))?/);
|
|
2011
|
+
if (!match) return null;
|
|
2012
|
+
const [, filePath, type, indexStr, lang] = match;
|
|
2013
|
+
const descriptor = cache.get(filePath);
|
|
2014
|
+
if (!descriptor) return null;
|
|
2015
|
+
if (type === "style") {
|
|
2016
|
+
const index = parseInt(indexStr ?? "0", 10);
|
|
2017
|
+
const style = descriptor.styles[index];
|
|
2018
|
+
if (!style) return null;
|
|
2019
|
+
const scopeId = hashId(filePath);
|
|
2020
|
+
const result = await sfc.compileStyleAsync({
|
|
2021
|
+
source: style.content,
|
|
2022
|
+
filename: filePath,
|
|
2023
|
+
id: `data-v-${scopeId}`,
|
|
2024
|
+
scoped: style.scoped ?? false
|
|
2025
|
+
});
|
|
2026
|
+
const cssCode = JSON.stringify(result.code);
|
|
2027
|
+
return {
|
|
2028
|
+
code: `
|
|
2029
|
+
const css = ${cssCode};
|
|
2030
|
+
const style = document.createElement('style');
|
|
2031
|
+
style.setAttribute('data-v-${scopeId}', '');
|
|
2032
|
+
style.textContent = css;
|
|
2033
|
+
document.head.appendChild(style);
|
|
2034
|
+
|
|
2035
|
+
if (import.meta.hot) {
|
|
2036
|
+
import.meta.hot.accept();
|
|
2037
|
+
import.meta.hot.prune(() => style.remove());
|
|
2038
|
+
}
|
|
2039
|
+
`
|
|
2040
|
+
};
|
|
2041
|
+
}
|
|
2042
|
+
return null;
|
|
2043
|
+
}
|
|
2044
|
+
function hashId(filename) {
|
|
2045
|
+
return crypto2.createHash("sha256").update(filename).digest("hex").slice(0, 8);
|
|
2046
|
+
}
|
|
2047
|
+
var VUE_FILE_RE, VUE_QUERY_RE, compiler;
|
|
2048
|
+
var init_vue = __esm({
|
|
2049
|
+
"src/plugins/vue.ts"() {
|
|
2050
|
+
"use strict";
|
|
2051
|
+
init_transformer();
|
|
2052
|
+
VUE_FILE_RE = /\.vue$/;
|
|
2053
|
+
VUE_QUERY_RE = /\.vue\?vue&type=(script|template|style)(&index=\d+)?(&lang=\w+)?/;
|
|
2054
|
+
compiler = null;
|
|
2055
|
+
}
|
|
2056
|
+
});
|
|
2057
|
+
|
|
1874
2058
|
// src/server/index.ts
|
|
1875
2059
|
var server_exports = {};
|
|
1876
2060
|
__export(server_exports, {
|
|
@@ -1886,6 +2070,7 @@ import pc from "picocolors";
|
|
|
1886
2070
|
async function createServer(inlineConfig = {}) {
|
|
1887
2071
|
const config = await resolveConfig(inlineConfig, "serve");
|
|
1888
2072
|
const allPlugins = [
|
|
2073
|
+
...config.framework === "vue" ? [vuePlugin(config)] : [],
|
|
1889
2074
|
resolvePlugin(config),
|
|
1890
2075
|
cssPlugin(config),
|
|
1891
2076
|
assetsPlugin(config),
|
|
@@ -1946,7 +2131,7 @@ async function createServer(inlineConfig = {}) {
|
|
|
1946
2131
|
const localUrl = `http://localhost:${actualPort}`;
|
|
1947
2132
|
const networkUrl = host === "0.0.0.0" ? `http://${getNetworkAddress()}:${actualPort}` : null;
|
|
1948
2133
|
console.log();
|
|
1949
|
-
console.log(pc.cyan(" nasti dev server") + pc.dim(` v${"1.
|
|
2134
|
+
console.log(pc.cyan(" nasti dev server") + pc.dim(` v${"1.7.1"}`));
|
|
1950
2135
|
console.log();
|
|
1951
2136
|
console.log(` ${pc.green(">")} Local: ${pc.cyan(localUrl)}`);
|
|
1952
2137
|
if (networkUrl) {
|
|
@@ -2014,6 +2199,7 @@ var init_server = __esm({
|
|
|
2014
2199
|
init_resolve();
|
|
2015
2200
|
init_css();
|
|
2016
2201
|
init_assets();
|
|
2202
|
+
init_vue();
|
|
2017
2203
|
init_html();
|
|
2018
2204
|
}
|
|
2019
2205
|
});
|
|
@@ -2069,7 +2255,7 @@ import pc2 from "picocolors";
|
|
|
2069
2255
|
async function build(inlineConfig = {}) {
|
|
2070
2256
|
const config = await resolveConfig(inlineConfig, "build");
|
|
2071
2257
|
const startTime = performance.now();
|
|
2072
|
-
console.log(pc2.cyan("\n\u{1F528} nasti build") + pc2.dim(` v${"1.
|
|
2258
|
+
console.log(pc2.cyan("\n\u{1F528} nasti build") + pc2.dim(` v${"1.7.1"}`));
|
|
2073
2259
|
console.log(pc2.dim(` root: ${config.root}`));
|
|
2074
2260
|
console.log(pc2.dim(` mode: ${config.mode}`));
|
|
2075
2261
|
const outDir = path11.resolve(config.root, config.build.outDir);
|
|
@@ -2102,6 +2288,7 @@ async function build(inlineConfig = {}) {
|
|
|
2102
2288
|
throw new Error("No entry point found. Add a <script> tag to index.html or create src/main.ts");
|
|
2103
2289
|
}
|
|
2104
2290
|
const builtinPlugins = [
|
|
2291
|
+
...config.framework === "vue" ? [vuePlugin(config)] : [],
|
|
2105
2292
|
resolvePlugin(config),
|
|
2106
2293
|
cssPlugin(config),
|
|
2107
2294
|
assetsPlugin(config)
|
|
@@ -2123,11 +2310,17 @@ async function build(inlineConfig = {}) {
|
|
|
2123
2310
|
};
|
|
2124
2311
|
const env = loadEnv(config.mode, config.root, config.envPrefix);
|
|
2125
2312
|
const envDefine = buildEnvDefine(env, config.mode);
|
|
2126
|
-
const
|
|
2127
|
-
const
|
|
2313
|
+
const { output: userOutput, transform: userTransform, ...restInputOptions } = config.build.rolldownOptions;
|
|
2314
|
+
const vueDefine = config.framework === "vue" ? {
|
|
2315
|
+
__VUE_OPTIONS_API__: "true",
|
|
2316
|
+
__VUE_PROD_DEVTOOLS__: "false",
|
|
2317
|
+
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: "false"
|
|
2318
|
+
} : {};
|
|
2319
|
+
const mergedDefine = { ...vueDefine, ...userTransform?.define ?? {}, ...envDefine };
|
|
2128
2320
|
const bundle = await rolldown({
|
|
2321
|
+
...restInputOptions,
|
|
2129
2322
|
input: entryPoints,
|
|
2130
|
-
transform: { ...
|
|
2323
|
+
transform: { ...userTransform, define: mergedDefine },
|
|
2131
2324
|
plugins: [
|
|
2132
2325
|
oxcTransformPlugin,
|
|
2133
2326
|
// 转换 Nasti 插件为 Rolldown 插件格式
|
|
@@ -2143,17 +2336,19 @@ async function build(inlineConfig = {}) {
|
|
|
2143
2336
|
// manifest/SW writers) rely on for final-stage artifact emission.
|
|
2144
2337
|
closeBundle: p.closeBundle
|
|
2145
2338
|
}))
|
|
2146
|
-
]
|
|
2147
|
-
...config.build.rolldownOptions
|
|
2339
|
+
]
|
|
2148
2340
|
});
|
|
2149
2341
|
const { output } = await bundle.write({
|
|
2150
|
-
dir: outDir,
|
|
2151
2342
|
format: "esm",
|
|
2152
2343
|
sourcemap: !!config.build.sourcemap,
|
|
2153
2344
|
minify: !!config.build.minify,
|
|
2154
2345
|
entryFileNames: "assets/[name].[hash].js",
|
|
2155
2346
|
chunkFileNames: "assets/[name].[hash].js",
|
|
2156
|
-
assetFileNames: "assets/[name].[hash][extname]"
|
|
2347
|
+
assetFileNames: "assets/[name].[hash][extname]",
|
|
2348
|
+
// 用户可覆盖默认输出:代码拆分(advancedChunks / codeSplitting)、chunk 命名等
|
|
2349
|
+
...userOutput,
|
|
2350
|
+
// dir 始终由 Nasti 掌管 —— 下方 HTML 改写依赖固定的产物目录,故放在最后强制生效
|
|
2351
|
+
dir: outDir
|
|
2157
2352
|
});
|
|
2158
2353
|
await bundle.close();
|
|
2159
2354
|
await pluginContainer.buildEnd();
|
|
@@ -2213,6 +2408,7 @@ var init_build = __esm({
|
|
|
2213
2408
|
init_resolve();
|
|
2214
2409
|
init_css();
|
|
2215
2410
|
init_assets();
|
|
2411
|
+
init_vue();
|
|
2216
2412
|
init_html();
|
|
2217
2413
|
init_transformer();
|
|
2218
2414
|
init_env();
|
|
@@ -2235,7 +2431,7 @@ async function buildElectron(inlineConfig = {}) {
|
|
|
2235
2431
|
const config = await resolveConfig({ ...inlineConfig, target: "electron" }, "build");
|
|
2236
2432
|
const startTime = performance.now();
|
|
2237
2433
|
assertElectronVersion(config);
|
|
2238
|
-
console.log(pc3.cyan("\n\u26A1 nasti build (electron)") + pc3.dim(` v${"1.
|
|
2434
|
+
console.log(pc3.cyan("\n\u26A1 nasti build (electron)") + pc3.dim(` v${"1.7.1"}`));
|
|
2239
2435
|
console.log(pc3.dim(` root: ${config.root}`));
|
|
2240
2436
|
console.log(pc3.dim(` mode: ${config.mode}`));
|
|
2241
2437
|
console.log(pc3.dim(` target: electron (\u2265 ${config.electron.minVersion})`));
|
|
@@ -2313,21 +2509,23 @@ async function bundleNode(config, entry, opts) {
|
|
|
2313
2509
|
return { code: result.code, map: result.map ? JSON.parse(result.map) : void 0 };
|
|
2314
2510
|
}
|
|
2315
2511
|
};
|
|
2316
|
-
const
|
|
2317
|
-
const mergedDefine = { ...
|
|
2512
|
+
const { output: userOutput, transform: userTransform, ...restInputOptions } = config.build.rolldownOptions;
|
|
2513
|
+
const mergedDefine = { ...userTransform?.define ?? {}, ...envDefine };
|
|
2318
2514
|
const bundle = await rolldown2({
|
|
2515
|
+
...restInputOptions,
|
|
2319
2516
|
input: entry,
|
|
2320
|
-
transform: { ...existingTransform, define: mergedDefine },
|
|
2321
2517
|
platform: "node",
|
|
2322
|
-
|
|
2323
|
-
|
|
2518
|
+
transform: { ...userTransform, define: mergedDefine },
|
|
2519
|
+
plugins: [oxcTransformPlugin, electronPlugin(config), resolvePlugin(config)]
|
|
2324
2520
|
});
|
|
2325
2521
|
fs9.mkdirSync(path12.dirname(opts.outFile), { recursive: true });
|
|
2326
2522
|
await bundle.write({
|
|
2327
|
-
file: opts.outFile,
|
|
2328
|
-
format: opts.format === "cjs" ? "cjs" : "esm",
|
|
2329
2523
|
sourcemap: !!config.build.sourcemap,
|
|
2330
2524
|
minify: !!config.build.minify,
|
|
2525
|
+
// 允许用户微调 output;但主进程 / preload 的单文件约束由下方键强制保证
|
|
2526
|
+
...userOutput,
|
|
2527
|
+
file: opts.outFile,
|
|
2528
|
+
format: opts.format === "cjs" ? "cjs" : "esm",
|
|
2331
2529
|
codeSplitting: false
|
|
2332
2530
|
});
|
|
2333
2531
|
await bundle.close();
|
|
@@ -2391,7 +2589,7 @@ async function startElectronDev(inlineConfig = {}) {
|
|
|
2391
2589
|
const { noSpawn, ...rest } = inlineConfig;
|
|
2392
2590
|
const config = await resolveConfig({ ...rest, target: "electron" }, "serve");
|
|
2393
2591
|
warnElectronVersion(config);
|
|
2394
|
-
console.log(pc4.cyan("\n\u26A1 nasti electron dev") + pc4.dim(` v${"1.
|
|
2592
|
+
console.log(pc4.cyan("\n\u26A1 nasti electron dev") + pc4.dim(` v${"1.7.1"}`));
|
|
2395
2593
|
const { createServer: createServer2 } = await Promise.resolve().then(() => (init_server(), server_exports));
|
|
2396
2594
|
const server = await createServer2({ ...rest, target: "electron" });
|
|
2397
2595
|
await server.listen();
|
|
@@ -2718,6 +2916,6 @@ cli.command("preview [root]", "Preview production build").option("--port <port>"
|
|
|
2718
2916
|
}
|
|
2719
2917
|
});
|
|
2720
2918
|
cli.help();
|
|
2721
|
-
cli.version("1.
|
|
2919
|
+
cli.version("1.7.1");
|
|
2722
2920
|
cli.parse();
|
|
2723
2921
|
//# sourceMappingURL=cli.js.map
|