create-lve 0.1.2 → 0.1.5
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/index.js +55 -28
- package/package.json +2 -3
- package/template/_oxfmtrc.json +9 -0
- package/template/_oxlintrc.json +15 -0
- package/template/{package.json → _package.json} +4 -4
- package/template/_vscode/settings.json +10 -0
- package/template/src/App.tsx +17 -1
- package/template/src/main.tsx +6 -6
- package/template/vite.config.ts +4 -4
- package/template/.oxfmtrc.json +0 -5
- package/template/pnpm-lock.yaml +0 -1762
package/index.js
CHANGED
|
@@ -10,20 +10,36 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
|
10
10
|
|
|
11
11
|
async function main() {
|
|
12
12
|
console.clear();
|
|
13
|
-
|
|
14
|
-
p.intro(`${pc.bgCyan(pc.black(' LVE-CLI '))}`);
|
|
15
13
|
|
|
16
|
-
|
|
14
|
+
p.intro(
|
|
15
|
+
`${pc.bgCyan(pc.black(' LVE-CLI '))} ` +
|
|
16
|
+
pc.gray('The Ultra-Fast React Stack (') +
|
|
17
|
+
pc.blue('Vite') + pc.gray(' + ') +
|
|
18
|
+
pc.yellow('Oxc') + pc.gray(' + ') +
|
|
19
|
+
pc.cyan('Tailwind') + pc.gray(')')
|
|
20
|
+
);
|
|
21
|
+
|
|
17
22
|
const project = await p.group(
|
|
18
23
|
{
|
|
19
|
-
path: () =>
|
|
24
|
+
path: () =>
|
|
20
25
|
p.text({
|
|
21
|
-
message: '
|
|
22
|
-
placeholder: '
|
|
26
|
+
message: '你的项目叫什么名字?',
|
|
27
|
+
placeholder: 'react-app',
|
|
28
|
+
defaultValue: 'react-app',
|
|
23
29
|
validate: (value) => {
|
|
24
|
-
if (value.length === 0) return
|
|
30
|
+
if (!value || value.length === 0) return;
|
|
31
|
+
if (value.match(/[<>:"|?*]/)) return '路径包含非法字符';
|
|
25
32
|
}
|
|
26
33
|
}),
|
|
34
|
+
shouldOverwrite: ({ results }) => {
|
|
35
|
+
const targetDir = path.resolve(process.cwd(), results.path);
|
|
36
|
+
if (fs.existsSync(targetDir) && fs.readdirSync(targetDir).length > 0) {
|
|
37
|
+
return p.confirm({
|
|
38
|
+
message: `⚠️ 目录 ${pc.yellow(results.path)} 已存在且不为空,是否清空?`,
|
|
39
|
+
initialValue: false,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
},
|
|
27
43
|
},
|
|
28
44
|
{
|
|
29
45
|
onCancel: () => {
|
|
@@ -33,29 +49,38 @@ async function main() {
|
|
|
33
49
|
}
|
|
34
50
|
);
|
|
35
51
|
|
|
52
|
+
if (project.shouldOverwrite === false) {
|
|
53
|
+
p.cancel('操作终止:请更换目录名后再试');
|
|
54
|
+
process.exit(0);
|
|
55
|
+
}
|
|
56
|
+
|
|
36
57
|
const targetDir = path.resolve(process.cwd(), project.path);
|
|
37
58
|
const templateDir = path.resolve(__dirname, 'template');
|
|
38
59
|
|
|
39
60
|
const s = p.spinner();
|
|
40
|
-
s.start('🚀
|
|
61
|
+
s.start('🚀 正在搬运模板...');
|
|
41
62
|
|
|
42
63
|
try {
|
|
43
|
-
if (
|
|
64
|
+
if (project.shouldOverwrite) {
|
|
65
|
+
await fs.emptyDir(targetDir);
|
|
66
|
+
} else {
|
|
44
67
|
await fs.ensureDir(targetDir);
|
|
45
68
|
}
|
|
46
69
|
|
|
47
70
|
await fs.copy(templateDir, targetDir);
|
|
48
71
|
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
72
|
+
const renameMap = {
|
|
73
|
+
'_package.json': 'package.json',
|
|
74
|
+
'_gitignore': '.gitignore',
|
|
75
|
+
'_oxfmtrc.json': '.oxfmtrc.json',
|
|
76
|
+
'_oxlintrc.json': '.oxlintrc.json',
|
|
77
|
+
'_vscode': '.vscode',
|
|
78
|
+
};
|
|
53
79
|
|
|
54
|
-
for (const [
|
|
55
|
-
const oldPath = path.join(targetDir,
|
|
56
|
-
const newPath = path.join(targetDir, newName);
|
|
80
|
+
for (const [oldFile, newFile] of Object.entries(renameMap)) {
|
|
81
|
+
const oldPath = path.join(targetDir, oldFile);
|
|
57
82
|
if (fs.existsSync(oldPath)) {
|
|
58
|
-
await fs.move(oldPath,
|
|
83
|
+
await fs.move(oldPath, path.join(targetDir, newFile), { overwrite: true });
|
|
59
84
|
}
|
|
60
85
|
}
|
|
61
86
|
|
|
@@ -66,24 +91,26 @@ async function main() {
|
|
|
66
91
|
await fs.writeJson(pkgPath, pkg, { spaces: 2 });
|
|
67
92
|
}
|
|
68
93
|
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
await fs.remove(lockFile);
|
|
72
|
-
}
|
|
94
|
+
const toRemove = ['pnpm-lock.yaml', 'node_modules', 'dist'];
|
|
95
|
+
await Promise.all(toRemove.map(file => fs.remove(path.join(targetDir, file))));
|
|
73
96
|
|
|
74
|
-
s.stop('
|
|
97
|
+
s.stop(pc.green('项目准备就绪!'));
|
|
98
|
+
|
|
99
|
+
const relativePath = path.relative(process.cwd(), targetDir);
|
|
100
|
+
const cdCmd = relativePath === '' ? '' : `cd ${relativePath}\n`;
|
|
75
101
|
|
|
76
|
-
const cdPath = path.relative(process.cwd(), targetDir);
|
|
77
|
-
|
|
78
102
|
p.note(
|
|
79
|
-
pc.cyan(
|
|
80
|
-
'
|
|
103
|
+
pc.cyan(`${cdCmd}pnpm install\npnpm dev`),
|
|
104
|
+
'快速开始指南'
|
|
81
105
|
);
|
|
82
106
|
|
|
83
|
-
p.outro(
|
|
107
|
+
p.outro(
|
|
108
|
+
`${pc.magenta('✨ Happy Coding!')}\n` +
|
|
109
|
+
`${pc.gray('已为你配置 OXC 规则:享受秒级校验与格式化。')}`
|
|
110
|
+
);
|
|
84
111
|
|
|
85
112
|
} catch (err) {
|
|
86
|
-
s.stop('
|
|
113
|
+
s.stop('失败');
|
|
87
114
|
console.error(pc.red(err));
|
|
88
115
|
process.exit(1);
|
|
89
116
|
}
|
package/package.json
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-lve",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"create-lve": "index.js"
|
|
7
7
|
},
|
|
8
8
|
"files": [
|
|
9
9
|
"index.js",
|
|
10
|
-
"template"
|
|
11
|
-
"dist"
|
|
10
|
+
"template"
|
|
12
11
|
],
|
|
13
12
|
"dependencies": {
|
|
14
13
|
"@clack/prompts": "^1.1.0",
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "./node_modules/oxlint/configuration_schema.json",
|
|
3
|
+
"categories": {
|
|
4
|
+
"correctness": "warn",
|
|
5
|
+
"perf": "warn",
|
|
6
|
+
"suspicious": "warn",
|
|
7
|
+
"pedantic": "allow"
|
|
8
|
+
},
|
|
9
|
+
"rules": {
|
|
10
|
+
"eslint/no-unused-vars": "error",
|
|
11
|
+
"react/jsx-no-target-blank": "error",
|
|
12
|
+
"react-hooks/rules-of-hooks": "error"
|
|
13
|
+
},
|
|
14
|
+
"ignorePatterns": ["dist/**", "coverage/**", "vendor/**", "test/snapshots/**"]
|
|
15
|
+
}
|
|
@@ -7,9 +7,10 @@
|
|
|
7
7
|
"dev": "vite",
|
|
8
8
|
"build": "tsc -b && vite build",
|
|
9
9
|
"build-only": "vite build",
|
|
10
|
-
"lint": "eslint .",
|
|
11
10
|
"preview": "vite preview",
|
|
12
|
-
"
|
|
11
|
+
"lint": "oxlint",
|
|
12
|
+
"lint:fix": "oxlint --fix",
|
|
13
|
+
"format": "oxfmt .",
|
|
13
14
|
"format:check": "oxfmt --check"
|
|
14
15
|
},
|
|
15
16
|
"dependencies": {
|
|
@@ -23,10 +24,9 @@
|
|
|
23
24
|
"@types/react": "^19.2.7",
|
|
24
25
|
"@types/react-dom": "^19.2.3",
|
|
25
26
|
"@vitejs/plugin-react": "^5.1.1",
|
|
26
|
-
"globals": "^16.5.0",
|
|
27
27
|
"oxfmt": "^0.36.0",
|
|
28
28
|
"oxlint": "^1.52.0",
|
|
29
29
|
"typescript": "~5.9.3",
|
|
30
30
|
"vite": "^8.0.0-beta.18"
|
|
31
31
|
}
|
|
32
|
-
}
|
|
32
|
+
}
|
package/template/src/App.tsx
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
|
+
import { useState } from 'react'
|
|
2
|
+
|
|
1
3
|
function App() {
|
|
2
|
-
|
|
4
|
+
const [count, setCount] = useState(0)
|
|
5
|
+
|
|
6
|
+
console.log(`%cApp Comp re-render`, 'background-color:blue;color:white;padding:20px;')
|
|
7
|
+
return (
|
|
8
|
+
<div className="min-h-screen flex flex-col gap-6 justify-center items-center">
|
|
9
|
+
<p className="text-6xl">{count}</p>
|
|
10
|
+
<button
|
|
11
|
+
className="px-6 py-2 text-white bg-zinc-900 hover:bg-zinc-900/60 rounded-3xl"
|
|
12
|
+
disabled={count < 0}
|
|
13
|
+
onClick={() => setCount((pre) => pre + 1)}
|
|
14
|
+
>
|
|
15
|
+
increment
|
|
16
|
+
</button>
|
|
17
|
+
</div>
|
|
18
|
+
)
|
|
3
19
|
}
|
|
4
20
|
|
|
5
21
|
export default App
|
package/template/src/main.tsx
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { StrictMode } from
|
|
2
|
-
import { createRoot } from
|
|
3
|
-
import
|
|
4
|
-
import App from
|
|
1
|
+
import { StrictMode } from 'react'
|
|
2
|
+
import { createRoot } from 'react-dom/client'
|
|
3
|
+
import './index.css'
|
|
4
|
+
import App from './App.tsx'
|
|
5
5
|
|
|
6
|
-
createRoot(document.getElementById(
|
|
6
|
+
createRoot(document.getElementById('root')!).render(
|
|
7
7
|
<StrictMode>
|
|
8
8
|
<App />
|
|
9
9
|
</StrictMode>,
|
|
10
|
-
)
|
|
10
|
+
)
|
package/template/vite.config.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { defineConfig } from
|
|
2
|
-
import react from
|
|
3
|
-
import tailwindcss from
|
|
1
|
+
import { defineConfig } from 'vite'
|
|
2
|
+
import react from '@vitejs/plugin-react'
|
|
3
|
+
import tailwindcss from '@tailwindcss/vite'
|
|
4
4
|
|
|
5
5
|
// https://vite.dev/config/
|
|
6
6
|
export default defineConfig({
|
|
7
7
|
plugins: [react(), tailwindcss()],
|
|
8
|
-
})
|
|
8
|
+
})
|