exportc 0.0.4 → 0.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.
- package/README.md +33 -28
- package/commands/init.js +90 -37
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# exportc
|
|
2
2
|
|
|
3
|
-
Add [export](https://github.com/ihasq/export) to existing Vite projects.
|
|
3
|
+
Add [export](https://github.com/ihasq/export) to existing Vite projects. One command sets up server-side functions with full TypeScript support.
|
|
4
4
|
|
|
5
5
|
## Quick Start
|
|
6
6
|
|
|
@@ -8,9 +8,6 @@ Add [export](https://github.com/ihasq/export) to existing Vite projects.
|
|
|
8
8
|
# In your existing Vite project
|
|
9
9
|
npx exportc init
|
|
10
10
|
|
|
11
|
-
# Install export dependencies
|
|
12
|
-
cd export && npm install && cd ..
|
|
13
|
-
|
|
14
11
|
# Start development (Wrangler starts automatically!)
|
|
15
12
|
npm run dev
|
|
16
13
|
|
|
@@ -18,6 +15,15 @@ npm run dev
|
|
|
18
15
|
npm run export
|
|
19
16
|
```
|
|
20
17
|
|
|
18
|
+
That's it. Dependencies are installed automatically.
|
|
19
|
+
|
|
20
|
+
## What You Get
|
|
21
|
+
|
|
22
|
+
- **Single command dev** -- `npm run dev` starts both Vite and Wrangler
|
|
23
|
+
- **Auto-generated types** -- TypeScript definitions from your actual code
|
|
24
|
+
- **Workers Sites deploy** -- Static assets + server exports in one deployment
|
|
25
|
+
- **Zero config** -- Production URL auto-detected from package name
|
|
26
|
+
|
|
21
27
|
## Usage
|
|
22
28
|
|
|
23
29
|
After initialization, import your server exports using the `export/` prefix:
|
|
@@ -34,24 +40,17 @@ await counter.increment(); // 1
|
|
|
34
40
|
|
|
35
41
|
## Commands
|
|
36
42
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
### `exportc dev`
|
|
45
|
-
|
|
46
|
-
Start the Wrangler development server for your exports.
|
|
47
|
-
|
|
48
|
-
### `exportc deploy`
|
|
49
|
-
|
|
50
|
-
Deploy your exports to Cloudflare Workers.
|
|
43
|
+
| Command | Description |
|
|
44
|
+
|---------|-------------|
|
|
45
|
+
| `npm run dev` | Start Vite + Wrangler together, auto-generate types |
|
|
46
|
+
| `npm run export` | Build Vite app and deploy to Workers Sites |
|
|
47
|
+
| `exportc init` | Initialize export in your project |
|
|
48
|
+
| `exportc dev` | Start Wrangler dev server standalone |
|
|
49
|
+
| `exportc deploy` | Deploy exports only |
|
|
51
50
|
|
|
52
51
|
## Vite Plugin
|
|
53
52
|
|
|
54
|
-
The `exportPlugin`
|
|
53
|
+
The `exportPlugin` handles everything automatically:
|
|
55
54
|
|
|
56
55
|
```typescript
|
|
57
56
|
// vite.config.ts
|
|
@@ -67,15 +66,20 @@ export default defineConfig({
|
|
|
67
66
|
});
|
|
68
67
|
```
|
|
69
68
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
69
|
+
### Development (`npm run dev`)
|
|
70
|
+
|
|
71
|
+
1. Automatically starts Wrangler dev server in the background
|
|
72
|
+
2. Waits for it to be ready before serving your app
|
|
73
|
+
3. Generates `export-env.d.ts` with TypeScript declarations
|
|
74
|
+
4. Watches for changes and regenerates types automatically
|
|
75
|
+
5. Transforms `export/` imports to `http://localhost:8787`
|
|
76
|
+
|
|
77
|
+
### Production (`npm run export`)
|
|
74
78
|
|
|
75
|
-
|
|
76
|
-
1. Builds Vite app
|
|
79
|
+
1. Builds your Vite app
|
|
77
80
|
2. Deploys to Workers Sites (static assets + server exports)
|
|
78
81
|
3. `export/` imports resolve to `https://{worker-name}.workers.dev`
|
|
82
|
+
4. Everything runs on Cloudflare's edge network
|
|
79
83
|
|
|
80
84
|
## Project Structure
|
|
81
85
|
|
|
@@ -83,11 +87,12 @@ After running `exportc init`:
|
|
|
83
87
|
|
|
84
88
|
```
|
|
85
89
|
my-vite-app/
|
|
86
|
-
├── src/ # Your Vite app
|
|
90
|
+
├── src/ # Your Vite app (unchanged)
|
|
87
91
|
├── export/ # Server exports (Cloudflare Worker)
|
|
88
92
|
│ ├── index.ts # Your server code
|
|
89
|
-
│
|
|
90
|
-
|
|
93
|
+
│ ├── package.json # Worker configuration
|
|
94
|
+
│ └── .gitignore # Generated files excluded
|
|
95
|
+
├── export-env.d.ts # TypeScript declarations (auto-generated)
|
|
91
96
|
└── vite.config.ts # Updated with exportPlugin
|
|
92
97
|
```
|
|
93
98
|
|
package/commands/init.js
CHANGED
|
@@ -3,19 +3,27 @@ import pc from "picocolors";
|
|
|
3
3
|
import fs from "node:fs";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
|
+
import { execSync } from "node:child_process";
|
|
6
7
|
|
|
7
8
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
8
9
|
|
|
9
10
|
export async function init(argv) {
|
|
10
11
|
const cwd = process.cwd();
|
|
12
|
+
const isNonInteractive = argv.yes || argv.y || process.env.CI === "true";
|
|
11
13
|
|
|
12
|
-
|
|
14
|
+
if (!isNonInteractive) {
|
|
15
|
+
p.intro(pc.bgCyan(pc.black(" exportc init ")));
|
|
16
|
+
}
|
|
13
17
|
|
|
14
18
|
// Check for Vite project
|
|
15
19
|
const viteConfigFiles = ["vite.config.ts", "vite.config.js", "vite.config.mts", "vite.config.mjs"];
|
|
16
20
|
const viteConfig = viteConfigFiles.find((f) => fs.existsSync(path.join(cwd, f)));
|
|
17
21
|
|
|
18
22
|
if (!viteConfig) {
|
|
23
|
+
if (isNonInteractive) {
|
|
24
|
+
console.error("Error: No Vite config found. exportc currently only supports Vite projects.");
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
19
27
|
p.cancel("No Vite config found. exportc currently only supports Vite projects.");
|
|
20
28
|
process.exit(1);
|
|
21
29
|
}
|
|
@@ -23,6 +31,10 @@ export async function init(argv) {
|
|
|
23
31
|
// Check for package.json
|
|
24
32
|
const pkgPath = path.join(cwd, "package.json");
|
|
25
33
|
if (!fs.existsSync(pkgPath)) {
|
|
34
|
+
if (isNonInteractive) {
|
|
35
|
+
console.error("Error: No package.json found.");
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
26
38
|
p.cancel("No package.json found.");
|
|
27
39
|
process.exit(1);
|
|
28
40
|
}
|
|
@@ -31,7 +43,7 @@ export async function init(argv) {
|
|
|
31
43
|
|
|
32
44
|
// Check if already initialized
|
|
33
45
|
const exportDir = path.join(cwd, "export");
|
|
34
|
-
if (fs.existsSync(exportDir)) {
|
|
46
|
+
if (fs.existsSync(exportDir) && !isNonInteractive) {
|
|
35
47
|
const overwrite = await p.confirm({
|
|
36
48
|
message: "export/ directory already exists. Continue and overwrite?",
|
|
37
49
|
initialValue: false,
|
|
@@ -42,28 +54,40 @@ export async function init(argv) {
|
|
|
42
54
|
}
|
|
43
55
|
}
|
|
44
56
|
|
|
45
|
-
// Get worker name
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
57
|
+
// Get worker name (use default in non-interactive mode)
|
|
58
|
+
const defaultWorkerName = pkg.name ? `${pkg.name}-api` : "my-api";
|
|
59
|
+
let workerName;
|
|
60
|
+
|
|
61
|
+
if (isNonInteractive) {
|
|
62
|
+
workerName = argv.name || defaultWorkerName;
|
|
63
|
+
} else {
|
|
64
|
+
workerName = await p.text({
|
|
65
|
+
message: "Worker name:",
|
|
66
|
+
placeholder: defaultWorkerName,
|
|
67
|
+
defaultValue: defaultWorkerName,
|
|
68
|
+
validate: (v) => {
|
|
69
|
+
if (!v) return "Worker name is required";
|
|
70
|
+
if (!/^[a-z0-9-]+$/.test(v)) return "Use lowercase letters, numbers, and hyphens only";
|
|
71
|
+
},
|
|
72
|
+
});
|
|
55
73
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
74
|
+
if (p.isCancel(workerName)) {
|
|
75
|
+
p.cancel("Operation cancelled.");
|
|
76
|
+
process.exit(0);
|
|
77
|
+
}
|
|
59
78
|
}
|
|
60
79
|
|
|
61
80
|
// Check for TypeScript
|
|
62
81
|
const isTypeScript = viteConfig.endsWith(".ts") || viteConfig.endsWith(".mts") ||
|
|
63
82
|
fs.existsSync(path.join(cwd, "tsconfig.json"));
|
|
64
83
|
|
|
65
|
-
|
|
66
|
-
|
|
84
|
+
let s;
|
|
85
|
+
if (!isNonInteractive) {
|
|
86
|
+
s = p.spinner();
|
|
87
|
+
s.start("Initializing export...");
|
|
88
|
+
} else {
|
|
89
|
+
console.log("Initializing export...");
|
|
90
|
+
}
|
|
67
91
|
|
|
68
92
|
// Create export directory
|
|
69
93
|
if (!fs.existsSync(exportDir)) {
|
|
@@ -262,18 +286,22 @@ declare module "export/" {
|
|
|
262
286
|
fs.writeFileSync(envDtsPath, envDtsContent);
|
|
263
287
|
}
|
|
264
288
|
|
|
265
|
-
// Update tsconfig
|
|
289
|
+
// Update tsconfig to include the type declarations
|
|
290
|
+
// Modern Vite uses tsconfig.app.json for app code, older uses tsconfig.json directly
|
|
291
|
+
const tsconfigAppPath = path.join(cwd, "tsconfig.app.json");
|
|
266
292
|
const tsconfigPath = path.join(cwd, "tsconfig.json");
|
|
267
|
-
|
|
293
|
+
const targetTsconfig = fs.existsSync(tsconfigAppPath) ? tsconfigAppPath : tsconfigPath;
|
|
294
|
+
|
|
295
|
+
if (fs.existsSync(targetTsconfig)) {
|
|
268
296
|
try {
|
|
269
|
-
const tsconfigContent = fs.readFileSync(
|
|
297
|
+
const tsconfigContent = fs.readFileSync(targetTsconfig, "utf8");
|
|
270
298
|
const tsconfig = JSON.parse(tsconfigContent);
|
|
271
299
|
|
|
272
300
|
// Add export-env.d.ts to include if not already present
|
|
273
301
|
tsconfig.include = tsconfig.include || [];
|
|
274
302
|
if (!tsconfig.include.includes("export-env.d.ts")) {
|
|
275
303
|
tsconfig.include.push("export-env.d.ts");
|
|
276
|
-
fs.writeFileSync(
|
|
304
|
+
fs.writeFileSync(targetTsconfig, JSON.stringify(tsconfig, null, 2) + "\n");
|
|
277
305
|
}
|
|
278
306
|
} catch {
|
|
279
307
|
// Ignore JSON parse errors (might have comments)
|
|
@@ -281,40 +309,65 @@ declare module "export/" {
|
|
|
281
309
|
}
|
|
282
310
|
}
|
|
283
311
|
|
|
284
|
-
|
|
312
|
+
// Install dependencies in export directory
|
|
313
|
+
if (!isNonInteractive) {
|
|
314
|
+
s.stop("Files created!");
|
|
315
|
+
s.start("Installing dependencies...");
|
|
316
|
+
} else {
|
|
317
|
+
console.log("Installing dependencies...");
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
try {
|
|
321
|
+
execSync("npm install", {
|
|
322
|
+
cwd: exportDir,
|
|
323
|
+
stdio: isNonInteractive ? "inherit" : "pipe",
|
|
324
|
+
});
|
|
325
|
+
} catch (err) {
|
|
326
|
+
if (!isNonInteractive) {
|
|
327
|
+
s.stop("Failed to install dependencies");
|
|
328
|
+
p.log.error(`Run ${pc.cyan("cd export && npm install")} manually.`);
|
|
329
|
+
} else {
|
|
330
|
+
console.error("Failed to install dependencies. Run 'cd export && npm install' manually.");
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
if (!isNonInteractive) {
|
|
335
|
+
s.stop("Export initialized!");
|
|
285
336
|
|
|
286
|
-
|
|
287
|
-
|
|
337
|
+
const filesCreated = isTypeScript
|
|
338
|
+
? `${pc.cyan("export/")}
|
|
288
339
|
├── index.${ext} ${pc.dim("# Your server exports")}
|
|
289
340
|
├── package.json ${pc.dim("# Worker configuration")}
|
|
290
341
|
└── .gitignore
|
|
291
342
|
|
|
292
343
|
${pc.cyan("export-env.d.ts")} ${pc.dim("# Type declarations for export/ imports")}`
|
|
293
|
-
|
|
344
|
+
: `${pc.cyan("export/")}
|
|
294
345
|
├── index.${ext} ${pc.dim("# Your server exports")}
|
|
295
346
|
├── package.json ${pc.dim("# Worker configuration")}
|
|
296
347
|
└── .gitignore`;
|
|
297
348
|
|
|
298
|
-
|
|
299
|
-
|
|
349
|
+
p.note(
|
|
350
|
+
`${filesCreated}
|
|
300
351
|
|
|
301
352
|
${pc.bold("Next steps:")}
|
|
302
353
|
|
|
303
|
-
1.
|
|
304
|
-
${pc.cyan("cd export && npm install && cd ..")}
|
|
305
|
-
|
|
306
|
-
2. Start development (Vite + Wrangler auto-start):
|
|
354
|
+
1. Start development (Vite + Wrangler auto-start):
|
|
307
355
|
${pc.cyan("npm run dev")}
|
|
308
356
|
|
|
309
|
-
|
|
357
|
+
2. Import in your client code:
|
|
310
358
|
${pc.cyan(`import { hello } from "export/";`)}
|
|
311
359
|
${pc.cyan(`const message = await hello("World");`)}
|
|
312
360
|
|
|
313
|
-
|
|
361
|
+
3. Deploy to Cloudflare Workers Sites:
|
|
314
362
|
${pc.cyan("npm run export")}
|
|
315
363
|
${pc.dim("# Builds Vite + deploys everything to Workers")}`,
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
364
|
+
"Ready"
|
|
365
|
+
);
|
|
366
|
+
|
|
367
|
+
p.outro(`Run ${pc.cyan("npm run dev")} to start!`);
|
|
368
|
+
} else {
|
|
369
|
+
console.log("Export initialized successfully!");
|
|
370
|
+
console.log("\nNext steps:");
|
|
371
|
+
console.log(" npm run dev");
|
|
372
|
+
}
|
|
320
373
|
}
|
package/package.json
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "exportc",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.6",
|
|
4
4
|
"description": "CLI to add export to existing projects",
|
|
5
5
|
"scripts": {
|
|
6
|
-
"test": "node --test test
|
|
6
|
+
"test": "node --test test/init.test.mjs",
|
|
7
|
+
"test:e2e": "node --test test/e2e.test.mjs"
|
|
7
8
|
},
|
|
8
9
|
"keywords": [
|
|
9
10
|
"cloudflare",
|