@evjs/cli 0.0.1-rc.15 → 0.0.1-rc.17

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/README.md CHANGED
@@ -8,7 +8,7 @@
8
8
  npm install -g @evjs/cli
9
9
  ```
10
10
 
11
- ## Zero-Config
11
+ ## Convention over Configuration
12
12
 
13
13
  No configuration file is needed. `ev dev` and `ev build` work out of the box with sensible defaults:
14
14
 
@@ -65,3 +65,35 @@ export default defineConfig({
65
65
  ```
66
66
 
67
67
  The `client.dev` and `server.dev` fields accept extra options that are merged with defaults.
68
+
69
+ ## Project Structure
70
+
71
+ ```
72
+ my-app/
73
+ ├── ev.config.ts # optional config
74
+ ├── index.html # HTML template
75
+ ├── package.json
76
+ ├── tsconfig.json
77
+ └── src/
78
+ ├── main.tsx # app bootstrap (keep minimal)
79
+ ├── routes.tsx # route tree + components
80
+ ├── api/ # server functions
81
+ │ ├── users.server.ts
82
+ │ └── posts.server.ts
83
+ └── middleware/ # server middleware (optional)
84
+ └── auth.ts
85
+ ```
86
+
87
+ ## Common Mistakes
88
+
89
+ 1. **Don't create `webpack.config.cjs`** — use `ev.config.ts` instead
90
+ 2. **Don't install webpack manually** — it's a dependency of `@evjs/cli`
91
+ 3. **Config file must be `ev.config.ts`** — not `evjs.config.ts`
92
+ 4. **Import `defineConfig` from `@evjs/cli`** — not from `@evjs/runtime`
93
+
94
+ ## Bundled Dependencies
95
+
96
+ Users do NOT need to install these — they're included in `@evjs/cli`:
97
+ - `webpack`, `webpack-dev-server`
98
+ - `html-webpack-plugin`, `swc-loader`, `@swc/core`
99
+ - `@evjs/webpack-plugin`, `@evjs/build-tools`
package/dist/index.js CHANGED
@@ -109,14 +109,14 @@ program
109
109
  /**
110
110
  * Load config and create webpack configuration object.
111
111
  *
112
- * Uses ev.config.ts when present, otherwise falls back to zero-config defaults.
112
+ * Uses ev.config.ts when present, otherwise falls back to convention-based defaults.
113
113
  * No webpack.config.cjs fallback — the meta-framework owns the build config.
114
114
  */
115
115
  async function resolveWebpackConfig(cwd) {
116
116
  const { loadConfig } = await import("./load-config.js");
117
117
  const evjsConfig = await loadConfig(cwd);
118
118
  const { createWebpackConfig } = await import("./create-webpack-config.js");
119
- logger.info `Using ${evjsConfig ? "ev.config.ts" : "zero-config defaults"}`;
119
+ logger.info `Using ${evjsConfig ? "ev.config.ts" : "convention-based defaults"}`;
120
120
  const webpackConfig = createWebpackConfig(evjsConfig, cwd);
121
121
  return { evjsConfig, webpackConfig };
122
122
  }
@@ -136,51 +136,49 @@ program
136
136
  const devServerOptions = webpackConfig.devServer ?? {};
137
137
  const server = new WebpackDevServer(devServerOptions, compiler);
138
138
  await server.start();
139
- // Background: wait for server bundle, then start Node API
140
- void (async () => {
139
+ // Background: start Node API when server bundle is ready
140
+ let apiStarted = false;
141
+ compiler.hooks.done.tap("EvDevServer", async () => {
142
+ if (apiStarted)
143
+ return;
141
144
  const manifestPath = path.resolve(cwd, "dist/manifest.json");
142
145
  const bootstrapPath = path.resolve(cwd, "dist/server/_dev_start.cjs");
143
- let started = false;
144
- while (true) {
145
- if (fs.existsSync(manifestPath)) {
146
- if (!started) {
147
- const runnerConfig = evjsConfig?.server?.runner ?? "node";
148
- const [runner, ...runnerExtraArgs] = runnerConfig.split(/\s+/);
149
- logger.info `Server bundle detected, starting ${runner} API...`;
150
- started = true;
151
- const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf-8"));
152
- const serverBundlePath = path.resolve(cwd, "dist/server", manifest.server.entry);
153
- fs.writeFileSync(bootstrapPath, [
154
- `const bundle = require(${JSON.stringify(serverBundlePath)});`,
155
- `const app = bundle.createApp({ endpoint: ${JSON.stringify(evjsConfig?.server?.endpoint ?? CONFIG_DEFAULTS.endpoint)} });`,
156
- `const { serve } = require("@evjs/runtime/server/node");`,
157
- `serve(app, { port: ${serverPort} });`,
158
- ].join("\n"));
159
- // node gets --watch flags; other runtimes use their own args as-is
160
- const runnerArgs = runner === "node"
161
- ? [
162
- "--watch",
163
- "--watch-preserve-output",
164
- ...runnerExtraArgs,
165
- bootstrapPath,
166
- ]
167
- : [...runnerExtraArgs, bootstrapPath];
168
- try {
169
- await execa(runner, runnerArgs, {
170
- stdio: "inherit",
171
- env: { ...process.env, NODE_ENV: "development" },
172
- });
173
- }
174
- catch (_e) {
175
- started = false;
176
- }
177
- }
146
+ if (fs.existsSync(manifestPath)) {
147
+ apiStarted = true;
148
+ const backendConfig = evjsConfig?.server?.backend ?? "node";
149
+ const [backend, ...backendExtraArgs] = backendConfig.split(/\s+/);
150
+ logger.info `Server bundle detected, starting ${backend} API...`;
151
+ try {
152
+ const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf-8"));
153
+ const serverBundlePath = path.resolve(cwd, "dist/server", manifest.server.entry);
154
+ fs.writeFileSync(bootstrapPath, [
155
+ `const bundle = require(${JSON.stringify(serverBundlePath)});`,
156
+ `const app = bundle.createApp({ endpoint: ${JSON.stringify(evjsConfig?.server?.endpoint ?? CONFIG_DEFAULTS.endpoint)} });`,
157
+ `const { serve } = require("@evjs/runtime/server/node");`,
158
+ `serve(app, { port: ${serverPort} });`,
159
+ ].join("\n"));
160
+ // node gets --watch flags; other runtimes use their own args as-is
161
+ const backendArgs = backend === "node"
162
+ ? [
163
+ "--watch",
164
+ "--watch-preserve-output",
165
+ ...backendExtraArgs,
166
+ bootstrapPath,
167
+ ]
168
+ : [...backendExtraArgs, bootstrapPath];
169
+ // Don't await execa here since it's a long-running watch process
170
+ execa(backend, backendArgs, {
171
+ stdio: "inherit",
172
+ env: { ...process.env, NODE_ENV: "development" },
173
+ }).catch(() => {
174
+ apiStarted = false;
175
+ });
176
+ }
177
+ catch (err) {
178
+ logger.error `Server backend failed: ${err}`;
179
+ apiStarted = false;
178
180
  }
179
- await new Promise((r) => setTimeout(r, 500));
180
181
  }
181
- })().catch((err) => {
182
- logger.error `Server runner failed: ${err}`;
183
- process.exit(1);
184
182
  });
185
183
  }
186
184
  catch (err) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@evjs/cli",
3
- "version": "0.0.1-rc.15",
3
+ "version": "0.0.1-rc.17",
4
4
  "description": "CLI and configuration layer for the evjs framework",
5
5
  "type": "module",
6
6
  "main": "./dist/config.js",
@@ -19,8 +19,7 @@
19
19
  },
20
20
  "files": [
21
21
  "dist",
22
- "templates",
23
- "AGENT.md"
22
+ "templates"
24
23
  ],
25
24
  "scripts": {
26
25
  "build": "tsc",
@@ -30,9 +29,9 @@
30
29
  "prepare": "npm run build"
31
30
  },
32
31
  "dependencies": {
33
- "@evjs/webpack-plugin": "0.0.1-rc.15",
32
+ "@evjs/webpack-plugin": "*",
34
33
  "@logtape/logtape": "^2.0.4",
35
- "@swc/core": "^1.2.147",
34
+ "@swc/core": "^1.15.18",
36
35
  "commander": "^12.1.0",
37
36
  "execa": "^9.5.2",
38
37
  "fs-extra": "^11.3.0",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "example-basic-csr",
3
- "version": "0.0.1-rc.8",
3
+ "version": "0.0.0",
4
4
  "private": true,
5
5
  "scripts": {
6
6
  "dev": "ev dev",
@@ -8,12 +8,12 @@
8
8
  "check-types": "tsc --noEmit"
9
9
  },
10
10
  "dependencies": {
11
- "@evjs/runtime": "^0.0.1-rc.15",
11
+ "@evjs/runtime": "*",
12
12
  "react": "^19.2.4",
13
13
  "react-dom": "^19.2.4"
14
14
  },
15
15
  "devDependencies": {
16
- "@evjs/cli": "^0.0.1-rc.5",
16
+ "@evjs/cli": "*",
17
17
  "@types/react": "^19.0.8",
18
18
  "@types/react-dom": "^19.0.3",
19
19
  "typescript": "^5.7.3"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "example-basic-server-fns",
3
- "version": "0.0.1-rc.8",
3
+ "version": "0.0.0",
4
4
  "private": true,
5
5
  "scripts": {
6
6
  "dev": "ev dev",
@@ -8,12 +8,12 @@
8
8
  "check-types": "tsc --noEmit"
9
9
  },
10
10
  "dependencies": {
11
- "@evjs/runtime": "^0.0.1-rc.15",
11
+ "@evjs/runtime": "*",
12
12
  "react": "^19.2.4",
13
13
  "react-dom": "^19.2.4"
14
14
  },
15
15
  "devDependencies": {
16
- "@evjs/cli": "^0.0.1-rc.5",
16
+ "@evjs/cli": "*",
17
17
  "@types/react": "^19.1.8",
18
18
  "@types/react-dom": "^19.1.8",
19
19
  "typescript": "^5.7.3"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "example-complex-routing",
3
- "version": "0.0.1-rc.8",
3
+ "version": "0.0.0",
4
4
  "private": true,
5
5
  "scripts": {
6
6
  "dev": "ev dev",
@@ -8,12 +8,12 @@
8
8
  "check-types": "tsc --noEmit"
9
9
  },
10
10
  "dependencies": {
11
- "@evjs/runtime": "^0.0.1-rc.15",
11
+ "@evjs/runtime": "*",
12
12
  "react": "^19.2.4",
13
13
  "react-dom": "^19.2.4"
14
14
  },
15
15
  "devDependencies": {
16
- "@evjs/cli": "^0.0.1-rc.5",
16
+ "@evjs/cli": "*",
17
17
  "@types/react": "^19.0.8",
18
18
  "@types/react-dom": "^19.0.3",
19
19
  "typescript": "^5.7.3"
@@ -4,7 +4,7 @@ import { defineConfig } from "@evjs/cli";
4
4
  * Advanced ev.config.ts example.
5
5
  *
6
6
  * This file demonstrates all available configuration options.
7
- * All fields are optional — evjs works zero-config out of the box.
7
+ * All fields are optional — evjs works out of the box.
8
8
  */
9
9
  export default defineConfig({
10
10
  client: {
@@ -39,9 +39,9 @@ export default defineConfig({
39
39
  // Server function endpoint path (default: "/api/fn")
40
40
  endpoint: "/api/fn",
41
41
 
42
- // Server runner module (default: "@evjs/runtime/server/node")
42
+ // Server backend module (default: "@evjs/runtime/server/node")
43
43
  // For Deno/Bun/Workers, use: "@evjs/runtime/server/ecma"
44
- runner: "@evjs/runtime/server/node",
44
+ backend: "@evjs/runtime/server/node",
45
45
 
46
46
  // Middleware module paths to auto-register in server entry
47
47
  // These are imported and applied in order
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "example-configured-server-fns",
3
- "version": "0.0.1-rc.8",
3
+ "version": "0.0.0",
4
4
  "private": true,
5
5
  "scripts": {
6
6
  "dev": "ev dev",
@@ -8,12 +8,12 @@
8
8
  "check-types": "tsc --noEmit"
9
9
  },
10
10
  "dependencies": {
11
- "@evjs/runtime": "^0.0.1-rc.15",
11
+ "@evjs/runtime": "*",
12
12
  "react": "^19.2.4",
13
13
  "react-dom": "^19.2.4"
14
14
  },
15
15
  "devDependencies": {
16
- "@evjs/cli": "^0.0.1-rc.5",
16
+ "@evjs/cli": "*",
17
17
  "@types/react": "^19.1.8",
18
18
  "@types/react-dom": "^19.1.8",
19
19
  "typescript": "^5.7.3"
package/AGENT.md DELETED
@@ -1,121 +0,0 @@
1
- # @evjs/cli — Agent Guide
2
-
3
- > AI-agent reference for developing apps with the `@evjs/cli` package.
4
-
5
- ## Overview
6
-
7
- `@evjs/cli` is the CLI and configuration layer. Users install it as a devDependency. It provides:
8
-
9
- - **`ev init`** — scaffold a new project from templates
10
- - **`ev dev`** — start dev server (webpack-dev-server + API server)
11
- - **`ev build`** — production build (client + server bundles)
12
- - **`defineConfig`** — type-safe config export for `ev.config.ts`
13
-
14
- ## Quick Start
15
-
16
- ```bash
17
- npx @evjs/cli@latest init my-app
18
- cd my-app && npm install
19
- ev dev # http://localhost:3000
20
- ```
21
-
22
- ## Configuration (`ev.config.ts`)
23
-
24
- Optional — everything works zero-config. Create `ev.config.ts` in project root when needed:
25
-
26
- ```ts
27
- import { defineConfig } from "@evjs/cli";
28
-
29
- export default defineConfig({
30
- client: {
31
- entry: "./src/main.tsx", // default
32
- html: "./index.html", // default
33
- dev: {
34
- port: 3000, // webpack-dev-server port
35
- open: true, // auto-open browser
36
- https: false, // enable HTTPS
37
- historyApiFallback: true, // SPA routing fallback
38
- },
39
- transport: {
40
- baseUrl: "", // API base URL (for separate API host)
41
- endpoint: "/api/fn", // server function endpoint path
42
- },
43
- },
44
- server: {
45
- endpoint: "/api/fn", // must match client transport endpoint
46
- runner: "@evjs/runtime/server/node",
47
- middleware: [
48
- "./src/middleware/auth.ts", // middleware module paths
49
- "./src/middleware/logging.ts",
50
- ],
51
- dev: {
52
- port: 3001, // API server port in dev mode
53
- },
54
- },
55
- });
56
- ```
57
-
58
- ### Config Defaults
59
-
60
- | Key | Default |
61
- |-----|---------|
62
- | `client.entry` | `"./src/main.tsx"` |
63
- | `client.html` | `"./index.html"` |
64
- | `client.dev.port` | `3000` |
65
- | `server.endpoint` | `"/api/fn"` |
66
- | `server.dev.port` | `3001` |
67
- | `server.runner` | `"@evjs/runtime/server/node"` |
68
-
69
- ## Project Structure
70
-
71
- ```
72
- my-app/
73
- ├── ev.config.ts # optional config
74
- ├── index.html # HTML template
75
- ├── package.json
76
- ├── tsconfig.json
77
- └── src/
78
- ├── main.tsx # app bootstrap (keep minimal)
79
- ├── routes.tsx # route tree + components
80
- ├── api/ # server functions
81
- │ ├── users.server.ts
82
- │ └── posts.server.ts
83
- └── middleware/ # server middleware (optional)
84
- └── auth.ts
85
- ```
86
-
87
- ## CLI Commands
88
-
89
- ### `ev init [project-name]`
90
- Interactive scaffolding. Templates:
91
- - `basic-csr` — client-side rendering only
92
- - `basic-server-fns` — server functions example
93
- - `configured-server-fns` — advanced config example
94
- - `complex-routing` — params, search, layouts, loaders
95
-
96
- ### `ev dev`
97
- - Starts webpack-dev-server on port 3000
98
- - Auto-starts API server on port 3001
99
- - Proxies `/api/fn` requests to API server
100
- - Hot reloads client; restarts server on changes
101
- - `NODE_ENV=development`
102
-
103
- ### `ev build`
104
- - Outputs client bundle to `dist/client/`
105
- - Outputs server bundle to `dist/server/`
106
- - Emits `dist/manifest.json` with server function registry
107
- - `NODE_ENV=production`
108
-
109
- ## Common Mistakes
110
-
111
- 1. **Don't create `webpack.config.cjs`** — use `ev.config.ts` instead
112
- 2. **Don't install webpack manually** — it's a dependency of `@evjs/cli`
113
- 3. **Config file must be `ev.config.ts`** — not `evjs.config.ts` or `evjs.config.ts`
114
- 4. **Import `defineConfig` from `@evjs/cli`** — not from `@evjs/runtime`
115
-
116
- ## Dependencies (bundled)
117
-
118
- Users do NOT need to install these — they're included in `@evjs/cli`:
119
- - `webpack`, `webpack-dev-server`, `webpack-cli`
120
- - `html-webpack-plugin`, `swc-loader`, `@swc/core`
121
- - `@evjs/webpack-plugin`