mikuru 1.0.0 → 1.0.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/CHANGELOG.md CHANGED
@@ -1,8 +1,14 @@
1
- # Changelog
2
-
3
- ## 1.0.0
4
-
5
- - Stabilized the v1 SFC compiler surface for `.mikuru` files.
1
+ # Changelog
2
+
3
+ ## 1.0.1
4
+
5
+ - Added the `mikuru` CLI with `mikuru create [project-name]`.
6
+ - Added a Vite starter template that shows a Mikuru welcome screen and counter after setup.
7
+ - Added create CLI smoke coverage and included it in CI.
8
+
9
+ ## 1.0.0
10
+
11
+ - Stabilized the v1 SFC compiler surface for `.mikuru` files.
6
12
  - Added Vite integration, generated DOM cleanup, component props/events/slots, `defineProps`, and `defineEmits`.
7
13
  - Added `v-if` / `v-else-if` / `v-else`, `v-show`, `v-for`, `v-model`, DOM event modifiers, style injection, and basic scoped CSS support.
8
14
  - Added CI, library build checks, basic example build checks, and browser E2E coverage.
package/README.md CHANGED
@@ -90,7 +90,7 @@ v1では次の機能を対象にします。
90
90
 
91
91
  MikuruはVue完全互換を目指しません。SSR、hydration、transition、devtools、完全なテンプレート型チェック、Vue互換を名乗るための広範な仕様追従はv1後に検討します。scoped CSSはv1では基本セレクタのみを対象にし、`:global()`、深いセレクタ、複雑なネスト規則は後続課題です。
92
92
 
93
- ## 開発
93
+ ## 開発
94
94
 
95
95
  ```sh
96
96
  npm install
@@ -140,3 +140,16 @@ npm run build:dogfood
140
140
  ## 補足
141
141
 
142
142
  Mikuru v1は、Vue完全互換ではなく小さなVue風SFCサブセットです。設計文書、対応構文、非対応構文、リリース前チェック項目などの詳細文書は内部資料として扱います。
143
+
144
+ ## Starter
145
+
146
+ 新しいMikuruアプリはCLIから作成できます。
147
+
148
+ ```sh
149
+ npx mikuru create my-app
150
+ cd my-app
151
+ npm install
152
+ npm run dev
153
+ ```
154
+
155
+ 生成されるスターターは、Viteの初期画面のようにMikuruのウェルカム画面を表示します。`src/App.mikuru` を編集するとHMRで画面が更新されます。
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/cli.js ADDED
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env node
2
+ import { copyFileSync, existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from "node:fs";
3
+ import { basename, dirname, join, resolve } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ const command = process.argv[2];
6
+ const targetArg = process.argv[3];
7
+ if (command === "--help" || command === "-h" || !command) {
8
+ printHelp();
9
+ process.exit(0);
10
+ }
11
+ if (command !== "create") {
12
+ console.error(`Unknown command: ${command}`);
13
+ printHelp();
14
+ process.exit(1);
15
+ }
16
+ const targetDir = resolve(process.cwd(), targetArg ?? "mikuru-app");
17
+ const appName = toPackageName(basename(targetDir));
18
+ if (existsSync(targetDir) && readdirSync(targetDir).length > 0) {
19
+ console.error(`Target directory is not empty: ${targetDir}`);
20
+ process.exit(1);
21
+ }
22
+ const templateDir = resolve(dirname(fileURLToPath(import.meta.url)), "../templates/starter");
23
+ copyTemplate(templateDir, targetDir, { appName });
24
+ console.log(`Created ${appName} in ${targetDir}`);
25
+ console.log("");
26
+ console.log("Next steps:");
27
+ console.log(` cd ${basename(targetDir)}`);
28
+ console.log(" npm install");
29
+ console.log(" npm run dev");
30
+ function printHelp() {
31
+ console.log("Usage:");
32
+ console.log(" mikuru create [project-name]");
33
+ }
34
+ function copyTemplate(sourceDir, targetDir, variables) {
35
+ mkdirSync(targetDir, { recursive: true });
36
+ for (const entry of readdirSync(sourceDir)) {
37
+ const sourcePath = join(sourceDir, entry);
38
+ const targetName = entry === "_gitignore" ? ".gitignore" : entry;
39
+ const targetPath = join(targetDir, targetName);
40
+ const stat = statSync(sourcePath);
41
+ if (stat.isDirectory()) {
42
+ copyTemplate(sourcePath, targetPath, variables);
43
+ continue;
44
+ }
45
+ if (isTextTemplate(sourcePath)) {
46
+ const content = readFileSync(sourcePath, "utf8").replaceAll("__MIKURU_APP_NAME__", variables.appName);
47
+ writeFileSync(targetPath, content);
48
+ continue;
49
+ }
50
+ copyFileSync(sourcePath, targetPath);
51
+ }
52
+ }
53
+ function isTextTemplate(path) {
54
+ return /\.(css|html|json|mikuru|ts)$/.test(path) || path.endsWith("_gitignore");
55
+ }
56
+ function toPackageName(value) {
57
+ return value
58
+ .trim()
59
+ .toLowerCase()
60
+ .replace(/[^a-z0-9._-]+/g, "-")
61
+ .replace(/^-+|-+$/g, "") || "mikuru-app";
62
+ }
63
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,18 +1,18 @@
1
1
  {
2
2
  "name": "mikuru",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "private": false,
5
- "type": "module",
6
- "description": "A compile-first JavaScript framework with Vue-like authoring and Svelte-like generated DOM updates.",
7
- "homepage": "https://github.com/miyagawayuu/mikuru#readme",
8
- "bugs": {
9
- "url": "https://github.com/miyagawayuu/mikuru/issues"
10
- },
11
- "repository": {
12
- "type": "git",
13
- "url": "git+https://github.com/miyagawayuu/mikuru.git"
14
- },
15
- "exports": {
5
+ "type": "module",
6
+ "description": "A compile-first JavaScript framework with Vue-like authoring and Svelte-like generated DOM updates.",
7
+ "homepage": "https://github.com/miyagawayuu/mikuru#readme",
8
+ "bugs": {
9
+ "url": "https://github.com/miyagawayuu/mikuru/issues"
10
+ },
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "git+https://github.com/miyagawayuu/mikuru.git"
14
+ },
15
+ "exports": {
16
16
  ".": {
17
17
  "types": "./dist/index.d.ts",
18
18
  "default": "./dist/index.js"
@@ -30,11 +30,15 @@
30
30
  "default": "./dist/vite.js"
31
31
  }
32
32
  },
33
- "files": [
34
- "dist",
35
- "README.md",
36
- "CHANGELOG.md"
37
- ],
33
+ "bin": {
34
+ "mikuru": "dist/cli.js"
35
+ },
36
+ "files": [
37
+ "dist",
38
+ "templates",
39
+ "README.md",
40
+ "CHANGELOG.md"
41
+ ],
38
42
  "engines": {
39
43
  "node": ">=22"
40
44
  },
@@ -45,15 +49,16 @@
45
49
  "build:realworld": "vite build --config examples/realworld/vite.config.ts",
46
50
  "build:mikuru-sample": "vite build --config examples/mikuru-sample/vite.config.ts",
47
51
  "build:mikuru-vue-like": "vite build --config examples/mikuru-vue-like/vite.config.ts",
48
- "ci": "npm run typecheck && npm test && npm run build && npm run build:basic && npm run build:realworld && npm run build:dogfood && npm run test:package && npm run test:pack && npm run test:e2e && npm run test:e2e:dogfood",
52
+ "ci": "npm run typecheck && npm test && npm run build && npm run test:create && npm run build:basic && npm run build:realworld && npm run build:dogfood && npm run test:package && npm run test:pack && npm run test:e2e && npm run test:e2e:dogfood",
49
53
  "dev:basic": "vite --config examples/basic/vite.config.ts",
50
- "dev:dogfood": "vite --config examples/dogfood/vite.config.ts",
51
- "dev:realworld": "vite --config examples/realworld/vite.config.ts",
52
- "dev:mikuru-sample": "vite --config examples/mikuru-sample/vite.config.ts",
53
- "dev:mikuru-vue-like": "vite --config examples/mikuru-vue-like/vite.config.ts",
54
+ "dev:dogfood": "vite --config examples/dogfood/vite.config.ts",
55
+ "dev:realworld": "vite --config examples/realworld/vite.config.ts",
56
+ "dev:mikuru-sample": "vite --config examples/mikuru-sample/vite.config.ts",
57
+ "dev:mikuru-vue-like": "vite --config examples/mikuru-vue-like/vite.config.ts",
54
58
  "test": "vitest run",
55
59
  "test:e2e": "playwright test",
56
60
  "test:e2e:dogfood": "playwright test --config playwright.dogfood.config.ts",
61
+ "test:create": "node tests/create-cli-smoke.mjs",
57
62
  "test:pack": "node tests/npm-pack-smoke.mjs",
58
63
  "test:package": "node tests/package-usage.mjs",
59
64
  "typecheck": "tsc -p tsconfig.json --noEmit"
@@ -0,0 +1,3 @@
1
+ node_modules
2
+ dist
3
+ *.local
@@ -0,0 +1,12 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Mikuru App</title>
7
+ </head>
8
+ <body>
9
+ <div id="app"></div>
10
+ <script type="module" src="/src/main.ts"></script>
11
+ </body>
12
+ </html>
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "__MIKURU_APP_NAME__",
3
+ "private": true,
4
+ "version": "0.0.0",
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "vite",
8
+ "build": "vite build",
9
+ "preview": "vite preview"
10
+ },
11
+ "dependencies": {
12
+ "mikuru": "^1.0.1"
13
+ },
14
+ "devDependencies": {
15
+ "typescript": "^6.0.3",
16
+ "vite": "^8.0.10"
17
+ }
18
+ }
@@ -0,0 +1,38 @@
1
+ <template>
2
+ <main class="shell">
3
+ <section class="hero">
4
+ <div class="mark">み</div>
5
+ <p class="eyebrow">Mikuru is ready</p>
6
+ <h1>Make tiny Vue-like apps feel sweet and fast.</h1>
7
+ <p class="summary">
8
+ Edit <code>src/App.mikuru</code> and save to test Mikuru with Vite HMR.
9
+ </p>
10
+ <button @click="increment">count: {{ count }}</button>
11
+ </section>
12
+
13
+ <section class="grid">
14
+ <article>
15
+ <h2>Template</h2>
16
+ <p>Write friendly SFC templates with interpolation, events, lists, and form models.</p>
17
+ </article>
18
+ <article>
19
+ <h2>Runtime</h2>
20
+ <p>Keep state small with <code>ref</code>, <code>computed</code>, and direct DOM updates.</p>
21
+ </article>
22
+ <article>
23
+ <h2>Compiler</h2>
24
+ <p>Compile SFCs into lightweight browser code without bringing a virtual DOM.</p>
25
+ </article>
26
+ </section>
27
+ </main>
28
+ </template>
29
+
30
+ <script>
31
+ import { ref } from "mikuru";
32
+
33
+ const count = ref(0);
34
+
35
+ function increment() {
36
+ count.value += 1;
37
+ }
38
+ </script>
@@ -0,0 +1,10 @@
1
+ import { mount } from "./App.mikuru";
2
+ import "./style.css";
3
+
4
+ const app = document.querySelector<HTMLDivElement>("#app");
5
+
6
+ if (!app) {
7
+ throw new Error("Missing #app");
8
+ }
9
+
10
+ mount(app);
@@ -0,0 +1,17 @@
1
+ declare module "*.mikuru" {
2
+ export type MikuruComponentInstance = {
3
+ element: Element | Comment;
4
+ unmount(): void;
5
+ };
6
+
7
+ export function mount(
8
+ target: Element | DocumentFragment,
9
+ props?: Record<string, unknown>
10
+ ): MikuruComponentInstance;
11
+
12
+ const component: {
13
+ mount: typeof mount;
14
+ };
15
+
16
+ export default component;
17
+ }
@@ -0,0 +1,151 @@
1
+ :root {
2
+ color: #3a2430;
3
+ background:
4
+ radial-gradient(circle at 18% 12%, rgba(255, 176, 211, 0.38), transparent 28%),
5
+ radial-gradient(circle at 82% 8%, rgba(255, 218, 235, 0.72), transparent 24%),
6
+ #fff7fb;
7
+ font-family:
8
+ Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
9
+ font-synthesis: none;
10
+ text-rendering: optimizeLegibility;
11
+ }
12
+
13
+ * {
14
+ box-sizing: border-box;
15
+ }
16
+
17
+ body {
18
+ min-width: 320px;
19
+ min-height: 100vh;
20
+ margin: 0;
21
+ }
22
+
23
+ button {
24
+ border: 1px solid #ff8abc;
25
+ border-radius: 999px;
26
+ background: #ff5fa2;
27
+ color: #ffffff;
28
+ cursor: pointer;
29
+ font: inherit;
30
+ font-weight: 700;
31
+ padding: 11px 18px;
32
+ box-shadow: 0 12px 26px rgba(255, 95, 162, 0.24);
33
+ }
34
+
35
+ button:hover {
36
+ background: #f34f96;
37
+ }
38
+
39
+ code {
40
+ border-radius: 6px;
41
+ background: #fff0f7;
42
+ color: #d93282;
43
+ padding: 2px 6px;
44
+ }
45
+
46
+ .shell {
47
+ width: min(1040px, calc(100vw - 32px));
48
+ margin: 0 auto;
49
+ padding: 72px 0;
50
+ }
51
+
52
+ .hero {
53
+ display: grid;
54
+ justify-items: center;
55
+ gap: 18px;
56
+ min-height: 520px;
57
+ align-content: center;
58
+ border: 1px solid #ffd2e4;
59
+ border-radius: 28px 28px 0 0;
60
+ background:
61
+ linear-gradient(180deg, rgba(255, 255, 255, 0.92), rgba(255, 244, 250, 0.96)),
62
+ #ffffff;
63
+ box-shadow: 0 24px 70px rgba(217, 50, 130, 0.14);
64
+ text-align: center;
65
+ }
66
+
67
+ .mark {
68
+ display: grid;
69
+ width: 84px;
70
+ height: 84px;
71
+ place-items: center;
72
+ border: 1px solid #ffb6d4;
73
+ border-radius: 26px;
74
+ background: linear-gradient(135deg, #ff6faf, #ffc1dc);
75
+ color: #ffffff;
76
+ font-size: 40px;
77
+ font-weight: 800;
78
+ box-shadow: 0 18px 34px rgba(255, 111, 175, 0.32);
79
+ }
80
+
81
+ .eyebrow {
82
+ margin: 0;
83
+ color: #e24e91;
84
+ font-size: 14px;
85
+ font-weight: 700;
86
+ letter-spacing: 0;
87
+ text-transform: uppercase;
88
+ }
89
+
90
+ h1 {
91
+ max-width: 760px;
92
+ margin: 0;
93
+ font-size: 56px;
94
+ font-weight: 750;
95
+ line-height: 1.05;
96
+ }
97
+
98
+ .summary {
99
+ max-width: 560px;
100
+ margin: 0;
101
+ color: #7b5b6a;
102
+ font-size: 18px;
103
+ line-height: 1.7;
104
+ }
105
+
106
+ .grid {
107
+ display: grid;
108
+ grid-template-columns: repeat(3, minmax(0, 1fr));
109
+ gap: 1px;
110
+ overflow: hidden;
111
+ border: 1px solid #ffd2e4;
112
+ border-top: 0;
113
+ border-radius: 0 0 28px 28px;
114
+ background: #ffd2e4;
115
+ }
116
+
117
+ article {
118
+ min-height: 180px;
119
+ padding: 28px;
120
+ background: rgba(255, 255, 255, 0.78);
121
+ }
122
+
123
+ h2 {
124
+ margin: 0 0 12px;
125
+ font-size: 22px;
126
+ }
127
+
128
+ article p {
129
+ margin: 0;
130
+ color: #7b5b6a;
131
+ line-height: 1.65;
132
+ }
133
+
134
+ @media (max-width: 760px) {
135
+ .shell {
136
+ padding: 24px 0;
137
+ }
138
+
139
+ .hero {
140
+ min-height: 460px;
141
+ padding: 32px 20px;
142
+ }
143
+
144
+ h1 {
145
+ font-size: 38px;
146
+ }
147
+
148
+ .grid {
149
+ grid-template-columns: 1fr;
150
+ }
151
+ }
@@ -0,0 +1,6 @@
1
+ import { defineConfig } from "vite";
2
+ import { mikuru } from "mikuru/vite";
3
+
4
+ export default defineConfig({
5
+ plugins: [mikuru()]
6
+ });