@ywal123456/jskim 0.1.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.
@@ -0,0 +1,322 @@
1
+ # JSKim 設定
2
+
3
+ `jskim.config.js` はワークスペースルート(コマンドを実行した `process.cwd()`)に置き、すべてのビルド動作の基準になります。npm パッケージとして入れた場合も、インストール先ではなく実行時のカレントディレクトリをルートとして扱います。
4
+
5
+ ## 全体例
6
+
7
+ ```js
8
+ module.exports = {
9
+ defaults: {
10
+ render: [
11
+ {
12
+ from: 'pages',
13
+ to: '',
14
+ include: ['**/*.njk'],
15
+ extension: '.html',
16
+ },
17
+ ],
18
+
19
+ templates: [
20
+ 'layouts',
21
+ 'components',
22
+ ],
23
+
24
+ copy: [
25
+ {
26
+ from: 'assets',
27
+ to: 'assets',
28
+ },
29
+ ],
30
+
31
+ build: {
32
+ clean: true,
33
+ },
34
+
35
+ watch: {
36
+ debounce: 150,
37
+ },
38
+
39
+ serve: {
40
+ host: '127.0.0.1',
41
+ port: 3000,
42
+ },
43
+
44
+ dev: {
45
+ liveReload: true,
46
+ },
47
+ },
48
+
49
+ projects: {
50
+ sample: {
51
+ sourceDir: 'src/sample',
52
+ outputDir: 'dist/sample',
53
+ },
54
+ },
55
+ };
56
+ ```
57
+
58
+ ## defaults
59
+
60
+ すべてのプロジェクトに共通で適用される既定値です。
61
+
62
+ プロジェクトに同じキーがあれば、プロジェクト側が優先されます。
63
+
64
+ ## projects
65
+
66
+ プロジェクト名 → 設定オブジェクトのマップです。
67
+
68
+ ```bash
69
+ npm run build -- sample
70
+ npm run watch -- sample
71
+ npm run serve -- sample
72
+ npm run dev -- sample
73
+ ```
74
+
75
+ 上記の `sample` が `projects.sample` を指します。
76
+
77
+ 必須:
78
+
79
+ - `sourceDir`
80
+ - `outputDir`
81
+
82
+ 任意:
83
+
84
+ - `render`, `templates`, `copy`, `build`, `watch`, `serve`, `dev` — defaults の上書き
85
+
86
+ ## sourceDir
87
+
88
+ プロジェクトのソースルートです。**ワークスペースルート**基準の相対パス(または絶対パス)です。
89
+
90
+ 例: `src/sample`
91
+
92
+ ## outputDir
93
+
94
+ ビルド結果のルートです。**ワークスペースルート**基準です。
95
+
96
+ 例: `dist/sample`
97
+
98
+ `serve` はこのディレクトリを静的サーバーのルートとして公開します。
99
+
100
+ ## render
101
+
102
+ Nunjucks ファイルを HTML にレンダリングするルール配列です。
103
+
104
+ | フィールド | 基準 | 説明 |
105
+ |------|------|------|
106
+ | `from` | sourceDir | 探索開始ディレクトリ |
107
+ | `to` | outputDir | 出力基準ディレクトリ(`''` = 出力ルート) |
108
+ | `include` | from 基準 | glob パターン配列 |
109
+ | `extension` | — | 出力拡張子(例: `.html`) |
110
+
111
+ 例:
112
+
113
+ ```text
114
+ src/sample/pages/index.njk → dist/sample/index.html
115
+ src/sample/pages/guide/basic.njk → dist/sample/guide/basic.html
116
+ ```
117
+
118
+ `layouts` と `components` は render 対象ではなく、直接出力されません。
119
+
120
+ ## templates
121
+
122
+ Nunjucks loader の追加検索パスです。**sourceDir** 基準です。
123
+
124
+ `sourceDir` 自体も常に loader root に含まれるため、次が動作します。
125
+
126
+ ```njk
127
+ {% extends "layouts/base.njk" %}
128
+ {% include "components/header.njk" %}
129
+ ```
130
+
131
+ ## copy
132
+
133
+ 静的ファイルを変換せずにコピーするルール配列です。
134
+
135
+ | フィールド | 基準 | 説明 |
136
+ |------|------|------|
137
+ | `from` | sourceDir | コピー元 |
138
+ | `to` | outputDir | コピー先 |
139
+
140
+ `from` が無い場合は警告のみ出してビルドを続行します。
141
+
142
+ ## build.clean
143
+
144
+ `true` のとき、ビルド前に `outputDir` だけを整理します。
145
+
146
+ 次のパスは削除せず、該当すればエラーで終了します。
147
+
148
+ - ファイルシステムルート
149
+ - ワークスペースルート
150
+ - sourceDir 自体
151
+ - sourceDir の上位パス
152
+ - 空のパス
153
+
154
+ ## watch.debounce
155
+
156
+ ファイル変更後、全体再ビルドを開始するまでの待ち時間(ms)です。
157
+
158
+ | 項目 | 内容 |
159
+ |------|------|
160
+ | 型 | `number`(有限の非負数) |
161
+ | 既定値 | `150` |
162
+ | マージ | `build` と同様にオブジェクト 1 段階マージ — プロジェクトで `watch.debounce` だけ上書き可能 |
163
+
164
+ プロジェクト別の上書き例:
165
+
166
+ ```js
167
+ projects: {
168
+ sample: {
169
+ sourceDir: 'src/sample',
170
+ outputDir: 'dist/sample',
171
+ watch: {
172
+ debounce: 300,
173
+ },
174
+ },
175
+ },
176
+ ```
177
+
178
+ 不正な値:
179
+
180
+ - 負数
181
+ - 数値でない
182
+ - `NaN` / `Infinity`
183
+
184
+ この場合は設定エラーで終了します。
185
+
186
+ 注意:
187
+
188
+ - この段階では `jskim.config.js` 自体は watch しません
189
+ - 設定を変えた場合は watch コマンドを再起動してください
190
+
191
+ ## serve.host
192
+
193
+ ローカル静的サーバーのバインドホストです。
194
+
195
+ | 項目 | 内容 |
196
+ |------|------|
197
+ | 型 | 空でない `string` |
198
+ | 既定値 | `'127.0.0.1'` |
199
+ | マージ | `serve` オブジェクトの 1 段階マージ |
200
+
201
+ 不正な値(空文字・非文字列)は設定エラーで終了します。
202
+
203
+ ## serve.port
204
+
205
+ ローカル静的サーバーのポートです。
206
+
207
+ | 項目 | 内容 |
208
+ |------|------|
209
+ | 型 | 整数 |
210
+ | 範囲 | `1` 以上 `65535` 以下 |
211
+ | 既定値 | `3000` |
212
+ | マージ | `serve` オブジェクトの 1 段階マージ — `serve.port` だけ上書き可能 |
213
+
214
+ プロジェクト別の上書き例:
215
+
216
+ ```js
217
+ projects: {
218
+ sample: {
219
+ sourceDir: 'src/sample',
220
+ outputDir: 'dist/sample',
221
+ serve: {
222
+ port: 4000,
223
+ },
224
+ },
225
+ },
226
+ ```
227
+
228
+ 不正な値の例: 文字列、小数、`NaN`、負数、`0`、`65536` 以上。
229
+
230
+ エラー例:
231
+
232
+ ```text
233
+ [JSKim] 設定値が不正です: serve.port
234
+ 1から65535までの整数を指定してください。
235
+ 受け取った値: -1
236
+ ```
237
+
238
+ `serve` は自動ビルドしません。`outputDir` が無い場合は先に `npm run build -- <name>` を実行してください。
239
+
240
+ ## dev.liveReload
241
+
242
+ 開発サーバー(`npm run dev`)のライブリロード有効/無効です。
243
+
244
+ | 項目 | 内容 |
245
+ |------|------|
246
+ | 型 | `boolean` |
247
+ | 既定値 | `true` |
248
+ | マージ | `dev` オブジェクトの 1 段階マージ |
249
+
250
+ `true` のとき:
251
+
252
+ - `GET /_jskim/live-reload` で SSE を提供
253
+ - HTML レスポンスにだけ client script を一時注入(`dist` には書き込まない)
254
+ - **成功した再ビルドのあとだけ** `reload` event を送信
255
+
256
+ `false` のとき:
257
+
258
+ - SSE endpoint は提供しない(404)
259
+ - HTML への script 注入なし
260
+ - build + watch + serve 自体は動作
261
+
262
+ ### 予約パス `/_jskim/live-reload`
263
+
264
+ `dev.liveReload: true` のときだけ有効になる内部 SSE endpoint です。
265
+
266
+ - JSKim が予約するパスであり、プロジェクトの静的ファイルとしては使わないことを推奨します
267
+ - `serve` コマンドでは有効になりません
268
+ - `dev.liveReload: false` では有効になりません
269
+ - パス自体を設定で変更するオプションはありません
270
+
271
+ プロジェクト別の上書き例:
272
+
273
+ ```js
274
+ projects: {
275
+ sample: {
276
+ sourceDir: 'src/sample',
277
+ outputDir: 'dist/sample',
278
+ dev: {
279
+ liveReload: false,
280
+ },
281
+ },
282
+ },
283
+ ```
284
+
285
+ 不正な値(boolean 以外)は設定エラーで終了します。
286
+
287
+ ### dev が再利用する設定
288
+
289
+ | 設定 | 用途 |
290
+ |------|------|
291
+ | `watch.debounce` | 変更後の再ビルド待ち時間 |
292
+ | `serve.host` | 開発サーバーのホスト |
293
+ | `serve.port` | 開発サーバーのポート |
294
+ | `dev.liveReload` | ライブリロード on/off |
295
+
296
+ `dev.host` / `dev.port` / `dev.debounce` は用意しません。
297
+
298
+ 設定変更後は実行中の watcher/server は自動再構成されないため、`dev` / `watch` / `serve` を再起動してください。
299
+
300
+ ## パス基準のまとめ
301
+
302
+ | 設定 | 基準 |
303
+ |------|------|
304
+ | `sourceDir`, `outputDir` | ワークスペースルート(`jskim.config.js` の場所) |
305
+ | `render[].from`, `templates[]`, `copy[].from` | `sourceDir` |
306
+ | `render[].to`, `copy[].to` | `outputDir` |
307
+
308
+ Windows / POSIX とも `node:path` で解釈します。HTML 内パス(`rootPath` など)は `/` を使います。
309
+
310
+ ## 配列マージ規則
311
+
312
+ - **通常値**: プロジェクト設定があれば優先、なければ defaults
313
+ - **オブジェクト**(`build`, `watch`, `serve`, `dev` など): 1 段階マージ — 例: `build.clean`、`watch.debounce`、`serve.port`、`dev.liveReload` だけ上書き可能
314
+ - **配列**(`render`, `templates`, `copy`): プロジェクトに同じ配列があれば **defaults 配列を丸ごと置き換え**。項目単位の自動マージなし
315
+
316
+ 元の `defaults` とプロジェクト設定オブジェクトは変更しません。
317
+
318
+ ## 外部パス
319
+
320
+ `sourceDir` / `outputDir` にワークスペース外のパスを使うことは禁止しません。
321
+ フレームワークは Git 構成やフォルダ配置を強制しません。
322
+ ただし clean の安全装置(上記)は常に適用されます。
@@ -0,0 +1,80 @@
1
+ # create-jskim
2
+
3
+ `create-jskim` は JSKim の作業空間を新規作成する **独立 scaffold package** です。
4
+
5
+ エンジン CLI(`jskim build` など)とは別 package として管理します。
6
+
7
+ ## 役割
8
+
9
+ - 新しい JSKim プロジェクトディレクトリを作る
10
+ - 標準 `src/sample` と `jskim.config.js` を含める
11
+ - 生成後の `npm install` / `git init` は **実行しない**
12
+
13
+ ## 名称の区別
14
+
15
+ | 名称 | 意味 |
16
+ |------|------|
17
+ | JSKim | 製品名 |
18
+ | `jskim` | CLI binary |
19
+ | `@ywal123456/jskim` | npm engine package |
20
+ | `create-jskim` | npm creator package |
21
+ | `npm create jskim@latest` | ユーザー向け生成コマンド(維持) |
22
+
23
+ ## 生成結果
24
+
25
+ ```text
26
+ project/
27
+ ├─ package.json
28
+ ├─ jskim.config.js
29
+ ├─ README.md
30
+ ├─ .gitignore
31
+ └─ src/sample/
32
+ ```
33
+
34
+ `package.json` の scripts は bin 名 `jskim` を使います(package name ではありません)。
35
+ 既定の engine dependency は `@ywal123456/jskim`(`^0.1.0`)です。
36
+
37
+ ```json
38
+ {
39
+ "devDependencies": {
40
+ "@ywal123456/jskim": "^0.1.0"
41
+ },
42
+ "scripts": {
43
+ "build": "jskim build sample",
44
+ "watch": "jskim watch sample",
45
+ "serve": "jskim serve sample",
46
+ "dev": "jskim dev sample"
47
+ }
48
+ }
49
+ ```
50
+
51
+ ## 安全ポリシー
52
+
53
+ - 空ではない既存ディレクトリは上書きしない
54
+ - 隠しファイルがある場合も空ではないとみなす
55
+ - 生成失敗時は今回作ったファイルだけを片付ける
56
+ - template 内の `gitignore` を生成時に `.gitignore` へ変換する
57
+
58
+ ## エンジン dependency
59
+
60
+ create package の `package.json` に `jskimEngine` metadata を持ち、生成プロジェクトの `devDependencies` に反映します。
61
+
62
+ ```json
63
+ {
64
+ "jskimEngine": {
65
+ "packageName": "@ywal123456/jskim",
66
+ "version": "^0.1.0"
67
+ }
68
+ }
69
+ ```
70
+
71
+ 生成プロジェクトへ License は強制しません。
72
+
73
+ ## 公開コマンド(publish 後)
74
+
75
+ ```bash
76
+ npm create jskim@latest
77
+ npx create-jskim my-project
78
+ ```
79
+
80
+ Package 名・CLI 構造は上記に合わせて準備済みです。registry への実際の publish は別手順です([publishing.md](./publishing.md))。
@@ -0,0 +1,134 @@
1
+ # 公開手順(publishing)
2
+
3
+ この文書は **将来の実際の publish 手順** をまとめたものです。
4
+ 開発リポジトリの通常作業では `npm publish` を実行しません。
5
+
6
+ ## 前提
7
+
8
+ - npm アカウントと認証(2FA ポリシーを含む)
9
+ - 公開 package 名
10
+ - engine: `@ywal123456/jskim`(scoped・公開 MIT)
11
+ - creator: `create-jskim`(unscoped)
12
+
13
+ ### 過去の失敗(参考)
14
+
15
+ unscoped 名 `jskim@0.1.0` の初回 publish は、npm の package name similarity ポリシーにより **E403** で拒否されました。registry には反映されていません。現在の engine 公開名は `@ywal123456/jskim` です。
16
+
17
+ ### 確定済み metadata
18
+
19
+ ```text
20
+ engine package: @ywal123456/jskim
21
+ creator package: create-jskim
22
+ CLI binary: jskim / create-jskim
23
+ license: MIT
24
+ author: Jeongsub Kim <ywal123456@gmail.com>
25
+ repository: https://github.com/ywal123456-collab/jskim
26
+ homepage: https://github.com/ywal123456-collab/jskim#readme
27
+ bugs: https://github.com/ywal123456-collab/jskim/issues
28
+ ```
29
+
30
+ Root `package.json` の `publishConfig`:
31
+
32
+ ```json
33
+ {
34
+ "publishConfig": {
35
+ "access": "public",
36
+ "registry": "https://registry.npmjs.org"
37
+ }
38
+ }
39
+ ```
40
+
41
+ `publishConfig` があっても、scoped engine の初回 publish では手動コマンドの `--access public` を省略しないでください。
42
+
43
+ ### 残りの運用判断
44
+
45
+ ```text
46
+ - 実際の npm publish 時点
47
+ - npm アカウントのログイン状態
48
+ - npm 2FA 状態
49
+ ```
50
+
51
+ ## 認証とセキュリティ
52
+
53
+ - 実際の publish には npm account 認証が必要です
54
+ - 2FA の有効化と運用ポリシーを確認してください
55
+ - token をソースコードや文書に記録しないでください
56
+ - `.npmrc` の認証情報を repository に含めないでください
57
+ - publish 直前に `npm whoami` でログイン状態を確認してください
58
+ - 公開前に会社固有情報・secret・内部 URL が残っていないことを確認してください
59
+
60
+ ## 推奨順序
61
+
62
+ Engine を先に publish します。生成プロジェクトの `package.json` が `@ywal123456/jskim` を参照するため、creator だけ先に公開すると生成直後の `npm install` が失敗し得ます。
63
+
64
+ 1. npm account と認証状態を確認する
65
+ 2. package 名を再確認する(`@ywal123456/jskim` / `create-jskim`)
66
+ 3. リポジトリ root で `npm test` を実行する
67
+ 4. engine の `npm pack` / `npm publish --dry-run --access public` を確認する
68
+ 5. creator の `npm pack` / `npm publish --dry-run` を確認する
69
+ 6. **engine を先に publish** する(`--access public` 必須)
70
+ 7. registry から engine をインストールできることを確認する
71
+ 8. creator を publish する
72
+ 9. `npm create jskim@latest` を検証する
73
+
74
+ ## コマンド例(ユーザーが実行)
75
+
76
+ リポジトリ root(PowerShell):
77
+
78
+ ```powershell
79
+ npm.cmd whoami --registry=https://registry.npmjs.org
80
+ npm.cmd view @ywal123456/jskim name version --registry=https://registry.npmjs.org
81
+ npm.cmd view create-jskim name version --registry=https://registry.npmjs.org
82
+ npm.cmd test
83
+ npm.cmd publish --dry-run --access public --registry=https://registry.npmjs.org
84
+ npm.cmd publish --access public --registry=https://registry.npmjs.org
85
+ ```
86
+
87
+ 期待する成功出力:
88
+
89
+ ```text
90
+ + @ywal123456/jskim@0.1.0
91
+ ```
92
+
93
+ Registry 確認:
94
+
95
+ ```powershell
96
+ npm.cmd view @ywal123456/jskim@0.1.0 name version license bin repository --registry=https://registry.npmjs.org
97
+ ```
98
+
99
+ 外部インストール:
100
+
101
+ ```powershell
102
+ npm.cmd install --save-dev @ywal123456/jskim@0.1.0 --registry=https://registry.npmjs.org
103
+ ```
104
+
105
+ Creator:
106
+
107
+ ```powershell
108
+ cd create-jskim
109
+ npm.cmd publish --dry-run --registry=https://registry.npmjs.org
110
+ npm.cmd publish --registry=https://registry.npmjs.org
111
+ ```
112
+
113
+ 期待する成功出力:
114
+
115
+ ```text
116
+ + create-jskim@0.1.0
117
+ ```
118
+
119
+ 最終ユーザー検証:
120
+
121
+ ```powershell
122
+ npm.cmd create jskim@latest generated-project
123
+ npx create-jskim my-project
124
+ ```
125
+
126
+ ## 注意
127
+
128
+ - unscoped engine 向けの `npm publish`(`--access public` なし・旧 package 名)は使わないでください
129
+ - lifecycle script(`prepublishOnly` など)は、creator を別 cwd から publish する構成との相性を考えて必須化していません
130
+ - publish 前チェックリストとして **手動の `npm test`** を必須とします
131
+ - token 生成・login・owner / dist-tag 変更は運用者が責任を持って行います
132
+ - 生成プロジェクトへ License を強制しません(ユーザー側で決定)
133
+ - creator は unscoped public package のため、creator `package.json` に `access: public` は追加していません
134
+ - dry-run 成功は、creator の similarity 審査通過を保証しません
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "@ywal123456/jskim",
3
+ "version": "0.1.0",
4
+ "description": "Nunjucks-based static HTML build environment with watch, serve, and live reload",
5
+ "keywords": [
6
+ "nunjucks",
7
+ "static-html",
8
+ "static-site",
9
+ "build-tool",
10
+ "template-engine",
11
+ "live-reload",
12
+ "cli"
13
+ ],
14
+ "license": "MIT",
15
+ "author": {
16
+ "name": "Jeongsub Kim",
17
+ "email": "ywal123456@gmail.com"
18
+ },
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "git+https://github.com/ywal123456-collab/jskim.git"
22
+ },
23
+ "homepage": "https://github.com/ywal123456-collab/jskim#readme",
24
+ "bugs": {
25
+ "url": "https://github.com/ywal123456-collab/jskim/issues"
26
+ },
27
+ "bin": {
28
+ "jskim": "bin/jskim.js"
29
+ },
30
+ "files": [
31
+ "bin/",
32
+ "scripts/",
33
+ "README.md",
34
+ "docs/",
35
+ "LICENSE"
36
+ ],
37
+ "scripts": {
38
+ "build": "node scripts/build.js",
39
+ "watch": "node scripts/watch.js",
40
+ "serve": "node scripts/serve.js",
41
+ "dev": "node scripts/dev.js",
42
+ "test": "node --test --test-concurrency=1 test/**/*.test.js"
43
+ },
44
+ "engines": {
45
+ "node": ">=18"
46
+ },
47
+ "publishConfig": {
48
+ "access": "public",
49
+ "registry": "https://registry.npmjs.org"
50
+ },
51
+ "dependencies": {
52
+ "chokidar": "^3.6.0",
53
+ "fast-glob": "^3.3.3",
54
+ "fs-extra": "^11.3.0",
55
+ "nunjucks": "^3.2.4"
56
+ }
57
+ }
@@ -0,0 +1,13 @@
1
+ 'use strict';
2
+
3
+ const { runBuildCommand } = require('./commands/build-command');
4
+
5
+ runBuildCommand({
6
+ projectName: process.argv[2],
7
+ workspaceRoot: process.cwd(),
8
+ usageLine: 'npm run build -- <project-name>',
9
+ }).catch((err) => {
10
+ const message = err && err.message ? err.message : String(err);
11
+ console.error(message);
12
+ process.exitCode = 1;
13
+ });
@@ -0,0 +1,29 @@
1
+ 'use strict';
2
+
3
+ const { buildProject } = require('../lib/build-project');
4
+
5
+ /**
6
+ * build コマンドを実行します。
7
+ * @param {object} options
8
+ * @param {string|undefined} options.projectName
9
+ * @param {string} [options.workspaceRoot]
10
+ * @param {string} [options.usageLine]
11
+ * @returns {Promise<object>}
12
+ */
13
+ async function runBuildCommand(options = {}) {
14
+ const workspaceRoot = options.workspaceRoot || process.cwd();
15
+ const usageLine =
16
+ options.usageLine || 'npm run build -- <project-name>';
17
+
18
+ return buildProject(options.projectName, {
19
+ workspaceRoot,
20
+ commandName: 'build',
21
+ usageLine,
22
+ logTitle: 'ビルドが完了しました',
23
+ includeOutput: true,
24
+ });
25
+ }
26
+
27
+ module.exports = {
28
+ runBuildCommand,
29
+ };