nsbp-cli 0.1.0 → 0.1.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 +72 -70
- package/package.json +7 -2
- package/CHANGELOG.md +0 -102
- package/scripts/sync-template.js +0 -277
package/README.md
CHANGED
|
@@ -2,83 +2,81 @@
|
|
|
2
2
|
|
|
3
3
|
Command-line interface for creating NSBP (Node React SSR by Webpack) projects.
|
|
4
4
|
|
|
5
|
+
📦 **Published on npm**: [https://www.npmjs.com/package/nsbp-cli](https://www.npmjs.com/package/nsbp-cli)
|
|
6
|
+
|
|
7
|
+
## Installation from npm
|
|
8
|
+
|
|
9
|
+
Install globally from npm registry:
|
|
10
|
+
|
|
11
|
+
\`\`\`bash
|
|
12
|
+
# Install globally
|
|
13
|
+
npm install -g nsbp-cli
|
|
14
|
+
|
|
15
|
+
# Or use npx (no installation required)
|
|
16
|
+
npx nsbp-cli create my-app
|
|
17
|
+
|
|
18
|
+
# Verify installation
|
|
19
|
+
nsbp-cli --version
|
|
20
|
+
\`\`\`
|
|
21
|
+
|
|
5
22
|
## Local Usage
|
|
6
23
|
|
|
7
|
-
The CLI is located in
|
|
24
|
+
The CLI is also located in \`cli/\` directory of the NSBP project. Run it locally for development:
|
|
8
25
|
|
|
9
|
-
|
|
26
|
+
\`\`\`bash
|
|
10
27
|
# Navigate to CLI directory
|
|
11
28
|
cd cli
|
|
12
29
|
|
|
13
30
|
# Show help
|
|
14
|
-
node ./bin/nsbp.js --help
|
|
31
|
+
node ./bin/nsbp-cli.js --help
|
|
15
32
|
|
|
16
33
|
# Show NSBP information
|
|
17
|
-
node ./bin/nsbp.js info
|
|
34
|
+
node ./bin/nsbp-cli.js info
|
|
18
35
|
|
|
19
36
|
# Create a new project
|
|
20
|
-
node ./bin/nsbp.js create my-app
|
|
37
|
+
node ./bin/nsbp-cli.js create my-app
|
|
21
38
|
|
|
22
39
|
# Skip npm install
|
|
23
|
-
node ./bin/nsbp.js create my-app --skip-install
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
## Global Installation
|
|
27
|
-
|
|
28
|
-
To use `nsbp` command globally from anywhere:
|
|
29
|
-
|
|
30
|
-
```bash
|
|
31
|
-
# Navigate to CLI directory
|
|
32
|
-
cd cli
|
|
33
|
-
|
|
34
|
-
# Install globally
|
|
35
|
-
npm link
|
|
36
|
-
|
|
37
|
-
# Now you can use from anywhere
|
|
38
|
-
nsbp create my-app
|
|
39
|
-
nsbp info
|
|
40
|
-
```
|
|
40
|
+
node ./bin/nsbp-cli.js create my-app --skip-install
|
|
41
|
+
\`\`\`
|
|
41
42
|
|
|
42
43
|
## Usage
|
|
43
44
|
|
|
44
45
|
### Create a new project
|
|
45
46
|
|
|
46
|
-
|
|
47
|
-
#
|
|
48
|
-
|
|
47
|
+
\`\`\`bash
|
|
48
|
+
# From npm (after global install)
|
|
49
|
+
nsbp-cli create my-app
|
|
50
|
+
|
|
51
|
+
# From npx
|
|
52
|
+
npx nsbp-cli create my-app
|
|
49
53
|
|
|
50
|
-
#
|
|
51
|
-
nsbp create my-app
|
|
54
|
+
# From local CLI directory
|
|
55
|
+
node ./bin/nsbp-cli.js create my-app
|
|
52
56
|
|
|
53
57
|
# Skip npm install
|
|
54
|
-
|
|
55
|
-
# or
|
|
56
|
-
nsbp create my-app --skip-install
|
|
58
|
+
nsbp-cli create my-app --skip-install
|
|
57
59
|
|
|
58
60
|
# Specify template (currently only basic is available)
|
|
59
|
-
nsbp create my-app --template basic
|
|
60
|
-
|
|
61
|
+
nsbp-cli create my-app --template basic
|
|
62
|
+
\`\`\`
|
|
61
63
|
|
|
62
64
|
### Display information
|
|
63
65
|
|
|
64
|
-
|
|
66
|
+
\`\`\`bash
|
|
65
67
|
# Show NSBP framework information
|
|
66
|
-
nsbp info
|
|
67
|
-
|
|
68
|
-
node ./bin/nsbp.js info
|
|
69
|
-
```
|
|
68
|
+
nsbp-cli info
|
|
69
|
+
\`\`\`
|
|
70
70
|
|
|
71
71
|
### Help
|
|
72
72
|
|
|
73
|
-
|
|
73
|
+
\`\`\`bash
|
|
74
74
|
# Show all commands
|
|
75
|
-
nsbp --help
|
|
76
|
-
# or
|
|
77
|
-
node ./bin/nsbp.js --help
|
|
75
|
+
nsbp-cli --help
|
|
78
76
|
|
|
79
77
|
# Show create command help
|
|
80
|
-
nsbp create --help
|
|
81
|
-
|
|
78
|
+
nsbp-cli create --help
|
|
79
|
+
\`\`\`
|
|
82
80
|
|
|
83
81
|
## Templates
|
|
84
82
|
|
|
@@ -88,63 +86,67 @@ nsbp create --help
|
|
|
88
86
|
|
|
89
87
|
## How it works
|
|
90
88
|
|
|
91
|
-
The CLI copies
|
|
89
|
+
The CLI copies NSBP project structure from \`templates/basic/\` to your target directory and creates a new \`package.json\` with appropriate dependencies. You get a fully functional NSBP project ready for development.
|
|
92
90
|
|
|
93
91
|
## Template Synchronization
|
|
94
92
|
|
|
95
|
-
The CLI includes a synchronization script that keeps
|
|
93
|
+
The CLI includes a synchronization script that keeps built-in templates up-to-date with the main NSBP project code.
|
|
96
94
|
|
|
97
95
|
### Sync Script
|
|
98
|
-
Location:
|
|
96
|
+
Location: \`cli/scripts/sync-template.js\`
|
|
99
97
|
|
|
100
98
|
### Usage
|
|
101
|
-
|
|
102
|
-
# From
|
|
103
|
-
cd /path/to/nsbp/cli
|
|
99
|
+
\`\`\`bash
|
|
100
|
+
# From CLI directory
|
|
101
|
+
cd /path/to/nsbp-cli/cli
|
|
104
102
|
|
|
105
|
-
# Run
|
|
103
|
+
# Run sync script
|
|
104
|
+
pnpm run sync-template
|
|
105
|
+
# or
|
|
106
106
|
npm run sync-template
|
|
107
107
|
|
|
108
|
-
# Or use
|
|
108
|
+
# Or use to update shortcut
|
|
109
|
+
pnpm run update
|
|
110
|
+
# or
|
|
109
111
|
npm run update
|
|
110
|
-
|
|
112
|
+
\`\`\`
|
|
111
113
|
|
|
112
114
|
### Features
|
|
113
115
|
- **Smart copying**: Copies only source code and configuration files
|
|
114
|
-
- **Build artifact filtering**: Automatically excludes .js.map, .css.map, .txt, .json, and .LICENSE.txt files from public directory
|
|
115
|
-
- **Template transformation**: Converts main project's package.json to template format (name: "nsbp-template")
|
|
116
|
+
- **Build artifact filtering**: Automatically excludes .js.map, .css.map, .txt, .json, and .LICENSE.txt files from the public directory
|
|
117
|
+
- **Template transformation**: Converts main project's package.json to template format (name: "nsbp-cli-template")
|
|
116
118
|
- **Integrity verification**: Checks for required files like src/Routers.tsx, scripts/start.js, and package.json
|
|
117
119
|
|
|
118
120
|
### What gets synchronized
|
|
119
|
-
-
|
|
120
|
-
-
|
|
121
|
-
-
|
|
122
|
-
-
|
|
123
|
-
-
|
|
124
|
-
-
|
|
125
|
-
-
|
|
126
|
-
-
|
|
121
|
+
- \`src/\` - React components and routing
|
|
122
|
+
- \`public/\` - Static assets (images, favicon.ico)
|
|
123
|
+
- \`scripts/\` - Startup and utility scripts
|
|
124
|
+
- \`webpack.*.js\` - Webpack configuration files
|
|
125
|
+
- \`tsconfig.json\` - TypeScript configuration
|
|
126
|
+
- \`postcss.config.js\` - PostCSS configuration
|
|
127
|
+
- \`package.json\` - Project configuration (automatically templatized)
|
|
128
|
+
- \`.gitignore\`, \`.prettierrc\`, \`.prettierignore\`, \`README.md\`
|
|
127
129
|
|
|
128
130
|
## Development
|
|
129
131
|
|
|
130
132
|
To work on the CLI locally:
|
|
131
133
|
|
|
132
|
-
|
|
134
|
+
\`\`\`bash
|
|
133
135
|
cd cli
|
|
134
136
|
pnpm install
|
|
135
137
|
# or
|
|
136
138
|
npm install
|
|
137
|
-
node ./bin/nsbp.js create test-app
|
|
138
|
-
|
|
139
|
+
node ./bin/nsbp-cli.js create test-app
|
|
140
|
+
\`\`\`
|
|
139
141
|
|
|
140
142
|
## Package Information
|
|
141
143
|
|
|
142
|
-
- **Package Name**:
|
|
143
|
-
- **Bin Command**:
|
|
144
|
+
- **Package Name**: \`nsbp-cli\`
|
|
145
|
+
- **Bin Command**: \`nsbp-cli\`
|
|
146
|
+
- **Version**: \`0.1.0\`
|
|
144
147
|
- **Dependencies**: chalk, commander, fs-extra, inquirer
|
|
145
148
|
- **Package Manager**: Supports both npm and pnpm
|
|
146
149
|
|
|
147
|
-
|
|
148
150
|
## License
|
|
149
151
|
|
|
150
|
-
ISC
|
|
152
|
+
ISC
|
package/package.json
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nsbp-cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "CLI tool for creating NSBP (Node React SSR by Webpack) projects",
|
|
5
5
|
"main": "index.js",
|
|
6
|
+
"files": [
|
|
7
|
+
"bin",
|
|
8
|
+
"templates",
|
|
9
|
+
"README.md"
|
|
10
|
+
],
|
|
6
11
|
"bin": {
|
|
7
12
|
"nsbp": "./bin/nsbp.js"
|
|
8
13
|
},
|
|
@@ -40,4 +45,4 @@
|
|
|
40
45
|
"engines": {
|
|
41
46
|
"node": ">=16.0.0"
|
|
42
47
|
}
|
|
43
|
-
}
|
|
48
|
+
}
|
package/CHANGELOG.md
DELETED
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
# NSBP CLI Changelog
|
|
2
|
-
|
|
3
|
-
All notable changes to the NSBP CLI project will be documented in this file.
|
|
4
|
-
|
|
5
|
-
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
-
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
-
|
|
8
|
-
## [0.1.0] - 2026-01-09
|
|
9
|
-
|
|
10
|
-
### Added
|
|
11
|
-
- **Initial release**: CLI tool for creating NSBP (Node React SSR by Webpack) projects
|
|
12
|
-
- **Create command**: `nsbp create <project-name>` to scaffold new projects
|
|
13
|
-
- **Template system**: Built-in templates (basic, blog, ecommerce support planned)
|
|
14
|
-
- **Interactive prompts**: Confirmation for overwriting existing directories
|
|
15
|
-
- **Template synchronization**: Smart sync script (`scripts/sync-template.js`) to update CLI templates from main NSBP project
|
|
16
|
-
|
|
17
|
-
### Changed
|
|
18
|
-
- **Package.json handling**: Automatic template name transformation ("nsbp-template" → user project name)
|
|
19
|
-
- **Build artifact filtering**: Exclude .js.map, .css.map, .txt, .json, .LICENSE.txt files from public directory during sync
|
|
20
|
-
|
|
21
|
-
### Features
|
|
22
|
-
- **Skip installation option**: `--skip-install` flag to skip npm install
|
|
23
|
-
- **Template selection**: `--template <template>` option (currently basic only)
|
|
24
|
-
- **Help system**: Comprehensive help with `--help` flag
|
|
25
|
-
- **Version info**: `--version` flag to display CLI version
|
|
26
|
-
- **Project info**: `nsbp info` command to display framework information
|
|
27
|
-
|
|
28
|
-
### Technical Details
|
|
29
|
-
- **Dependencies**:
|
|
30
|
-
- `commander` for CLI argument parsing
|
|
31
|
-
- `chalk` for colored console output
|
|
32
|
-
- `inquirer` for interactive prompts
|
|
33
|
-
- `fs-extra` for enhanced file operations
|
|
34
|
-
- **Built-in templates**: Located in `cli/templates/basic/`
|
|
35
|
-
- **Sync script**: Located in `cli/scripts/sync-template.js`
|
|
36
|
-
|
|
37
|
-
### Usage
|
|
38
|
-
|
|
39
|
-
#### Installation
|
|
40
|
-
```bash
|
|
41
|
-
# Install globally
|
|
42
|
-
npm install -g nsbp
|
|
43
|
-
|
|
44
|
-
# Or use with npx (no installation required)
|
|
45
|
-
npx nsbp create my-app
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
#### Create a new project
|
|
49
|
-
```bash
|
|
50
|
-
# Basic usage
|
|
51
|
-
nsbp create my-app
|
|
52
|
-
|
|
53
|
-
# Skip npm install
|
|
54
|
-
nsbp create my-app --skip-install
|
|
55
|
-
|
|
56
|
-
# Specify template (currently basic only)
|
|
57
|
-
nsbp create my-app --template basic
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
#### Update CLI templates
|
|
61
|
-
```bash
|
|
62
|
-
# Run from CLI directory
|
|
63
|
-
cd /path/to/nsbp/cli
|
|
64
|
-
npm run sync-template
|
|
65
|
-
|
|
66
|
-
# Or use the update shortcut
|
|
67
|
-
npm run update
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
#### Display information
|
|
71
|
-
```bash
|
|
72
|
-
# Show NSBP framework information
|
|
73
|
-
nsbp info
|
|
74
|
-
|
|
75
|
-
# Show CLI version
|
|
76
|
-
nsbp --version
|
|
77
|
-
|
|
78
|
-
# Show help
|
|
79
|
-
nsbp --help
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
### Notes
|
|
83
|
-
- This is the initial release of NSBP CLI
|
|
84
|
-
- The CLI currently supports the "basic" template only
|
|
85
|
-
- Blog and ecommerce templates are planned for future releases
|
|
86
|
-
- The sync script automatically filters out build artifacts to keep templates clean
|
|
87
|
-
- All templates are built-in; no external downloads required
|
|
88
|
-
|
|
89
|
-
---
|
|
90
|
-
|
|
91
|
-
## Future Plans
|
|
92
|
-
- **Template expansion**: Add blog and ecommerce templates
|
|
93
|
-
- **Advanced configuration**: Custom webpack and TypeScript configuration options
|
|
94
|
-
- **Plugin system**: Support for third-party templates and plugins
|
|
95
|
-
- **CI/CD integration**: Automated testing and deployment workflows
|
|
96
|
-
- **Internationalization**: Multi-language support for CLI output
|
|
97
|
-
|
|
98
|
-
## Contributing
|
|
99
|
-
Contributions are welcome! Please see the main NSBP project repository for contribution guidelines.
|
|
100
|
-
|
|
101
|
-
## License
|
|
102
|
-
ISC © Erishen Sun
|
package/scripts/sync-template.js
DELETED
|
@@ -1,277 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* 同步 NSBP 主项目代码到 CLI 模板目录
|
|
4
|
-
* 使用:node scripts/sync-template.js
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
const fs = require('fs-extra');
|
|
8
|
-
const path = require('path');
|
|
9
|
-
const chalk = require('chalk');
|
|
10
|
-
|
|
11
|
-
// 路径配置
|
|
12
|
-
const ROOT_DIR = path.resolve(__dirname, '../..'); // nsbp 项目根目录
|
|
13
|
-
const CLI_DIR = path.resolve(__dirname, '..'); // cli 目录
|
|
14
|
-
const TARGET_DIR = path.join(CLI_DIR, 'templates/basic');
|
|
15
|
-
|
|
16
|
-
// 要复制的文件和目录列表
|
|
17
|
-
const COPY_ITEMS = [
|
|
18
|
-
'src',
|
|
19
|
-
'public',
|
|
20
|
-
'scripts',
|
|
21
|
-
'webpack.base.js',
|
|
22
|
-
'webpack.client.js',
|
|
23
|
-
'webpack.server.js',
|
|
24
|
-
'tsconfig.json',
|
|
25
|
-
'postcss.config.js',
|
|
26
|
-
'.gitignore',
|
|
27
|
-
'.prettierrc',
|
|
28
|
-
'.prettierignore',
|
|
29
|
-
'README.md',
|
|
30
|
-
'package.json'
|
|
31
|
-
];
|
|
32
|
-
|
|
33
|
-
// 排除的模式(相对路径包含这些字符串的文件将被跳过)
|
|
34
|
-
const EXCLUDE_PATTERNS = [
|
|
35
|
-
'/node_modules/',
|
|
36
|
-
'/.temp_cache/',
|
|
37
|
-
'/build/',
|
|
38
|
-
'/.git/',
|
|
39
|
-
'.DS_Store',
|
|
40
|
-
'/.serena/',
|
|
41
|
-
'/.vscode/',
|
|
42
|
-
'/.idea/',
|
|
43
|
-
'.log',
|
|
44
|
-
'.tmp',
|
|
45
|
-
// 构建产物 - 匹配 public 下的特定文件
|
|
46
|
-
'public/js/',
|
|
47
|
-
'public/css/',
|
|
48
|
-
'public/client.',
|
|
49
|
-
'public/*.js',
|
|
50
|
-
'public/*.js.map',
|
|
51
|
-
'public/*.txt',
|
|
52
|
-
'public/*.json'
|
|
53
|
-
];
|
|
54
|
-
|
|
55
|
-
// 特殊文件处理配置
|
|
56
|
-
const SPECIAL_FILES = {
|
|
57
|
-
'package.json': (content) => {
|
|
58
|
-
const pkg = JSON.parse(content);
|
|
59
|
-
// 修改为模板名称
|
|
60
|
-
pkg.name = 'nsbp-template';
|
|
61
|
-
pkg.description = 'node react ssr by webpack';
|
|
62
|
-
// 确保版本号
|
|
63
|
-
pkg.version = '1.0.0';
|
|
64
|
-
return JSON.stringify(pkg, null, 2);
|
|
65
|
-
}
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
// 主函数
|
|
69
|
-
async function syncTemplate() {
|
|
70
|
-
console.log(chalk.cyan('🔄 开始同步 NSBP 主项目代码到 CLI 模板...'));
|
|
71
|
-
console.log(chalk.gray(`源目录: ${ROOT_DIR}`));
|
|
72
|
-
console.log(chalk.gray(`目标目录: ${TARGET_DIR}`));
|
|
73
|
-
|
|
74
|
-
// 验证源目录
|
|
75
|
-
if (!fs.existsSync(ROOT_DIR)) {
|
|
76
|
-
console.error(chalk.red(`❌ 源目录不存在: ${ROOT_DIR}`));
|
|
77
|
-
process.exit(1);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
// 清理目标目录(但保留 templates/basic 本身)
|
|
81
|
-
if (fs.existsSync(TARGET_DIR)) {
|
|
82
|
-
console.log(chalk.gray('🧹 清理目标目录...'));
|
|
83
|
-
await fs.emptyDir(TARGET_DIR);
|
|
84
|
-
} else {
|
|
85
|
-
await fs.ensureDir(TARGET_DIR);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// 复制文件
|
|
89
|
-
console.log(chalk.cyan('📦 复制项目文件...'));
|
|
90
|
-
let copiedCount = 0;
|
|
91
|
-
let skippedCount = 0;
|
|
92
|
-
|
|
93
|
-
for (const item of COPY_ITEMS) {
|
|
94
|
-
const source = path.join(ROOT_DIR, item);
|
|
95
|
-
const target = path.join(TARGET_DIR, item);
|
|
96
|
-
|
|
97
|
-
if (!fs.existsSync(source)) {
|
|
98
|
-
console.log(chalk.yellow(`⚠️ 源文件不存在,跳过: ${item}`));
|
|
99
|
-
skippedCount++;
|
|
100
|
-
continue;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// 检查是否为排除项
|
|
104
|
-
const shouldExclude = EXCLUDE_PATTERNS.some(pattern => {
|
|
105
|
-
if (pattern.includes('*')) {
|
|
106
|
-
// 简单的通配符匹配(仅支持后缀)
|
|
107
|
-
if (pattern.startsWith('*')) {
|
|
108
|
-
const ext = pattern.substring(1);
|
|
109
|
-
return item.endsWith(ext);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
return item.includes(pattern);
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
if (shouldExclude) {
|
|
116
|
-
console.log(chalk.gray(` 跳过排除项: ${item}`));
|
|
117
|
-
skippedCount++;
|
|
118
|
-
continue;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
try {
|
|
122
|
-
const stat = fs.statSync(source);
|
|
123
|
-
|
|
124
|
-
if (stat.isDirectory()) {
|
|
125
|
-
// 复制目录,使用自定义过滤器
|
|
126
|
-
await fs.copy(source, target, {
|
|
127
|
-
filter: (src) => {
|
|
128
|
-
const relativePath = path.relative(source, src);
|
|
129
|
-
// 检查是否匹配排除模式
|
|
130
|
-
for (const pattern of EXCLUDE_PATTERNS) {
|
|
131
|
-
if (relativePath.includes(pattern)) {
|
|
132
|
-
return false;
|
|
133
|
-
}
|
|
134
|
-
// 简单的通配符匹配
|
|
135
|
-
if (pattern.includes('*')) {
|
|
136
|
-
const [prefix] = pattern.split('*');
|
|
137
|
-
if (relativePath.startsWith(prefix)) {
|
|
138
|
-
return false;
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// 排除构建产物文件(避免复制 .js, .js.map, .css, .css.map, .txt, .json 等)
|
|
144
|
-
// 仅对 public 目录应用此过滤
|
|
145
|
-
if (item === 'public') {
|
|
146
|
-
const buildArtifactPatterns = [
|
|
147
|
-
'.js.map',
|
|
148
|
-
'.css.map',
|
|
149
|
-
'.js',
|
|
150
|
-
'.css',
|
|
151
|
-
'.txt',
|
|
152
|
-
'.json',
|
|
153
|
-
'.LICENSE.txt'
|
|
154
|
-
];
|
|
155
|
-
|
|
156
|
-
// 只检查文件,不检查目录
|
|
157
|
-
try {
|
|
158
|
-
const stat = fs.statSync(src);
|
|
159
|
-
if (stat.isFile()) {
|
|
160
|
-
const name = path.basename(src);
|
|
161
|
-
|
|
162
|
-
// 检查构建产物模式
|
|
163
|
-
for (const pattern of buildArtifactPatterns) {
|
|
164
|
-
if (name.endsWith(pattern)) {
|
|
165
|
-
// 但保留 favicon.ico
|
|
166
|
-
if (name === 'favicon.ico') {
|
|
167
|
-
return true;
|
|
168
|
-
}
|
|
169
|
-
return false;
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
} catch (err) {
|
|
174
|
-
// 如果无法获取状态,继续复制
|
|
175
|
-
console.warn(chalk.yellow(`⚠️ 无法检查文件状态: ${src}`), err.message);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
return true;
|
|
180
|
-
}
|
|
181
|
-
});
|
|
182
|
-
console.log(chalk.green(` 目录复制: ${item}`));
|
|
183
|
-
} else {
|
|
184
|
-
// 复制文件
|
|
185
|
-
await fs.copy(source, target);
|
|
186
|
-
|
|
187
|
-
// 特殊文件处理
|
|
188
|
-
const basename = path.basename(item);
|
|
189
|
-
if (SPECIAL_FILES[basename]) {
|
|
190
|
-
const content = await fs.readFile(target, 'utf8');
|
|
191
|
-
const processed = SPECIAL_FILES[basename](content);
|
|
192
|
-
await fs.writeFile(target, processed, 'utf8');
|
|
193
|
-
console.log(chalk.green(` 文件处理: ${item} (已模板化)`));
|
|
194
|
-
} else {
|
|
195
|
-
console.log(chalk.green(` 文件复制: ${item}`));
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
copiedCount++;
|
|
199
|
-
} catch (error) {
|
|
200
|
-
console.error(chalk.red(`❌ 复制失败: ${item}`), error.message);
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
// 确保必要的目录存在(即使源目录为空)
|
|
205
|
-
const requiredDirs = ['public/css', 'public/js', 'public/images'];
|
|
206
|
-
for (const dir of requiredDirs) {
|
|
207
|
-
const dirPath = path.join(TARGET_DIR, dir);
|
|
208
|
-
if (!fs.existsSync(dirPath)) {
|
|
209
|
-
await fs.ensureDir(dirPath);
|
|
210
|
-
console.log(chalk.gray(` 创建目录: ${dir}`));
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
// 清理 public 目录中的构建产物
|
|
215
|
-
console.log(chalk.cyan('🧹 清理构建产物...'));
|
|
216
|
-
const publicDir = path.join(TARGET_DIR, 'public');
|
|
217
|
-
if (fs.existsSync(publicDir)) {
|
|
218
|
-
const items = await fs.readdir(publicDir, { withFileTypes: true });
|
|
219
|
-
for (const item of items) {
|
|
220
|
-
const itemPath = path.join(publicDir, item.name);
|
|
221
|
-
// 删除 .js, .js.map, .txt, .json 文件(但保留 favicon.ico 和目录)
|
|
222
|
-
if (item.isFile()) {
|
|
223
|
-
const ext = path.extname(item.name);
|
|
224
|
-
if (['.js', '.js.map', '.txt', '.json', '.css'].includes(ext) && item.name !== 'favicon.ico') {
|
|
225
|
-
await fs.remove(itemPath);
|
|
226
|
-
console.log(chalk.gray(` 删除: ${item.name}`));
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
// 清理子目录中的文件
|
|
231
|
-
const subDirs = ['css', 'js'];
|
|
232
|
-
for (const subDir of subDirs) {
|
|
233
|
-
const subDirPath = path.join(publicDir, subDir);
|
|
234
|
-
if (fs.existsSync(subDirPath)) {
|
|
235
|
-
const subItems = await fs.readdir(subDirPath, { withFileTypes: true });
|
|
236
|
-
for (const subItem of subItems) {
|
|
237
|
-
if (subItem.isFile()) {
|
|
238
|
-
await fs.remove(path.join(subDirPath, subItem.name));
|
|
239
|
-
console.log(chalk.gray(` 删除: ${subDir}/${subItem.name}`));
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
// 验证模板完整性
|
|
247
|
-
console.log(chalk.cyan('🔍 验证模板完整性...'));
|
|
248
|
-
const requiredFiles = ['src/Routers.tsx', 'scripts/start.js', 'package.json'];
|
|
249
|
-
let missingFiles = [];
|
|
250
|
-
|
|
251
|
-
for (const file of requiredFiles) {
|
|
252
|
-
if (!fs.existsSync(path.join(TARGET_DIR, file))) {
|
|
253
|
-
missingFiles.push(file);
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
if (missingFiles.length > 0) {
|
|
258
|
-
console.log(chalk.yellow(`⚠️ 缺少必要文件: ${missingFiles.join(', ')}`));
|
|
259
|
-
} else {
|
|
260
|
-
console.log(chalk.green('✅ 模板完整性验证通过'));
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
console.log(chalk.cyan('\n📊 同步完成'));
|
|
264
|
-
console.log(chalk.green(` 复制文件: ${copiedCount} 个`));
|
|
265
|
-
console.log(chalk.yellow(` 跳过文件: ${skippedCount} 个`));
|
|
266
|
-
console.log(chalk.blue(` 目标目录: ${TARGET_DIR}`));
|
|
267
|
-
|
|
268
|
-
if (missingFiles.length > 0) {
|
|
269
|
-
console.log(chalk.yellow('\n⚠️ 警告:部分必要文件缺失,请检查源项目'));
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
// 执行
|
|
274
|
-
syncTemplate().catch(error => {
|
|
275
|
-
console.error(chalk.red('❌ 同步过程中发生错误:'), error);
|
|
276
|
-
process.exit(1);
|
|
277
|
-
});
|