@shark-pepper/create-app 1.0.4 → 1.0.6
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 +8 -9
- package/bin/create-app-cli.js +43 -52
- package/package.json +1 -1
- package/templates/react-app/.babelrc +17 -0
- package/templates/react-app/.commitlintrc.js +3 -0
- package/templates/react-app/.eslintrc.js +44 -0
- package/templates/react-app/.husky/commit-msg +4 -0
- package/templates/react-app/.husky/pre-commit +4 -0
- package/templates/react-app/package.base.json +29 -19
- package/templates/react-app/pnpm-lock.yaml +6079 -2403
- package/templates/react-app/postcss.config.js +5 -0
- package/templates/react-app/src/App.tsx +17 -2
- package/templates/react-app/src/index.tsx +1 -1
- package/templates/react-app/src/routes/index.tsx +3 -16
- package/templates/react-app/src/styles/App.module.scss +16 -0
- package/templates/react-app/webpack/webpack.common.js +53 -0
- package/templates/react-app/webpack/webpack.dev.js +79 -0
- package/templates/react-app/webpack/webpack.prod.js +82 -0
- package/templates/react-app/eslint.config.js +0 -108
- package/templates/react-app/src/components/ProtectedRoute.tsx +0 -17
- package/templates/react-app/src/pages/Home.tsx +0 -15
- package/templates/react-app/src/pages/Login.tsx +0 -29
- package/templates/react-app/src/styles/Home.scss +0 -9
- package/templates/react-app/src/styles/Login.scss +0 -16
- package/templates/react-app/webpack.config.js +0 -123
package/README.md
CHANGED
|
@@ -1,28 +1,27 @@
|
|
|
1
1
|
# 🦈 @shark-pepper/create-app
|
|
2
2
|
|
|
3
|
-
> 🚀
|
|
4
|
-
>
|
|
3
|
+
> 🚀 A scaffolding tool for creating modern front-end projects.
|
|
4
|
+
> It supports mainstream configurations such as React, TypeScript, Webpack, ESLint, Prettier, and Jest.
|
|
5
5
|
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
## ✨
|
|
8
|
+
## ✨ Characteristic
|
|
9
9
|
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
- 🧪 支持 Jest 单元测试
|
|
10
|
+
- ⚙️ By default, it integrates specification tools such as ESLint, Prettier, Husky, and Commitlint.
|
|
11
|
+
- 🧪 Supports Jest unit testing
|
|
13
12
|
|
|
14
13
|
---
|
|
15
14
|
|
|
16
|
-
## 📦
|
|
15
|
+
## 📦 Quick Start
|
|
17
16
|
|
|
18
|
-
###
|
|
17
|
+
### Use npx (recommended)
|
|
19
18
|
|
|
20
19
|
```bash
|
|
21
20
|
npx @shark-pepper/create-app my-project
|
|
22
21
|
|
|
23
22
|
```
|
|
24
23
|
|
|
25
|
-
###
|
|
24
|
+
### Or install globally
|
|
26
25
|
|
|
27
26
|
```bash
|
|
28
27
|
npm install -g @shark-pepper/create-app
|
package/bin/create-app-cli.js
CHANGED
|
@@ -12,7 +12,6 @@ import chalk from "chalk";
|
|
|
12
12
|
import symbols from "log-symbols";
|
|
13
13
|
import fse from "fs-extra";
|
|
14
14
|
|
|
15
|
-
// __dirname for ESM
|
|
16
15
|
const __filename = fileURLToPath(import.meta.url);
|
|
17
16
|
const __dirname = path.dirname(__filename);
|
|
18
17
|
|
|
@@ -35,7 +34,10 @@ const installCmd = hasPnpm() ? "pnpm install" : "npm install";
|
|
|
35
34
|
function getTemplatePath(templateName) {
|
|
36
35
|
const templatePath = path.resolve(__dirname, "../templates", templateName);
|
|
37
36
|
if (!fs.existsSync(templatePath)) {
|
|
38
|
-
console.error(
|
|
37
|
+
console.error(
|
|
38
|
+
symbols.error,
|
|
39
|
+
chalk.red(`Template does not exist: ${templatePath}`)
|
|
40
|
+
);
|
|
39
41
|
process.exit(1);
|
|
40
42
|
}
|
|
41
43
|
return templatePath;
|
|
@@ -51,49 +53,26 @@ async function copyTemplate(src, dest) {
|
|
|
51
53
|
if (!relPath) return true; // 根目录
|
|
52
54
|
// 忽略 node_modules 目录和某些隐藏文件
|
|
53
55
|
if (relPath.split(path.sep).includes("node_modules")) return false;
|
|
54
|
-
if (relPath.startsWith(".git")
|
|
56
|
+
if (relPath.startsWith(".git") && relPath !== ".gitignore")
|
|
57
|
+
return false;
|
|
55
58
|
if (relPath.startsWith(".DS_Store")) return false;
|
|
56
59
|
|
|
57
60
|
return true;
|
|
58
61
|
},
|
|
59
62
|
});
|
|
60
|
-
console.log(
|
|
63
|
+
console.log(
|
|
64
|
+
symbols.success,
|
|
65
|
+
chalk.green("✅ Template file copy completed")
|
|
66
|
+
);
|
|
61
67
|
} catch (err) {
|
|
62
|
-
console.error(symbols.error, chalk.red("
|
|
68
|
+
console.error(symbols.error, chalk.red("Template copy failed"), err);
|
|
63
69
|
process.exit(1);
|
|
64
70
|
}
|
|
65
71
|
}
|
|
66
72
|
|
|
67
|
-
// Husky + lint-staged 配置
|
|
68
|
-
function setupHusky(projectPath) {
|
|
69
|
-
console.log(chalk.blue("⚙️ 配置 Husky + lint-staged ..."));
|
|
70
|
-
|
|
71
|
-
try {
|
|
72
|
-
// 执行 husky install
|
|
73
|
-
execSync("npx husky install", { cwd: projectPath, stdio: "inherit" });
|
|
74
|
-
|
|
75
|
-
// 创建 pre-commit 钩子
|
|
76
|
-
const huskyDir = path.join(projectPath, ".husky");
|
|
77
|
-
if (!fs.existsSync(huskyDir)) fs.mkdirSync(huskyDir, { recursive: true });
|
|
78
|
-
|
|
79
|
-
const preCommitFile = path.join(huskyDir, "pre-commit");
|
|
80
|
-
if (!fs.existsSync(preCommitFile)) {
|
|
81
|
-
fs.writeFileSync(
|
|
82
|
-
preCommitFile,
|
|
83
|
-
'#!/bin/sh\n. "$(dirname "$0")/_/husky.sh"\nnpx lint-staged\n',
|
|
84
|
-
{ mode: 0o755 }
|
|
85
|
-
);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
console.log(symbols.success, chalk.green("✅ Husky + lint-staged 已配置"));
|
|
89
|
-
} catch (err) {
|
|
90
|
-
console.error(symbols.error, chalk.red("Husky 配置失败"), err);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
73
|
// Jest 配置
|
|
95
74
|
function setupJest(projectPath) {
|
|
96
|
-
console.log(chalk.blue("⚙️
|
|
75
|
+
console.log(chalk.blue("⚙️ Configuring the Jest testing environment..."));
|
|
97
76
|
|
|
98
77
|
try {
|
|
99
78
|
// 安装依赖
|
|
@@ -156,9 +135,12 @@ module.exports = {
|
|
|
156
135
|
const fileMock = `module.exports = 'test-file-stub';\n`;
|
|
157
136
|
fs.writeFileSync(path.join(mocksDir, "fileMock.js"), fileMock, "utf-8");
|
|
158
137
|
|
|
159
|
-
console.log(
|
|
138
|
+
console.log(
|
|
139
|
+
symbols.success,
|
|
140
|
+
chalk.green("✅ Jest configuration complete")
|
|
141
|
+
);
|
|
160
142
|
} catch (err) {
|
|
161
|
-
console.error(symbols.error, chalk.red("Jest
|
|
143
|
+
console.error(symbols.error, chalk.red("Jest configuration failed."), err);
|
|
162
144
|
}
|
|
163
145
|
}
|
|
164
146
|
|
|
@@ -170,32 +152,32 @@ async function run() {
|
|
|
170
152
|
{
|
|
171
153
|
type: "input",
|
|
172
154
|
name: "projectName",
|
|
173
|
-
message: "
|
|
155
|
+
message: "Project Name: ",
|
|
174
156
|
default: "my-app",
|
|
175
157
|
when: () => !projectNameArg,
|
|
176
158
|
},
|
|
177
159
|
{
|
|
178
160
|
type: "input",
|
|
179
161
|
name: "version",
|
|
180
|
-
message: "
|
|
162
|
+
message: "Version: ",
|
|
181
163
|
default: "1.0.0",
|
|
182
164
|
},
|
|
183
165
|
{
|
|
184
166
|
type: "input",
|
|
185
167
|
name: "description",
|
|
186
|
-
message: "
|
|
187
|
-
default: "A project created by create-app
|
|
168
|
+
message: "Description: ",
|
|
169
|
+
default: "A project created by @shark-pepper/create-app",
|
|
188
170
|
},
|
|
189
171
|
{
|
|
190
172
|
type: "list",
|
|
191
173
|
name: "template",
|
|
192
|
-
message: "
|
|
193
|
-
choices: ["react-app"
|
|
174
|
+
message: "Select a project template: ",
|
|
175
|
+
choices: ["react-app"],
|
|
194
176
|
},
|
|
195
177
|
{
|
|
196
178
|
type: "confirm",
|
|
197
179
|
name: "useJest",
|
|
198
|
-
message: "
|
|
180
|
+
message: "Need to generate a Jest-based unit test configuration",
|
|
199
181
|
default: true,
|
|
200
182
|
},
|
|
201
183
|
]);
|
|
@@ -205,12 +187,15 @@ async function run() {
|
|
|
205
187
|
|
|
206
188
|
const projectPath = path.join(process.cwd(), projectName);
|
|
207
189
|
if (fs.existsSync(projectPath)) {
|
|
208
|
-
console.log(
|
|
190
|
+
console.log(
|
|
191
|
+
symbols.error,
|
|
192
|
+
chalk.red(`The directory ${projectName} already exists!`)
|
|
193
|
+
);
|
|
209
194
|
process.exit(1);
|
|
210
195
|
}
|
|
211
196
|
|
|
212
197
|
fs.mkdirSync(projectPath);
|
|
213
|
-
console.log(symbols.info, chalk.blue("📁
|
|
198
|
+
console.log(symbols.info, chalk.blue("📁 Create a project directory..."));
|
|
214
199
|
|
|
215
200
|
// 复制模板
|
|
216
201
|
const templatePath = getTemplatePath(template);
|
|
@@ -226,30 +211,36 @@ async function run() {
|
|
|
226
211
|
pkgData.description = description;
|
|
227
212
|
fs.writeFileSync(pkgPath, JSON.stringify(pkgData, null, 2), "utf-8");
|
|
228
213
|
fs.unlinkSync(basePkgPath);
|
|
229
|
-
console.log(
|
|
214
|
+
console.log(
|
|
215
|
+
symbols.success,
|
|
216
|
+
chalk.green("✅ package.json has been generated")
|
|
217
|
+
);
|
|
230
218
|
}
|
|
231
219
|
|
|
220
|
+
execSync("git init", { cwd: projectPath, stdio: "inherit" });
|
|
221
|
+
|
|
232
222
|
// 安装依赖
|
|
233
223
|
console.log(
|
|
234
|
-
chalk.yellow(
|
|
224
|
+
chalk.yellow(
|
|
225
|
+
`📦 Dependencies are being installed using ${
|
|
226
|
+
installCmd.split(" ")[0]
|
|
227
|
+
}...`
|
|
228
|
+
)
|
|
235
229
|
);
|
|
236
230
|
execSync(installCmd, { cwd: projectPath, stdio: "inherit" });
|
|
237
231
|
|
|
238
|
-
// Husky + lint-staged
|
|
239
|
-
setupHusky(projectPath);
|
|
240
|
-
|
|
241
232
|
// 可选 Jest
|
|
242
233
|
if (useJest) setupJest(projectPath);
|
|
243
234
|
|
|
244
235
|
console.log(
|
|
245
236
|
symbols.success,
|
|
246
|
-
chalk.green(`🎉
|
|
237
|
+
chalk.green(`🎉 Project ${projectName} created successfully!`)
|
|
247
238
|
);
|
|
248
|
-
console.log(chalk.cyan(`👉
|
|
239
|
+
console.log(chalk.cyan(`👉 Run the project:`));
|
|
249
240
|
console.log(chalk.white(` cd ${projectName}`));
|
|
250
241
|
console.log(chalk.white(` npm start`));
|
|
251
242
|
} catch (err) {
|
|
252
|
-
console.error(symbols.error, chalk.red("
|
|
243
|
+
console.error(symbols.error, chalk.red("Project creation failed!"), err);
|
|
253
244
|
}
|
|
254
245
|
}
|
|
255
246
|
|
package/package.json
CHANGED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
root: true,
|
|
3
|
+
|
|
4
|
+
parser: '@typescript-eslint/parser',
|
|
5
|
+
parserOptions: {
|
|
6
|
+
ecmaVersion: 'latest',
|
|
7
|
+
sourceType: 'module',
|
|
8
|
+
ecmaFeatures: { jsx: true },
|
|
9
|
+
},
|
|
10
|
+
|
|
11
|
+
env: {
|
|
12
|
+
browser: true,
|
|
13
|
+
node: true,
|
|
14
|
+
es2022: true,
|
|
15
|
+
},
|
|
16
|
+
|
|
17
|
+
plugins: ['@typescript-eslint', 'react', 'react-hooks'],
|
|
18
|
+
|
|
19
|
+
extends: [
|
|
20
|
+
'eslint:recommended',
|
|
21
|
+
'plugin:@typescript-eslint/recommended',
|
|
22
|
+
'plugin:react/recommended',
|
|
23
|
+
'plugin:react-hooks/recommended',
|
|
24
|
+
'prettier',
|
|
25
|
+
],
|
|
26
|
+
|
|
27
|
+
settings: {
|
|
28
|
+
react: {
|
|
29
|
+
version: 'detect',
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
rules: {
|
|
34
|
+
'react/react-in-jsx-scope': 'off',
|
|
35
|
+
'react/prop-types': 'off',
|
|
36
|
+
'react-hooks/exhaustive-deps': 'warn',
|
|
37
|
+
'@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }],
|
|
38
|
+
'@typescript-eslint/no-explicit-any': 'warn',
|
|
39
|
+
'no-console': ['warn', { allow: ['warn', 'error'] }],
|
|
40
|
+
'prefer-const': 'warn',
|
|
41
|
+
},
|
|
42
|
+
|
|
43
|
+
ignorePatterns: ['dist', 'build', 'node_modules'],
|
|
44
|
+
};
|
|
@@ -4,31 +4,45 @@
|
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"start": "webpack serve --open --mode development",
|
|
8
|
-
"build": "webpack --mode production",
|
|
9
|
-
"
|
|
10
|
-
"
|
|
7
|
+
"start": "webpack serve --open --mode development --config webpack/webpack.dev.js",
|
|
8
|
+
"build": "webpack --mode production --config webpack/webpack.prod.js",
|
|
9
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
|
10
|
+
"prepare": "husky"
|
|
11
11
|
},
|
|
12
12
|
"keywords": [],
|
|
13
13
|
"author": "",
|
|
14
14
|
"license": "ISC",
|
|
15
15
|
"packageManager": "pnpm@10.18.1",
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"normalize.css": "^8.0.1",
|
|
18
17
|
"react": "^19.2.0",
|
|
19
18
|
"react-dom": "^19.2.0",
|
|
20
19
|
"react-router-dom": "^7.9.5"
|
|
21
20
|
},
|
|
22
21
|
"devDependencies": {
|
|
22
|
+
"@babel/core": "^7.28.5",
|
|
23
|
+
"@babel/preset-env": "^7.28.5",
|
|
24
|
+
"@babel/preset-react": "^7.28.5",
|
|
25
|
+
"@babel/preset-typescript": "^7.28.5",
|
|
26
|
+
"@commitlint/cli": "^20.2.0",
|
|
27
|
+
"@commitlint/config-conventional": "^20.2.0",
|
|
28
|
+
"@pmmmwh/react-refresh-webpack-plugin": "^0.6.2",
|
|
29
|
+
"@types/css-modules": "^1.0.5",
|
|
23
30
|
"@types/react": "^19.2.2",
|
|
24
31
|
"@types/react-dom": "^19.2.2",
|
|
25
32
|
"@types/react-router-dom": "^5.3.3",
|
|
26
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
27
|
-
"@typescript-eslint/parser": "^
|
|
33
|
+
"@typescript-eslint/eslint-plugin": "^6.21.0",
|
|
34
|
+
"@typescript-eslint/parser": "^6.21.0",
|
|
35
|
+
"autoprefixer": "^10.4.22",
|
|
36
|
+
"babel-loader": "^10.0.0",
|
|
37
|
+
"core-js": "^3.47.0",
|
|
28
38
|
"cspell": "^9.2.2",
|
|
29
39
|
"css-loader": "^7.1.2",
|
|
30
|
-
"
|
|
31
|
-
"
|
|
40
|
+
"esbuild": "^0.27.0",
|
|
41
|
+
"esbuild-loader": "^4.4.0",
|
|
42
|
+
"eslint": "8.57.1",
|
|
43
|
+
"eslint-config-prettier": "^9.1.2",
|
|
44
|
+
"eslint-plugin-react": "^7.37.5",
|
|
45
|
+
"eslint-plugin-react-hooks": "^4.6.2",
|
|
32
46
|
"fork-ts-checker-webpack-plugin": "^9.1.0",
|
|
33
47
|
"html-webpack-plugin": "^5.6.4",
|
|
34
48
|
"husky": "^9.1.7",
|
|
@@ -36,22 +50,18 @@
|
|
|
36
50
|
"mini-css-extract-plugin": "^2.9.4",
|
|
37
51
|
"postcss-loader": "^8.2.0",
|
|
38
52
|
"prettier": "^3.6.2",
|
|
53
|
+
"react-refresh": "^0.18.0",
|
|
39
54
|
"sass": "^1.93.3",
|
|
40
55
|
"sass-loader": "^16.0.6",
|
|
41
56
|
"style-loader": "^4.0.0",
|
|
42
|
-
"
|
|
43
|
-
"typescript": "^5.9.3",
|
|
57
|
+
"typescript": "~5.3.3",
|
|
44
58
|
"webpack": "^5.102.1",
|
|
45
59
|
"webpack-cli": "^6.0.1",
|
|
46
|
-
"webpack-dev-server": "^5.2.2"
|
|
60
|
+
"webpack-dev-server": "^5.2.2",
|
|
61
|
+
"webpack-merge": "^6.0.1"
|
|
47
62
|
},
|
|
48
63
|
"lint-staged": {
|
|
49
|
-
"*.{ts,tsx,js,jsx}": [
|
|
50
|
-
|
|
51
|
-
"prettier --write"
|
|
52
|
-
],
|
|
53
|
-
"*.{css,scss,less,json,md}": [
|
|
54
|
-
"prettier --write"
|
|
55
|
-
]
|
|
64
|
+
"*.{ts,tsx,js,jsx}": ["eslint --fix", "prettier --write"],
|
|
65
|
+
"*.{css,scss,less,json,md}": ["prettier --write"]
|
|
56
66
|
}
|
|
57
67
|
}
|