@lark-apaas/coding-template-nestjs-react-fullstack 0.1.23 → 0.1.25-alpha.20260820120346
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/package.json
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"name": "fullstack-nestjs-template",
|
|
9
9
|
"version": "2.2.5",
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"@lark-apaas/fullstack-nestjs-core": "^1.1.
|
|
11
|
+
"@lark-apaas/fullstack-nestjs-core": "^1.1.59",
|
|
12
12
|
"@nestjs/axios": "^4.0.1",
|
|
13
13
|
"@nestjs/cache-manager": "^3.1.3",
|
|
14
14
|
"@nestjs/common": "^10.4.20",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"@headlessui/react": "^2.2.9",
|
|
38
38
|
"@heroicons/react": "^2.2.0",
|
|
39
39
|
"@hookform/resolvers": "^5.2.2",
|
|
40
|
-
"@lark-apaas/client-toolkit": "^1.2.
|
|
40
|
+
"@lark-apaas/client-toolkit": "^1.2.63",
|
|
41
41
|
"@lark-apaas/fullstack-presets": "^1.1.0",
|
|
42
42
|
"@lark-apaas/fullstack-vite-preset": "^1.0.34",
|
|
43
43
|
"@nestjs/cli": "^10.4.9",
|
|
@@ -3100,9 +3100,9 @@
|
|
|
3100
3100
|
}
|
|
3101
3101
|
},
|
|
3102
3102
|
"node_modules/@lark-apaas/client-toolkit": {
|
|
3103
|
-
"version": "1.2.
|
|
3104
|
-
"resolved": "https://registry.npmmirror.com/@lark-apaas/client-toolkit/-/client-toolkit-1.2.
|
|
3105
|
-
"integrity": "sha512
|
|
3103
|
+
"version": "1.2.63",
|
|
3104
|
+
"resolved": "https://registry.npmmirror.com/@lark-apaas/client-toolkit/-/client-toolkit-1.2.63.tgz",
|
|
3105
|
+
"integrity": "sha512-/ZtOLOb72bWob1rV950B30C9E9Msda8BdwAFQeMWs7khaVjHBJq/k2vdJksWip14frlsUAPBPcuGe3XafBIcPw==",
|
|
3106
3106
|
"dev": true,
|
|
3107
3107
|
"dependencies": {
|
|
3108
3108
|
"@ant-design/colors": "^7.2.1",
|
|
@@ -3251,16 +3251,16 @@
|
|
|
3251
3251
|
}
|
|
3252
3252
|
},
|
|
3253
3253
|
"node_modules/@lark-apaas/fullstack-nestjs-core": {
|
|
3254
|
-
"version": "1.1.
|
|
3255
|
-
"resolved": "https://registry.npmmirror.com/@lark-apaas/fullstack-nestjs-core/-/fullstack-nestjs-core-1.1.
|
|
3256
|
-
"integrity": "sha512-
|
|
3254
|
+
"version": "1.1.59",
|
|
3255
|
+
"resolved": "https://registry.npmmirror.com/@lark-apaas/fullstack-nestjs-core/-/fullstack-nestjs-core-1.1.59.tgz",
|
|
3256
|
+
"integrity": "sha512-oJs91O+XrrZ36JPyZLi63KKKIphGKXC8Ima3WM6l5Do7wm+VwtGkZKIKa4y44Y4Xv+0kqSotfS9rxs1FwlRPwg==",
|
|
3257
3257
|
"license": "MIT",
|
|
3258
3258
|
"dependencies": {
|
|
3259
3259
|
"@lark-apaas/cache-service": "^0.1.1",
|
|
3260
3260
|
"@lark-apaas/file-service": "^0.1.2",
|
|
3261
3261
|
"@lark-apaas/http-client": "^0.1.7",
|
|
3262
|
-
"@lark-apaas/nestjs-authnpaas": "^1.0.
|
|
3263
|
-
"@lark-apaas/nestjs-authzpaas": "^0.1.
|
|
3262
|
+
"@lark-apaas/nestjs-authnpaas": "^1.0.7",
|
|
3263
|
+
"@lark-apaas/nestjs-authzpaas": "^0.1.14",
|
|
3264
3264
|
"@lark-apaas/nestjs-capability": "^0.1.14",
|
|
3265
3265
|
"@lark-apaas/nestjs-common": "^0.1.9",
|
|
3266
3266
|
"@lark-apaas/nestjs-datapaas": "^1.0.21",
|
|
@@ -3912,9 +3912,9 @@
|
|
|
3912
3912
|
}
|
|
3913
3913
|
},
|
|
3914
3914
|
"node_modules/@lark-apaas/nestjs-authnpaas": {
|
|
3915
|
-
"version": "1.0.
|
|
3916
|
-
"resolved": "https://registry.npmmirror.com/@lark-apaas/nestjs-authnpaas/-/nestjs-authnpaas-1.0.
|
|
3917
|
-
"integrity": "sha512-
|
|
3915
|
+
"version": "1.0.7",
|
|
3916
|
+
"resolved": "https://registry.npmmirror.com/@lark-apaas/nestjs-authnpaas/-/nestjs-authnpaas-1.0.7.tgz",
|
|
3917
|
+
"integrity": "sha512-MIx73hgunGCPCPmWyBGHc99O275Hi9g2MTe/rr4xkXC4AtCxPVuZco/RqBt1gH1HslDNZKJ54Nuq2D8tJ/hDZA==",
|
|
3918
3918
|
"license": "MIT",
|
|
3919
3919
|
"dependencies": {
|
|
3920
3920
|
"reflect-metadata": "^0.1.13"
|
|
@@ -3930,13 +3930,13 @@
|
|
|
3930
3930
|
}
|
|
3931
3931
|
},
|
|
3932
3932
|
"node_modules/@lark-apaas/nestjs-authzpaas": {
|
|
3933
|
-
"version": "0.1.
|
|
3934
|
-
"resolved": "https://registry.npmmirror.com/@lark-apaas/nestjs-authzpaas/-/nestjs-authzpaas-0.1.
|
|
3935
|
-
"integrity": "sha512
|
|
3933
|
+
"version": "0.1.14",
|
|
3934
|
+
"resolved": "https://registry.npmmirror.com/@lark-apaas/nestjs-authzpaas/-/nestjs-authzpaas-0.1.14.tgz",
|
|
3935
|
+
"integrity": "sha512-/FmzjpB1v70EUcKs8VlinM5k4Jw3lvUgNA2+ot2XU3qEFKEiUDfswPKZgj1wIRjvtBxBCpUNaYQ2zm0UjK6Uxw==",
|
|
3936
3936
|
"license": "MIT",
|
|
3937
3937
|
"dependencies": {
|
|
3938
3938
|
"@casl/ability": "^6.7.3",
|
|
3939
|
-
"@lark-apaas/nestjs-authnpaas": "^1.0.
|
|
3939
|
+
"@lark-apaas/nestjs-authnpaas": "^1.0.7",
|
|
3940
3940
|
"@lark-apaas/nestjs-common": "^0.1.9",
|
|
3941
3941
|
"jsonwebtoken": "^9.0.3",
|
|
3942
3942
|
"reflect-metadata": "^0.1.13",
|
package/template/package.json
CHANGED
|
@@ -33,10 +33,10 @@
|
|
|
33
33
|
"upgrade": "npx -y @lark-apaas/fullstack-cli sync --disable-gen-openapi"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@lark-apaas/fullstack-nestjs-core": "^1.1.
|
|
36
|
+
"@lark-apaas/fullstack-nestjs-core": "^1.1.59",
|
|
37
37
|
"@nestjs/axios": "^4.0.1",
|
|
38
|
-
"@nestjs/common": "^10.4.20",
|
|
39
38
|
"@nestjs/cache-manager": "^3.1.3",
|
|
39
|
+
"@nestjs/common": "^10.4.20",
|
|
40
40
|
"@nestjs/config": "^3.3.0",
|
|
41
41
|
"@nestjs/core": "^10.4.20",
|
|
42
42
|
"@nestjs/platform-express": "^10.4.20",
|
|
@@ -62,9 +62,9 @@
|
|
|
62
62
|
"@headlessui/react": "^2.2.9",
|
|
63
63
|
"@heroicons/react": "^2.2.0",
|
|
64
64
|
"@hookform/resolvers": "^5.2.2",
|
|
65
|
-
"@lark-apaas/client-toolkit": "^1.2.
|
|
65
|
+
"@lark-apaas/client-toolkit": "^1.2.63",
|
|
66
|
+
"@lark-apaas/coding-preset-vite-react": "1.0.18-alpha.20260819103004",
|
|
66
67
|
"@lark-apaas/fullstack-presets": "^1.1.0",
|
|
67
|
-
"@lark-apaas/fullstack-vite-preset": "^1.0.34",
|
|
68
68
|
"@nestjs/cli": "^10.4.9",
|
|
69
69
|
"@nestjs/testing": "^10.4.20",
|
|
70
70
|
"@radix-ui/react-accordion": "^1.2.12",
|
|
@@ -181,7 +181,7 @@
|
|
|
181
181
|
"typescript-eslint": "^8.44.0",
|
|
182
182
|
"uuid": "11.0.5",
|
|
183
183
|
"vaul": "^1.1.2",
|
|
184
|
-
"vite": "^
|
|
184
|
+
"vite": "^8",
|
|
185
185
|
"xlsx": "^0.18.5",
|
|
186
186
|
"xlsx-js-style": "^1.2.0",
|
|
187
187
|
"zod": "^3.25.76",
|
package/template/scripts/dev.js
CHANGED
|
@@ -59,10 +59,23 @@ function timestamp() {
|
|
|
59
59
|
);
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
// Cap pending async stdout writes so a stalled pty consumer can't grow memory unbounded.
|
|
63
|
+
// Each pending fs.write retains ~1.5 KB (msg + libuv/V8 wrappers); 1000 ≈ ~1.5 MB ceiling.
|
|
64
|
+
let _stdoutInFlight = 0;
|
|
65
|
+
const STDOUT_MAX_INFLIGHT = 1000;
|
|
66
|
+
|
|
67
|
+
/** Write to dev.std.log (sync, guaranteed) + mirror to terminal (async, non-blocking) */
|
|
63
68
|
function writeOutput(msg) {
|
|
64
|
-
|
|
69
|
+
// File first and synchronously — read-logs reads this file; it must never be gated
|
|
70
|
+
// by the terminal consumer.
|
|
65
71
|
try { fs.writeSync(devStdLogFd, msg); } catch {}
|
|
72
|
+
// stdout mirror via async fs.write: if process.stdout is a pty/pipe whose consumer
|
|
73
|
+
// stalls, the block happens on the libuv threadpool, NOT the event loop — so the
|
|
74
|
+
// synchronous log-FILE writes above (and subsequent readline callbacks) keep running.
|
|
75
|
+
// Drop overflow when too many writes are already pending (best-effort mirror).
|
|
76
|
+
if (_stdoutInFlight >= STDOUT_MAX_INFLIGHT) { return; }
|
|
77
|
+
_stdoutInFlight++;
|
|
78
|
+
try { fs.write(1, msg, () => { _stdoutInFlight--; }); } catch { _stdoutInFlight--; }
|
|
66
79
|
}
|
|
67
80
|
|
|
68
81
|
/** Structured event log → terminal + dev.std.log + dev.log */
|
|
@@ -239,20 +252,23 @@ process.on('SIGTERM', cleanup);
|
|
|
239
252
|
process.on('SIGINT', cleanup);
|
|
240
253
|
process.on('SIGHUP', cleanup);
|
|
241
254
|
|
|
242
|
-
//
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
255
|
+
// 定向保留 dist/ 里能复用的部分, 替代之前无脑 rm -rf dist/。
|
|
256
|
+
// 收益: 保留 dist/server 让 nest --watch 从增量编译起点起 (省 8-13s 冷启动),
|
|
257
|
+
// routes JSON 也保留 (build 会覆盖, 无 stale 风险)。dist/client/index.html 按
|
|
258
|
+
// preset 打的 <meta name="miaoda-html-mode"> marker 判定:
|
|
259
|
+
// marker=dev → 保留 dist/client/ 整个 (dev cache hit)
|
|
260
|
+
// marker=prod → agent 跑过 build:client 污染, 定向清 index.html + assets/
|
|
261
|
+
// 具体逻辑抽到 lib/preserve-dev-cache.cjs 便于单测。
|
|
262
|
+
// 降级 escape hatch: FORCE_CLEAN_DIST=true 走原全清路径 (marker 逻辑出 bug 时用)。
|
|
263
|
+
const { preserveDevCache } = require('./lib/preserve-dev-cache.cjs');
|
|
250
264
|
|
|
251
265
|
// ── Main ──────────────────────────────────────────────────────────────────────
|
|
252
266
|
async function main() {
|
|
253
267
|
logEvent('INFO', 'main', '========== Dev session started ==========');
|
|
254
268
|
|
|
255
|
-
|
|
269
|
+
preserveDevCache(PROJECT_ROOT, {
|
|
270
|
+
log: (level, msg) => logEvent(level, 'main', msg),
|
|
271
|
+
});
|
|
256
272
|
|
|
257
273
|
// Initialize action plugins
|
|
258
274
|
writeOutput('\n🔌 Initializing action plugins...\n');
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// dev.js 启动时替代无脑 rm -rf dist/ 的 lib: 保留 dist/server (nest --watch 增量编译起点)
|
|
4
|
+
// + 按 HTML mode marker 决定 dist/client 是保留还是清污染。
|
|
5
|
+
// 跟 preset 侧 html-output plugin 的 injectHtmlModeMarker / detectHtmlMode 配套:
|
|
6
|
+
// preset 写盘时打 marker (dev 版 vs prod 污染版), 这里读 marker 定去留。
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* 从 HTML 里回读 <meta name="miaoda-html-mode" content="dev|prod"> marker。
|
|
13
|
+
* 与 packages/tools/fullstack-vite-preset/src/vite-plugins/html-output-plugin.ts
|
|
14
|
+
* 的 detectHtmlMode 同源, 为了让 dev.js 模板脚本零依赖跑起来这里重复一份。
|
|
15
|
+
*/
|
|
16
|
+
function detectHtmlMode(htmlContent) {
|
|
17
|
+
const match = htmlContent.match(
|
|
18
|
+
/<meta\s+name=["']miaoda-html-mode["']\s+content=["'](dev|prod)["'][^>]*>/i
|
|
19
|
+
);
|
|
20
|
+
return (match && match[1]) || 'unknown';
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* 定向清理 dist/ 的可复用副本, 替代 dev.js 之前无脑 `rm -rf dist/` 的 cleanStaleDist。
|
|
25
|
+
*
|
|
26
|
+
* 决策规则:
|
|
27
|
+
* - FORCE_CLEAN_DIST=true → 走 escape hatch 全清 (preserveDevCache 逻辑 / 保留的
|
|
28
|
+
* dist/server 出 stale 时兜底)
|
|
29
|
+
* - dist/ 不存在 → 无动作
|
|
30
|
+
* - dist/client/index.html 存在且 marker=dev → 整个 dist/client/ 保留 (dev cache hit)
|
|
31
|
+
* - 存在但 marker=prod 或缺失 → 只清 dist/client/index.html + dist/client/assets/
|
|
32
|
+
* (build 污染部分), dist/server/ 与 routes JSON 保留
|
|
33
|
+
* - 不存在 → 无动作, htmlOutputPlugin 稍后会写入
|
|
34
|
+
*
|
|
35
|
+
* @param {string} projectRoot 项目根目录
|
|
36
|
+
* @param {object} [options]
|
|
37
|
+
* @param {(level: string, msg: string) => void} [options.log] 日志回调, 默认 console.log
|
|
38
|
+
* @param {boolean} [options.forceClean] 覆盖 FORCE_CLEAN_DIST env var 判断 (给测试用)
|
|
39
|
+
* @returns {{ action: 'no_dist' | 'force_cleaned' | 'no_index' | 'preserved' | 'cleaned_polluted' | 'read_failed_cleaned' | 'cleanup_failed', mode: string }}
|
|
40
|
+
*/
|
|
41
|
+
function preserveDevCache(projectRoot, options) {
|
|
42
|
+
const log = (options && options.log) || defaultLogger;
|
|
43
|
+
const forceClean =
|
|
44
|
+
options && typeof options.forceClean === 'boolean'
|
|
45
|
+
? options.forceClean
|
|
46
|
+
: process.env.FORCE_CLEAN_DIST === 'true';
|
|
47
|
+
|
|
48
|
+
const distPath = path.join(projectRoot, 'dist');
|
|
49
|
+
if (!fs.existsSync(distPath)) {
|
|
50
|
+
log('INFO', 'preserveDevCache: no dist/, will be created by vite/nest');
|
|
51
|
+
return { action: 'no_dist', mode: 'unknown' };
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (forceClean) {
|
|
55
|
+
fs.rmSync(distPath, { recursive: true, force: true });
|
|
56
|
+
log(
|
|
57
|
+
'INFO',
|
|
58
|
+
'preserveDevCache: FORCE_CLEAN_DIST=true, cleaned entire dist/'
|
|
59
|
+
);
|
|
60
|
+
return { action: 'force_cleaned', mode: 'unknown' };
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const clientDir = path.join(distPath, 'client');
|
|
64
|
+
const indexHtml = path.join(clientDir, 'index.html');
|
|
65
|
+
|
|
66
|
+
if (!fs.existsSync(indexHtml)) {
|
|
67
|
+
log(
|
|
68
|
+
'INFO',
|
|
69
|
+
'preserveDevCache: no dist/client/index.html, other artifacts preserved'
|
|
70
|
+
);
|
|
71
|
+
return { action: 'no_index', mode: 'unknown' };
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
let mode = 'unknown';
|
|
75
|
+
let readFailed = false;
|
|
76
|
+
try {
|
|
77
|
+
const content = fs.readFileSync(indexHtml, 'utf-8');
|
|
78
|
+
mode = detectHtmlMode(content);
|
|
79
|
+
} catch (e) {
|
|
80
|
+
log(
|
|
81
|
+
'WARN',
|
|
82
|
+
`preserveDevCache: read dist/client/index.html failed: ${e.message}, treating as polluted`
|
|
83
|
+
);
|
|
84
|
+
readFailed = true;
|
|
85
|
+
mode = 'unknown';
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (mode === 'dev') {
|
|
89
|
+
log('INFO', 'preserveDevCache: dist/client preserved (dev cache hit)');
|
|
90
|
+
return { action: 'preserved', mode: 'dev' };
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// marker=prod 或 unknown → build:client 污染 (或人为放的产物), 定向清 index.html + assets/
|
|
94
|
+
// dist/server/, dist/*.json 保留
|
|
95
|
+
try {
|
|
96
|
+
fs.rmSync(indexHtml, { force: true });
|
|
97
|
+
const assetsDir = path.join(clientDir, 'assets');
|
|
98
|
+
if (fs.existsSync(assetsDir)) {
|
|
99
|
+
fs.rmSync(assetsDir, { recursive: true, force: true });
|
|
100
|
+
}
|
|
101
|
+
log(
|
|
102
|
+
'INFO',
|
|
103
|
+
`preserveDevCache: dist/client/index.html was ${mode}, cleaned index.html + assets/ (dist/server preserved)`
|
|
104
|
+
);
|
|
105
|
+
return {
|
|
106
|
+
action: readFailed ? 'read_failed_cleaned' : 'cleaned_polluted',
|
|
107
|
+
mode,
|
|
108
|
+
};
|
|
109
|
+
} catch (e) {
|
|
110
|
+
log(
|
|
111
|
+
'WARN',
|
|
112
|
+
`preserveDevCache: cleanup failed: ${e.message}, continuing anyway (index.html / assets may still be polluted)`
|
|
113
|
+
);
|
|
114
|
+
return { action: 'cleanup_failed', mode };
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function defaultLogger(level, msg) {
|
|
119
|
+
// eslint-disable-next-line no-console
|
|
120
|
+
console.log(`[${level}] [main] ${msg}`);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
module.exports = { detectHtmlMode, preserveDevCache };
|
package/template/scripts/lint.js
CHANGED
|
@@ -72,20 +72,35 @@ const STYLELINT_CONFIG_FILES = [
|
|
|
72
72
|
];
|
|
73
73
|
|
|
74
74
|
/**
|
|
75
|
-
* 老模板(fullstack-nestjs-template 1.x
|
|
76
|
-
*
|
|
75
|
+
* 老模板(fullstack-nestjs-template 1.x 时代)的应用跑不了 stylelint,跑了就挂、把 pre-commit
|
|
76
|
+
* 卡死。两种形态都实测过:
|
|
77
|
+
*
|
|
78
|
+
* - 缺 scripts.stylelint → `npm error Missing script: "stylelint"`
|
|
79
|
+
* - 缺 .stylelintrc.* → `ConfigurationError: No configuration provided`
|
|
80
|
+
*
|
|
81
|
+
* 注意光判断 stylelint 装没装拦不住:@lark-apaas/fullstack-presets 的 dependencies 里有
|
|
82
|
+
* stylelint,只要 dep 了 presets 二进制就在。缺任一件就跳过这一步。
|
|
77
83
|
*/
|
|
78
|
-
function
|
|
84
|
+
function canRunStylelint() {
|
|
85
|
+
let pkg;
|
|
86
|
+
try {
|
|
87
|
+
pkg = JSON.parse(fs.readFileSync(path.join(cwd, 'package.json'), 'utf8'));
|
|
88
|
+
} catch {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (!pkg.scripts || !pkg.scripts.stylelint) return false;
|
|
93
|
+
|
|
79
94
|
return STYLELINT_CONFIG_FILES.some(file => fs.existsSync(path.join(cwd, file)));
|
|
80
95
|
}
|
|
81
96
|
|
|
82
97
|
async function runDefaultLint() {
|
|
83
98
|
const commands = ['npm run eslint', 'npm run type:check'];
|
|
84
99
|
|
|
85
|
-
if (
|
|
100
|
+
if (canRunStylelint()) {
|
|
86
101
|
commands.push('npm run stylelint');
|
|
87
102
|
} else {
|
|
88
|
-
console.warn('[lint] Skip stylelint:
|
|
103
|
+
console.warn('[lint] Skip stylelint: missing scripts.stylelint or stylelint config');
|
|
89
104
|
}
|
|
90
105
|
|
|
91
106
|
const code = await runCommand(getBinName('npx'), ['concurrently', ...commands]);
|
|
@@ -126,8 +141,8 @@ async function runSelectiveLint(inputFiles) {
|
|
|
126
141
|
tasks.push(runCommand(getBinName('npx'), ['eslint', '--quiet', ...eslintFiles]));
|
|
127
142
|
}
|
|
128
143
|
|
|
129
|
-
if (stylelintFiles.length > 0 && !
|
|
130
|
-
console.warn('[lint] Skip stylelint:
|
|
144
|
+
if (stylelintFiles.length > 0 && !canRunStylelint()) {
|
|
145
|
+
console.warn('[lint] Skip stylelint: missing scripts.stylelint or stylelint config');
|
|
131
146
|
} else if (stylelintFiles.length > 0) {
|
|
132
147
|
tasks.push(runCommand(getBinName('npx'), ['stylelint', '--quiet', ...stylelintFiles]));
|
|
133
148
|
}
|
package/template/vite.config.ts
CHANGED