create-miniprogram-scaffold 1.0.0
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/bin/cli.js +315 -0
- package/package.json +25 -0
package/bin/cli.js
ADDED
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { Command } = require('commander');
|
|
4
|
+
const inquirer = require('inquirer');
|
|
5
|
+
const fs = require('fs-extra');
|
|
6
|
+
const path = require('path');
|
|
7
|
+
const chalk = require('chalk');
|
|
8
|
+
|
|
9
|
+
const program = new Command();
|
|
10
|
+
|
|
11
|
+
program
|
|
12
|
+
.name('create-mini-scaffold')
|
|
13
|
+
.description('Create Taro + Go mini program projects')
|
|
14
|
+
.version('1.0.0')
|
|
15
|
+
.argument('[project-name]', 'Project name')
|
|
16
|
+
.option('-f, --framework <framework>', 'Framework to use (React/Vue)', 'React')
|
|
17
|
+
.option('-c, --css <preprocessor>', 'CSS preprocessor (Sass/Less/Stylus/None)', 'Sass')
|
|
18
|
+
.option('-p, --port <port>', 'Server port', '8080')
|
|
19
|
+
.option('-y, --yes', 'Skip prompts and use defaults')
|
|
20
|
+
.option('--overwrite', 'Overwrite existing directory')
|
|
21
|
+
.action(async (projectName, options) => {
|
|
22
|
+
try {
|
|
23
|
+
// If project name not provided, ask for it
|
|
24
|
+
if (!projectName) {
|
|
25
|
+
if (options.yes) {
|
|
26
|
+
projectName = 'my-mini-app';
|
|
27
|
+
} else {
|
|
28
|
+
const answers = await inquirer.prompt([
|
|
29
|
+
{
|
|
30
|
+
type: 'input',
|
|
31
|
+
name: 'projectName',
|
|
32
|
+
message: 'What is your project name?',
|
|
33
|
+
default: 'my-mini-app'
|
|
34
|
+
}
|
|
35
|
+
]);
|
|
36
|
+
projectName = answers.projectName;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Validate project name
|
|
41
|
+
if (!/^[a-zA-Z0-9-_]+$/.test(projectName)) {
|
|
42
|
+
console.error(chalk.red('Error: Project name can only contain letters, numbers, hyphens, and underscores'));
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const targetDir = path.join(process.cwd(), projectName);
|
|
47
|
+
|
|
48
|
+
// Check if directory already exists
|
|
49
|
+
if (await fs.pathExists(targetDir)) {
|
|
50
|
+
if (!options.overwrite) {
|
|
51
|
+
if (options.yes) {
|
|
52
|
+
console.error(chalk.red(`Directory ${projectName} already exists. Use --overwrite to overwrite.`));
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const { overwrite } = await inquirer.prompt([
|
|
57
|
+
{
|
|
58
|
+
type: 'confirm',
|
|
59
|
+
name: 'overwrite',
|
|
60
|
+
message: `Directory ${projectName} already exists. Overwrite?`,
|
|
61
|
+
default: false
|
|
62
|
+
}
|
|
63
|
+
]);
|
|
64
|
+
|
|
65
|
+
if (!overwrite) {
|
|
66
|
+
console.log(chalk.yellow('Operation cancelled'));
|
|
67
|
+
process.exit(0);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
await fs.remove(targetDir);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Configuration
|
|
75
|
+
const config = {
|
|
76
|
+
framework: options.framework,
|
|
77
|
+
cssPreprocessor: options.css,
|
|
78
|
+
serverPort: options.port
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
// Ask for configuration options if not using --yes
|
|
82
|
+
if (!options.yes) {
|
|
83
|
+
const answers = await inquirer.prompt([
|
|
84
|
+
{
|
|
85
|
+
type: 'list',
|
|
86
|
+
name: 'framework',
|
|
87
|
+
message: 'Which framework do you want to use?',
|
|
88
|
+
choices: ['React', 'Vue'],
|
|
89
|
+
default: config.framework
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
type: 'list',
|
|
93
|
+
name: 'cssPreprocessor',
|
|
94
|
+
message: 'Which CSS preprocessor do you want to use?',
|
|
95
|
+
choices: ['Sass', 'Less', 'Stylus', 'None'],
|
|
96
|
+
default: config.cssPreprocessor
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
type: 'input',
|
|
100
|
+
name: 'serverPort',
|
|
101
|
+
message: 'What port should the Go server run on?',
|
|
102
|
+
default: config.serverPort
|
|
103
|
+
}
|
|
104
|
+
]);
|
|
105
|
+
|
|
106
|
+
config.framework = answers.framework;
|
|
107
|
+
config.cssPreprocessor = answers.cssPreprocessor;
|
|
108
|
+
config.serverPort = answers.serverPort;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
console.log(chalk.blue('\nCreating project...'));
|
|
112
|
+
|
|
113
|
+
// Copy templates
|
|
114
|
+
await copyTemplates(projectName, config);
|
|
115
|
+
|
|
116
|
+
console.log(chalk.green('\n✓ Project created successfully!'));
|
|
117
|
+
console.log(chalk.cyan('\nNext steps:'));
|
|
118
|
+
console.log(chalk.white(` cd ${projectName}`));
|
|
119
|
+
console.log(chalk.white(' # Start frontend:'));
|
|
120
|
+
console.log(chalk.white(' cd miniprogram && npm install && npm run dev:weapp'));
|
|
121
|
+
console.log(chalk.white(' # Start backend:'));
|
|
122
|
+
console.log(chalk.white(' cd server && go run main.go'));
|
|
123
|
+
|
|
124
|
+
} catch (error) {
|
|
125
|
+
console.error(chalk.red('Error creating project:'), error);
|
|
126
|
+
process.exit(1);
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
async function copyTemplates(projectName, config) {
|
|
131
|
+
const targetDir = path.join(process.cwd(), projectName);
|
|
132
|
+
const templateDir = path.join(__dirname, '..', '..', 'templates');
|
|
133
|
+
|
|
134
|
+
// Create project structure
|
|
135
|
+
await fs.ensureDir(path.join(targetDir, 'miniprogram'));
|
|
136
|
+
await fs.ensureDir(path.join(targetDir, 'server'));
|
|
137
|
+
|
|
138
|
+
// Copy miniprogram template
|
|
139
|
+
await copyMiniprogramTemplate(targetDir, config);
|
|
140
|
+
|
|
141
|
+
// Copy server template
|
|
142
|
+
await copyServerTemplate(targetDir, config);
|
|
143
|
+
|
|
144
|
+
// Create root README
|
|
145
|
+
await createRootReadme(targetDir, projectName, config);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
async function copyMiniprogramTemplate(targetDir, config) {
|
|
149
|
+
const templateDir = path.join(__dirname, '..', '..', 'templates', 'miniprogram');
|
|
150
|
+
const targetMiniprogramDir = path.join(targetDir, 'miniprogram');
|
|
151
|
+
|
|
152
|
+
// Copy all template files
|
|
153
|
+
await fs.copy(templateDir, targetMiniprogramDir);
|
|
154
|
+
|
|
155
|
+
// Update package.json with correct name
|
|
156
|
+
const packageJsonPath = path.join(targetMiniprogramDir, 'package.json');
|
|
157
|
+
const packageJson = await fs.readJson(packageJsonPath);
|
|
158
|
+
packageJson.name = path.basename(targetDir) + '-miniprogram';
|
|
159
|
+
await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 });
|
|
160
|
+
|
|
161
|
+
// Update project.config.json
|
|
162
|
+
const projectConfigPath = path.join(targetMiniprogramDir, 'project.config.json');
|
|
163
|
+
const projectConfig = await fs.readJson(projectConfigPath);
|
|
164
|
+
projectConfig.projectname = path.basename(targetDir);
|
|
165
|
+
await fs.writeJson(projectConfigPath, projectConfig, { spaces: 2 });
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
async function copyServerTemplate(targetDir, config) {
|
|
169
|
+
const templateDir = path.join(__dirname, '..', '..', 'templates', 'server');
|
|
170
|
+
const targetServerDir = path.join(targetDir, 'server');
|
|
171
|
+
|
|
172
|
+
// Copy all template files
|
|
173
|
+
await fs.copy(templateDir, targetServerDir);
|
|
174
|
+
|
|
175
|
+
// Update go.mod with correct module name
|
|
176
|
+
const goModPath = path.join(targetServerDir, 'go.mod');
|
|
177
|
+
let goModContent = await fs.readFile(goModPath, 'utf8');
|
|
178
|
+
goModContent = goModContent.replace('module mini-scaffold-server', `module ${path.basename(targetDir)}-server`);
|
|
179
|
+
await fs.writeFile(goModPath, goModContent);
|
|
180
|
+
|
|
181
|
+
// Update .env with correct port
|
|
182
|
+
const envPath = path.join(targetServerDir, '.env');
|
|
183
|
+
let envContent = await fs.readFile(envPath, 'utf8');
|
|
184
|
+
envContent = envContent.replace('PORT=8080', `PORT=${config.serverPort}`);
|
|
185
|
+
await fs.writeFile(envPath, envContent);
|
|
186
|
+
|
|
187
|
+
// Update .env.example with correct port
|
|
188
|
+
const envExamplePath = path.join(targetServerDir, '.env.example');
|
|
189
|
+
let envExampleContent = await fs.readFile(envExamplePath, 'utf8');
|
|
190
|
+
envExampleContent = envExampleContent.replace('PORT=8080', `PORT=${config.serverPort}`);
|
|
191
|
+
await fs.writeFile(envExamplePath, envExampleContent);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
async function createRootReadme(targetDir, projectName, config) {
|
|
195
|
+
const readmeContent = `# ${projectName}
|
|
196
|
+
|
|
197
|
+
A mini program built with Taro (frontend) and Go (backend).
|
|
198
|
+
|
|
199
|
+
## Project Structure
|
|
200
|
+
|
|
201
|
+
\`\`\`
|
|
202
|
+
${projectName}/
|
|
203
|
+
├── miniprogram/ # Taro frontend
|
|
204
|
+
│ ├── src/ # Source code
|
|
205
|
+
│ ├── config/ # Taro config
|
|
206
|
+
│ └── package.json
|
|
207
|
+
├── server/ # Go backend
|
|
208
|
+
│ ├── main.go # Entry point
|
|
209
|
+
│ ├── handler/ # HTTP handlers
|
|
210
|
+
│ ├── go.mod # Go module
|
|
211
|
+
│ └── go.sum # Go dependencies
|
|
212
|
+
└── README.md
|
|
213
|
+
\`\`\`
|
|
214
|
+
|
|
215
|
+
## Getting Started
|
|
216
|
+
|
|
217
|
+
### Prerequisites
|
|
218
|
+
|
|
219
|
+
- Node.js >= 16
|
|
220
|
+
- Go >= 1.21
|
|
221
|
+
- WeChat Developer Tools
|
|
222
|
+
|
|
223
|
+
### Frontend (Taro)
|
|
224
|
+
|
|
225
|
+
1. Install dependencies:
|
|
226
|
+
\`\`\`bash
|
|
227
|
+
cd miniprogram
|
|
228
|
+
npm install
|
|
229
|
+
\`\`\`
|
|
230
|
+
|
|
231
|
+
2. Start development server:
|
|
232
|
+
\`\`\`bash
|
|
233
|
+
npm run dev:weapp
|
|
234
|
+
\`\`\`
|
|
235
|
+
|
|
236
|
+
3. Open WeChat Developer Tools and import the \`miniprogram\` directory.
|
|
237
|
+
|
|
238
|
+
### Backend (Go)
|
|
239
|
+
|
|
240
|
+
1. Install dependencies:
|
|
241
|
+
\`\`\`bash
|
|
242
|
+
cd server
|
|
243
|
+
go mod tidy
|
|
244
|
+
\`\`\`
|
|
245
|
+
|
|
246
|
+
2. Start the server:
|
|
247
|
+
\`\`\`bash
|
|
248
|
+
go run main.go
|
|
249
|
+
\`\`\`
|
|
250
|
+
|
|
251
|
+
The server will run on port ${config.serverPort}.
|
|
252
|
+
|
|
253
|
+
## API Endpoints
|
|
254
|
+
|
|
255
|
+
- \`GET /api/hello\` - Returns a hello world message
|
|
256
|
+
|
|
257
|
+
## Development
|
|
258
|
+
|
|
259
|
+
### Frontend Development
|
|
260
|
+
|
|
261
|
+
The frontend is built with Taro and React. Key files:
|
|
262
|
+
|
|
263
|
+
- \`src/app.tsx\` - App entry point
|
|
264
|
+
- \`src/pages/index/index.tsx\` - Main page
|
|
265
|
+
- \`config/index.ts\` - Taro configuration
|
|
266
|
+
|
|
267
|
+
### Backend Development
|
|
268
|
+
|
|
269
|
+
The backend is built with Go and Fiber. Key files:
|
|
270
|
+
|
|
271
|
+
- \`main.go\` - Server entry point
|
|
272
|
+
- \`handler/hello.go\` - Hello world handler
|
|
273
|
+
- \`router/router.go\` - Route definitions
|
|
274
|
+
|
|
275
|
+
## Building for Production
|
|
276
|
+
|
|
277
|
+
### Frontend
|
|
278
|
+
|
|
279
|
+
\`\`\`bash
|
|
280
|
+
cd miniprogram
|
|
281
|
+
npm run build:weapp
|
|
282
|
+
\`\`\`
|
|
283
|
+
|
|
284
|
+
### Backend
|
|
285
|
+
|
|
286
|
+
\`\`\`bash
|
|
287
|
+
cd server
|
|
288
|
+
go build -o server main.go
|
|
289
|
+
./server
|
|
290
|
+
\`\`\`
|
|
291
|
+
|
|
292
|
+
## Configuration
|
|
293
|
+
|
|
294
|
+
### Frontend Configuration
|
|
295
|
+
|
|
296
|
+
Edit \`miniprogram/config/index.ts\` to configure Taro settings.
|
|
297
|
+
|
|
298
|
+
### Backend Configuration
|
|
299
|
+
|
|
300
|
+
Edit \`server/.env\` to configure server settings:
|
|
301
|
+
|
|
302
|
+
\`\`\`env
|
|
303
|
+
PORT=8080
|
|
304
|
+
GIN_MODE=release
|
|
305
|
+
\`\`\`
|
|
306
|
+
|
|
307
|
+
## License
|
|
308
|
+
|
|
309
|
+
MIT
|
|
310
|
+
`;
|
|
311
|
+
|
|
312
|
+
await fs.writeFile(path.join(targetDir, 'README.md'), readmeContent);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
program.parse();
|
package/package.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "create-miniprogram-scaffold",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Create Taro + Go mini program projects",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/hk029/miniprogram-scaffold.git"
|
|
8
|
+
},
|
|
9
|
+
"main": "index.js",
|
|
10
|
+
"bin": {
|
|
11
|
+
"create-mini-scaffold": "./bin/cli.js"
|
|
12
|
+
},
|
|
13
|
+
"scripts": {
|
|
14
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
15
|
+
},
|
|
16
|
+
"keywords": ["scaffold", "taro", "go", "mini-program"],
|
|
17
|
+
"author": "",
|
|
18
|
+
"license": "MIT",
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"commander": "^11.0.0",
|
|
21
|
+
"inquirer": "^8.2.0",
|
|
22
|
+
"fs-extra": "^11.1.0",
|
|
23
|
+
"chalk": "^4.1.2"
|
|
24
|
+
}
|
|
25
|
+
}
|