create-express-esm 1.1.2 → 1.1.4
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 +92 -82
- package/package.json +20 -7
- package/template/js/_env +2 -0
- package/template/js/_gitignore +18 -0
- package/template/ts/_env +0 -0
- package/template/ts/_gitignore +0 -0
- package/template/ts/package.json +23 -0
- package/template/ts/src/app.ts +20 -0
- package/template/ts/src/controllers/userController.ts +17 -0
- package/template/ts/src/routes/userRoutes.ts +8 -0
- package/template/ts/src/server.ts +8 -0
- package/template/ts/src/services/userService.ts +14 -0
- package/template/ts/tsconfig.json +15 -0
- package/template/_env +0 -1
- package/template/_gitignore +0 -4
- /package/template/{.env.example → js/.env.example} +0 -0
- /package/template/{package.json → js/package.json} +0 -0
- /package/template/{src → js/src}/app.js +0 -0
- /package/template/{src → js/src}/controllers/userController.js +0 -0
- /package/template/{src → js/src}/routes/userRoutes.js +0 -0
- /package/template/{src → js/src}/server.js +0 -0
- /package/template/{src → js/src}/services/userService.js +0 -0
package/bin/cli.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
1
|
+
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import inquirer from 'inquirer';
|
|
3
|
+
import { input, select } from '@inquirer/prompts'; // 현대적인 방식으로 교체
|
|
5
4
|
import fs from 'fs-extra';
|
|
6
5
|
import path from 'path';
|
|
7
6
|
import chalk from 'chalk';
|
|
@@ -12,89 +11,100 @@ import { fileURLToPath } from 'url';
|
|
|
12
11
|
const __filename = fileURLToPath(import.meta.url);
|
|
13
12
|
const __dirname = path.dirname(__filename);
|
|
14
13
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
.
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
14
|
+
// 1.2.0 버전 정보 및 메인 로직
|
|
15
|
+
async function run() {
|
|
16
|
+
console.log(chalk.blue.bold('\n🚀 Create Express ESM 시작!\n'));
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
// 1. 사용자 질문 (비동기 함수 방식으로 변경)
|
|
20
|
+
const projectName = await input({
|
|
21
|
+
message: '생성할 프로젝트 이름을 입력하세요:',
|
|
22
|
+
default: 'my-app',
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
const language = await select({
|
|
26
|
+
message: '사용할 언어를 선택하세요:',
|
|
27
|
+
choices: [
|
|
28
|
+
{ name: 'JavaScript (ESM)', value: 'js' },
|
|
29
|
+
{ name: 'TypeScript', value: 'ts' },
|
|
30
|
+
],
|
|
31
|
+
});
|
|
32
32
|
|
|
33
|
-
const { projectName } = answers;
|
|
34
33
|
const targetPath = path.join(process.cwd(), projectName);
|
|
35
|
-
const templatePath = path.join(__dirname, '../template');
|
|
34
|
+
const templatePath = path.join(__dirname, '../template', language);
|
|
36
35
|
|
|
37
|
-
// 2.
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
36
|
+
// 2. 폴더 존재 여부 확인
|
|
37
|
+
if (fs.existsSync(targetPath)) {
|
|
38
|
+
console.error(chalk.red(`\n❌ 오류: '${projectName}' 폴더가 이미 존재합니다.`));
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// 3. 템플릿 복사
|
|
43
|
+
console.log(chalk.cyan(`\n📂 [${language.toUpperCase()}] 템플릿을 복사하는 중...`));
|
|
44
|
+
|
|
45
|
+
if (!fs.existsSync(templatePath)) {
|
|
46
|
+
console.error(chalk.red(`\n❌ 오류: ${language} 템플릿 폴더를 찾을 수 없습니다.`));
|
|
47
|
+
console.log(chalk.gray(`경로 확인: ${templatePath}`));
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
await fs.copy(templatePath, targetPath);
|
|
52
|
+
|
|
53
|
+
// 4. 도트 파일 변환 및 환경 설정
|
|
54
|
+
const renameMap = {
|
|
55
|
+
'gitignore': '.gitignore',
|
|
56
|
+
'_gitignore': '.gitignore',
|
|
57
|
+
'_env': '.env'
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
for (const [oldName, newName] of Object.entries(renameMap)) {
|
|
61
|
+
const oldFilePath = path.join(targetPath, oldName);
|
|
62
|
+
const newFilePath = path.join(targetPath, newName);
|
|
63
|
+
|
|
64
|
+
if (await fs.pathExists(oldFilePath)) {
|
|
65
|
+
await fs.move(oldFilePath, newFilePath, { overwrite: true });
|
|
66
|
+
if (newName === '.env') {
|
|
67
|
+
const exampleEnvPath = path.join(targetPath, '.env.example');
|
|
68
|
+
await fs.copy(newFilePath, exampleEnvPath);
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
|
-
|
|
72
|
-
// 3. package.json 프로젝트 이름 수정
|
|
73
|
-
const pkgPath = path.join(targetPath, 'package.json');
|
|
74
|
-
if (await fs.pathExists(pkgPath)) {
|
|
75
|
-
const pkg = await fs.readJson(pkgPath);
|
|
76
|
-
pkg.name = projectName;
|
|
77
|
-
await fs.writeJson(pkgPath, pkg, { spaces: 2 });
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
console.log(chalk.green(`✅ 템플릿 구성 및 환경 설정 완료!`));
|
|
81
|
-
|
|
82
|
-
// 4. 패키지 자동 설치
|
|
83
|
-
console.log(chalk.yellow(`\n📦 패키지 자동 설치를 진행합니다... (npm install)`));
|
|
84
|
-
|
|
85
|
-
execSync('npm install', {
|
|
86
|
-
cwd: targetPath,
|
|
87
|
-
stdio: 'inherit'
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
console.log(chalk.green(`\n✨ 모든 설치가 완료되었습니다!`));
|
|
91
|
-
console.log(chalk.white(`\n다음 명령어로 시작하세요:\n`));
|
|
92
|
-
console.log(chalk.cyan(` cd ${projectName}`));
|
|
93
|
-
console.log(chalk.cyan(` npm run dev\n`));
|
|
94
|
-
|
|
95
|
-
} catch (error) {
|
|
96
|
-
console.error(chalk.red('\n❌ 프로젝트 생성 중 오류 발생:'), error);
|
|
97
71
|
}
|
|
98
|
-
|
|
72
|
+
|
|
73
|
+
// 5. package.json 프로젝트 이름 수정
|
|
74
|
+
const pkgPath = path.join(targetPath, 'package.json');
|
|
75
|
+
if (await fs.pathExists(pkgPath)) {
|
|
76
|
+
const pkg = await fs.readJson(pkgPath);
|
|
77
|
+
pkg.name = projectName;
|
|
78
|
+
await fs.writeJson(pkgPath, pkg, { spaces: 2 });
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
console.log(chalk.green(`✅ 템플릿 구성 완료!`));
|
|
82
|
+
|
|
83
|
+
// 6. 패키지 자동 설치
|
|
84
|
+
console.log(chalk.yellow(`\n📦 패키지 자동 설치를 진행합니다... (npm install)`));
|
|
85
|
+
|
|
86
|
+
execSync('npm install', {
|
|
87
|
+
cwd: targetPath,
|
|
88
|
+
stdio: 'inherit'
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
console.log(chalk.green(`\n✨ 모든 설치가 완료되었습니다!`));
|
|
92
|
+
console.log(chalk.white(`\n다음 명령어로 시작하세요:\n`));
|
|
93
|
+
console.log(chalk.cyan(` cd ${projectName}`));
|
|
94
|
+
if (language === 'ts') {
|
|
95
|
+
console.log(chalk.cyan(` npm run dev (또는 npm run build)`));
|
|
96
|
+
} else {
|
|
97
|
+
console.log(chalk.cyan(` npm run dev`));
|
|
98
|
+
}
|
|
99
|
+
console.log('\n');
|
|
100
|
+
|
|
101
|
+
} catch (error) {
|
|
102
|
+
if (error.name === 'ExitPromptError') {
|
|
103
|
+
console.log(chalk.yellow('\n\n👋 설치를 중단했습니다.'));
|
|
104
|
+
} else {
|
|
105
|
+
console.error(chalk.red('\n❌ 오류 발생:'), error);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
99
109
|
|
|
100
|
-
|
|
110
|
+
run();
|
package/package.json
CHANGED
|
@@ -1,19 +1,28 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-express-esm",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.4",
|
|
4
4
|
"description": "A modern CLI tool to bootstrap Express.js applications with ES Modules and Layered Architecture.",
|
|
5
5
|
"main": "index.js",
|
|
6
|
+
"type": "module",
|
|
6
7
|
"bin": {
|
|
7
|
-
"create-express-esm": "
|
|
8
|
+
"create-express-esm": "bin/cli.js"
|
|
9
|
+
},
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "git+https://github.com/munjuin/create-express-esm.git"
|
|
8
13
|
},
|
|
9
14
|
"scripts": {
|
|
10
15
|
"test": "echo \"Error: no test specified\" && exit 1",
|
|
11
16
|
"deploy": "npm version patch && git push origin main --tags && npm publish"
|
|
12
17
|
},
|
|
13
|
-
"keywords": [
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
18
|
+
"keywords": [
|
|
19
|
+
"express",
|
|
20
|
+
"esm",
|
|
21
|
+
"cli",
|
|
22
|
+
"boilerplate"
|
|
23
|
+
],
|
|
24
|
+
"author": "munjuin",
|
|
25
|
+
"license": "MIT",
|
|
17
26
|
"dependencies": {
|
|
18
27
|
"chalk": "^5.6.2",
|
|
19
28
|
"commander": "^14.0.2",
|
|
@@ -23,5 +32,9 @@
|
|
|
23
32
|
"files": [
|
|
24
33
|
"bin",
|
|
25
34
|
"template"
|
|
26
|
-
]
|
|
35
|
+
],
|
|
36
|
+
"bugs": {
|
|
37
|
+
"url": "https://github.com/munjuin/create-express-esm/issues"
|
|
38
|
+
},
|
|
39
|
+
"homepage": "https://github.com/munjuin/create-express-esm#readme"
|
|
27
40
|
}
|
package/template/js/_env
ADDED
package/template/ts/_env
ADDED
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "temp-name",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"start": "node dist/server.js",
|
|
7
|
+
"dev": "nodemon --exec ts-node src/server.ts",
|
|
8
|
+
"build": "tsc"
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"express": "^4.18.2",
|
|
12
|
+
"dotenv": "^16.3.1",
|
|
13
|
+
"cors": "^2.8.5"
|
|
14
|
+
},
|
|
15
|
+
"devDependencies": {
|
|
16
|
+
"typescript": "^5.0.0",
|
|
17
|
+
"@types/express": "^4.17.17",
|
|
18
|
+
"@types/node": "^20.0.0",
|
|
19
|
+
"@types/cors": "^2.8.13",
|
|
20
|
+
"ts-node": "^10.9.1",
|
|
21
|
+
"nodemon": "^3.0.1"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import express, { Application, Request, Response } from 'express';
|
|
2
|
+
import cors from 'cors';
|
|
3
|
+
import userRoutes from './routes/userRoutes.js';
|
|
4
|
+
|
|
5
|
+
const app: Application = express();
|
|
6
|
+
|
|
7
|
+
// Middleware
|
|
8
|
+
app.use(cors());
|
|
9
|
+
app.use(express.json());
|
|
10
|
+
app.use(express.urlencoded({ extended: true }));
|
|
11
|
+
|
|
12
|
+
// Routes
|
|
13
|
+
app.use('/api/users', userRoutes);
|
|
14
|
+
|
|
15
|
+
// Health Check
|
|
16
|
+
app.get('/', (req: Request, res: Response) => {
|
|
17
|
+
res.send('Create Express ESM (TypeScript) Server is Running!');
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
export default app;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Request, Response } from 'express';
|
|
2
|
+
import * as userService from '../services/userService.js';
|
|
3
|
+
|
|
4
|
+
export const getUsers = async (req: Request, res: Response): Promise<void> => {
|
|
5
|
+
try {
|
|
6
|
+
const users = await userService.fetchAllUsers();
|
|
7
|
+
res.status(200).json({
|
|
8
|
+
success: true,
|
|
9
|
+
data: users,
|
|
10
|
+
});
|
|
11
|
+
} catch (error) {
|
|
12
|
+
res.status(500).json({
|
|
13
|
+
success: false,
|
|
14
|
+
message: 'Internal Server Error',
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// 유저 데이터 타입 정의
|
|
2
|
+
interface User {
|
|
3
|
+
id: number;
|
|
4
|
+
name: string;
|
|
5
|
+
email: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export const fetchAllUsers = async (): Promise<User[]> => {
|
|
9
|
+
// 실제 DB 연동 대신 샘플 데이터를 반환합니다.
|
|
10
|
+
return [
|
|
11
|
+
{ id: 1, name: 'Owner', email: 'owner@example.com' },
|
|
12
|
+
{ id: 2, name: 'Gemini', email: 'gemini@ai.com' },
|
|
13
|
+
];
|
|
14
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ESNext",
|
|
4
|
+
"module": "NodeNext",
|
|
5
|
+
"moduleResolution": "NodeNext",
|
|
6
|
+
"outDir": "./dist",
|
|
7
|
+
"rootDir": "./src",
|
|
8
|
+
"strict": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"skipLibCheck": true,
|
|
11
|
+
"forceConsistentCasingInFileNames": true
|
|
12
|
+
},
|
|
13
|
+
"include": ["src/**/*"],
|
|
14
|
+
"exclude": ["node_modules"]
|
|
15
|
+
}
|
package/template/_env
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
PORT=8080
|
package/template/_gitignore
DELETED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|