create-express-esm 1.0.5 → 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.
Files changed (2) hide show
  1. package/README.md +114 -24
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -2,12 +2,17 @@
2
2
 
3
3
  > **Modern Express Generator**
4
4
  >
5
- > " 이상 구식 문법(`require`) 복잡한 설정에 시간을 낭비하지 마세요."
6
- > 명령어 한 줄로 **ES Modules**와 **Layered Architecture**가 적용된 프로젝트를 1초 만에 생성합니다.
5
+ > "1초 만에 완성하는 Modern Express(ESM) 환경"
6
+ >
7
+ > CommonJS(require)가 아닌, 최신 ES Modules(import/export) 문법을 기반으로 하는 Express 프로젝트 구조를 자동으로 생성해주는 CLI 도구입니다.
7
8
 
8
9
  [![npm version](https://img.shields.io/npm/v/create-express-esm.svg)](https://www.npmjs.com/package/create-express-esm)
9
10
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
10
11
 
12
+ ## ✨ Demo
13
+
14
+ ![Image](https://github.com/user-attachments/assets/10a7c289-ba5b-42a0-bfb8-6319610fef78)
15
+
11
16
  ## ✨ Key Features (핵심 기능)
12
17
 
13
18
  기존 `express-generator`의 한계를 분석하고 개선하여 개발했습니다.
@@ -23,9 +28,10 @@
23
28
 
24
29
  ```bash
25
30
  npx create-express-esm
31
+ npm create express-esm
26
32
  ```
27
33
 
28
- 또는 전역으로 설치하여 사용할 수도 있습니다.
34
+ 또는 전역으로 설치하여 사용할 수도 있습니다
29
35
 
30
36
  ```
31
37
  npm install -g create-express-esm
@@ -40,41 +46,125 @@ create-express-esm
40
46
  ```text
41
47
  my-app/
42
48
  ├── src/
43
- ├── config/ # ⚙️ 환경변수 및 DB 연결 설정
44
- ├── controllers/ # 🕹️ 요청과 응답 처리 (Controller Layer)
45
- ├── models/ # 🗄️ 데이터베이스 스키마 (Data Access Layer)
46
- ├── routes/ # 🚦 API 라우팅 정의 (Route Definitions)
47
- ├── services/ # 🧠 비즈니스 로직 (Service Layer) - 핵심 로직!
48
- ├── app.js # 🏗️ Express App 설정 (Middleware, CORS 등)
49
- └── server.js # 🚀 서버 실행 진입점 (Entry Point)
50
- ├── .env # 🔐 환경 변수 (Port, DB Key 등)
51
- ├── .gitignore # 🙈 Git 무시 설정
52
- └── package.json # 📦 프로젝트 의존성 및 스크립트
49
+   ├── config/          # ⚙️ 환경변수 및 DB 연결 설정
50
+   ├── controllers/     # 🕹️ 요청과 응답 처리 (Controller Layer)
51
+   ├── models/          # 🗄️ 데이터베이스 스키마 (Data Access Layer)
52
+   ├── routes/          # 🚦 API 라우팅 정의 (Route Definitions)
53
+   ├── services/        # 🧠 비즈니스 로직 (Service Layer) - 핵심 로직!
54
+   ├── app.js           # 🏗️ Express App 설정 (Middleware, CORS 등)
55
+   └── server.js        # 🚀 서버 실행 진입점 (Entry Point)
56
+ ├── .env                 # 🔐 환경 변수 (Port, DB Key 등)
57
+ ├── .gitignore           # 🙈 Git 무시 설정
58
+ └── package.json         # 📦 프로젝트 의존성 및 스크립트
53
59
  ```
54
60
 
55
61
  ## 🛠 Tech Stack (기술 스택)
56
62
 
57
- Runtime: Node.js
63
+ - **Runtime**: Node.js
64
+ - **Framework**: Express.js
65
+ - **Architecture**: Layered Pattern (Controller-Service-Model)
66
+ - **Language**: JavaScript (ES6+ Modules)
67
+ - **Tools**:
68
+ - `dotenv` (환경변수 관리)
69
+ - `cors` (Cross-Origin 리소스 공유 설정)
70
+ - `morgan` (HTTP 요청 로그 기록)
71
+ - `nodemon` (개발 생산성 향상/자동 재시작)
72
+
73
+ ## 🛠️ Engineering Deep Dive
74
+
75
+ 단순한 도구 개발을 넘어, Node.js의 런타임 환경과 모듈 시스템의 차이를 깊이 있게 이해하기 위해 진행한 프로젝트입니다.
76
+
77
+ ### - Project Motivation (Why)
78
+
79
+ 대부분의 Express 예제나 스캐폴딩 도구들이 여전히 CommonJS(require) 방식을 사용하고 있습니다. 하지만 최신 Node.js 생태계는 ES Modules(import)로 전환되고 있습니다.
80
+ **"최신 문법을 지원하는 환경을 매번 수동으로 설정하는 비효율을 해결하자"**는 목표로 시작했으며, 프레임워크 없이 순수 Node.js의 `fs`, `path` 모듈을 다루며 CLI 도구의 동작 원리를 체득하고자 했습니다.
81
+
82
+ ### - Architecture
83
+
84
+ 1. **비동기 파일 시스템 제어**: 대량의 템플릿 파일을 생성할 때 I/O 블로킹을 막기 위해 `fs.promises`와 `async/await`를 사용하여 안정적인 파일 쓰기 작업을 구현했습니다.
85
+ 2. **동적 템플릿 생성**: 사용자가 입력한 프로젝트 이름을 `package.json` 등에 동적으로 주입하여, 생성 즉시 실행 가능한 상태를 보장합니다.
58
86
 
59
- Framework: Express.js
87
+ ## 🔥 Challenges & Troubleshooting
60
88
 
61
- Architecture: Layered Pattern (Controller-Service-Model)
89
+ 개발 과정에서 마주친 기술적 난관과 해결 과정입니다.
62
90
 
63
- Language: JavaScript (ES6+ Modules)
91
+ ### 1. ESM 환경에서의 경로 시스템 구축 (Transition to ESM)
92
+
93
+ > **🔴 Problem:** `ReferenceError: __dirname is not defined`
94
+
95
+ 프로젝트를 `type: "module"`(ESM)로 설정한 후, 템플릿 폴더 경로를 참조하기 위해 관습적으로 `__dirname`을 사용했으나 에러가 발생하며 앱이 종료되었습니다.
96
+
97
+ **🔍 Root Cause & Solution**
98
+
99
+ Node.js의 CommonJS 환경에서는 `__dirname`이 기본적으로 주입되지만, ESM 표준 스펙에는 이 변수가 존재하지 않습니다. 이를 해결하기 위해 `url`과 `path` 모듈을 조합하여 Polyfill(직접 구현) 했습니다.
100
+
101
+ ```javascript
102
+ import path from "path";
103
+ import { fileURLToPath } from "url";
104
+
105
+ // 1. 현재 파일의 URL(file://...)을 시스템 경로로 변환
106
+ const __filename = fileURLToPath(import.meta.url);
107
+
108
+ // 2. 파일 경로에서 디렉토리 경로만 추출하여 __dirname 구현
109
+ const __dirname = path.dirname(__filename);
110
+ ```
64
111
 
65
- Tools:
112
+ ### 2. CLI의 실행 위치와 파일 위치의 혼동 (Execution Context)
66
113
 
67
- dotenv (환경변수 관리)
114
+ > **🔴 Problem:** `ENOENT: no such file or directory`
68
115
 
69
- cors (CORS 설정)
116
+ 로컬 테스트(`node bin/cli.js`) 시에는 정상 작동했으나, `npm link` 후 다른 경로(바탕화면 등)에서 실행했을 때 템플릿 폴더를 찾지 못하는 문제가 발생했습니다.
117
+
118
+ **🔍 Root Cause**
119
+
120
+ CLI 도구 개발 시 **'코드의 위치(Source)'**와 **'명령어 실행 위치(Target)'**가 다를 수 있음을 간과했습니다. 템플릿을 찾을 때 `process.cwd()`(사용자 위치)를 기준으로 탐색했기 때문에 발생한 문제였습니다.
121
+
122
+ **✅ Solution**
123
+
124
+ 리소스의 성격에 따라 기준 경로를 명확히 분리하여 해결했습니다.
125
+
126
+ - **Source (Template)**: 코드가 설치된 곳에 항상 함께 존재하므로 `__dirname` 기준.
127
+ - **Target (Project)**: 사용자가 명령어를 실행한 위치에 생성되어야 하므로 `process.cwd()` 기준.
128
+
129
+ ```javascript
130
+ // [Source] 템플릿 경로: 내 코드가 설치된 곳 기준
131
+ const templateDir = path.join(__dirname, "../template");
132
+
133
+ // [Target] 생성 경로: 사용자가 명령어를 실행한 곳 기준
134
+ const targetDir = path.join(process.cwd(), projectName);
135
+
136
+ // Copy: Source -> Target
137
+ await copyDir(templateDir, targetDir);
138
+ ```
139
+
140
+ ### 3. 배포 파이프라인 최적화 (Appropriate Technology)
141
+
142
+ > **🔴 Problem**
143
+
144
+ 잦은 업데이트 과정에서 `버전 수정` -> `태그 생성` -> `깃 푸시` -> `npm 배포`라는 4단계 프로세스를 수동으로 반복하다 보니, 순서를 누락하거나 버전을 잘못 기입하는 휴먼 에러가 발생했습니다.
145
+
146
+ **🔍 Approach & Solution**
147
+
148
+ GitHub Actions와 같은 CI/CD 도구 도입을 고려했으나, 1인 개발 프로젝트 규모에 비해 설정 비용이 크고 오버엔지니어링이라는 판단이 들었습니다. 대신 Node.js의 내장 기능인 **NPM Scripts**를 활용하는 것이 가장 효율적인 **'적정 기술(Appropriate Technology)'**이라 판단했습니다.
149
+
150
+ ```json
151
+ // package.json
152
+ "scripts": {
153
+ // patch 버전 업 -> 깃 태그 푸시 -> npm 배포를 명령어 한 줄로 원자적(Atomic) 실행
154
+ "deploy": "npm version patch && git push origin main --tags && npm publish"
155
+ }
156
+ ```
70
157
 
71
- morgan (HTTP 로그)
158
+ ## 📝 Retrospective
72
159
 
73
- nodemon (개발용 서버 자동 재시작)
160
+ - **Legacy to Modern**: Node.js 생태계가 CJS에서 ESM으로 전환되는 과도기에서 발생하는 호환성 문제를 직접 겪고 해결하며, 모던 자바스크립트 환경에 대한 이해도를 높였습니다.
161
+ - **Consumer to Producer**: 항상 라이브러리를 사용하기만 하던 입장에서, 직접 도구를 만들어 배포하는 생산자가 되어봄으로써 오픈소스 생태계의 순환 구조를 체감했습니다.
162
+ - **JavaScript to TypeScript (Next Step)**: 순수 ESM 환경을 구축하며 모듈 시스템은 표준화했으나, 컴파일 단계에서 오류를 잡을 수 없는 동적 타입 언어의 한계를 체감했습니다. 프로젝트의 안정성과 유지보수성을 높이기 위해 **TypeScript** 도입과 엄격한 타입 시스템의 필요성을 깨달았으며, 차기 버전에서는 이를 지원할 계획입니다.
74
163
 
75
- ## 🤝 Contributing
164
+ ## 🗺️ Roadmap (Future Plans)
76
165
 
77
- 버그 신고, 기능 제안, PR은 언제나 환영합니다! 이슈는 Issues 탭을 이용해 주세요.
166
+ - [ ] **TypeScript Support**: `tsconfig.json` 자동 설정 `.ts` 템플릿 지원
167
+ - [ ] **Test Environment**: Jest/Supertest 설정 자동화
78
168
 
79
169
  ## 📝 License
80
170
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-express-esm",
3
- "version": "1.0.5",
3
+ "version": "1.0.6",
4
4
  "description": "A modern CLI tool to bootstrap Express.js applications with ES Modules and Layered Architecture.",
5
5
  "main": "index.js",
6
6
  "bin": {