exportc 0.0.2 → 0.0.3
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 +13 -10
- package/commands/deploy.js +45 -15
- package/commands/init.js +17 -11
- package/package.json +1 -1
- package/vite-plugin.js +23 -3
package/README.md
CHANGED
|
@@ -13,6 +13,9 @@ cd export && npm install && cd ..
|
|
|
13
13
|
|
|
14
14
|
# Start development (Wrangler starts automatically!)
|
|
15
15
|
npm run dev
|
|
16
|
+
|
|
17
|
+
# Deploy to Cloudflare Workers Sites
|
|
18
|
+
npm run export
|
|
16
19
|
```
|
|
17
20
|
|
|
18
21
|
## Usage
|
|
@@ -57,22 +60,22 @@ import { exportPlugin } from "exportc/vite";
|
|
|
57
60
|
|
|
58
61
|
export default defineConfig({
|
|
59
62
|
plugins: [
|
|
60
|
-
exportPlugin(
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
// Optional: customize dev server
|
|
65
|
-
// port: 8787,
|
|
66
|
-
// autoStart: true, // Auto-start Wrangler (default: true)
|
|
67
|
-
}),
|
|
63
|
+
exportPlugin(),
|
|
64
|
+
// Production URL is auto-detected from export/package.json name
|
|
65
|
+
// Override with: exportPlugin({ production: "https://custom.workers.dev" })
|
|
68
66
|
],
|
|
69
67
|
});
|
|
70
68
|
```
|
|
71
69
|
|
|
72
|
-
|
|
70
|
+
**Development** (`npm run dev`):
|
|
73
71
|
1. Automatically starts Wrangler dev server
|
|
74
72
|
2. Waits for it to be ready
|
|
75
|
-
3. Transforms `export:/` imports to
|
|
73
|
+
3. Transforms `export:/` imports to `http://localhost:8787`
|
|
74
|
+
|
|
75
|
+
**Production** (`npm run export`):
|
|
76
|
+
1. Builds Vite app
|
|
77
|
+
2. Deploys to Workers Sites (static assets + server exports)
|
|
78
|
+
3. `export:/` imports resolve to `https://{worker-name}.workers.dev`
|
|
76
79
|
|
|
77
80
|
## Project Structure
|
|
78
81
|
|
package/commands/deploy.js
CHANGED
|
@@ -23,27 +23,54 @@ export async function deploy(argv) {
|
|
|
23
23
|
|
|
24
24
|
p.intro(pc.bgCyan(pc.black(" exportc deploy ")));
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
// Step 1: Build Vite
|
|
27
|
+
const s1 = p.spinner();
|
|
28
|
+
s1.start("Building with Vite...");
|
|
28
29
|
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
const viteBuild = spawn("npm", ["run", "build"], {
|
|
31
|
+
cwd,
|
|
32
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
33
|
+
shell: true,
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
let viteBuildOutput = "";
|
|
37
|
+
viteBuild.stdout.on("data", (data) => { viteBuildOutput += data.toString(); });
|
|
38
|
+
viteBuild.stderr.on("data", (data) => { viteBuildOutput += data.toString(); });
|
|
39
|
+
|
|
40
|
+
const viteExitCode = await new Promise((resolve) => {
|
|
41
|
+
viteBuild.on("close", resolve);
|
|
42
|
+
viteBuild.on("error", () => resolve(1));
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
if (viteExitCode !== 0) {
|
|
46
|
+
s1.stop("Vite build failed");
|
|
47
|
+
console.error(viteBuildOutput);
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
s1.stop("Vite build complete");
|
|
52
|
+
|
|
53
|
+
// Step 2: Deploy to Cloudflare Workers
|
|
54
|
+
const s2 = p.spinner();
|
|
55
|
+
s2.start("Deploying to Cloudflare Workers...");
|
|
56
|
+
|
|
57
|
+
const wranglerDeploy = spawn("npm", ["run", "deploy"], {
|
|
31
58
|
cwd: exportDir,
|
|
32
59
|
stdio: "inherit",
|
|
33
60
|
shell: true,
|
|
34
61
|
});
|
|
35
62
|
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
63
|
+
const wranglerExitCode = await new Promise((resolve) => {
|
|
64
|
+
wranglerDeploy.on("close", resolve);
|
|
65
|
+
wranglerDeploy.on("error", () => resolve(1));
|
|
39
66
|
});
|
|
40
67
|
|
|
41
|
-
if (
|
|
42
|
-
|
|
68
|
+
if (wranglerExitCode !== 0) {
|
|
69
|
+
s2.stop("Deployment failed");
|
|
43
70
|
process.exit(1);
|
|
44
71
|
}
|
|
45
72
|
|
|
46
|
-
|
|
73
|
+
s2.stop("Deployed successfully!");
|
|
47
74
|
|
|
48
75
|
// Read worker name from export/package.json
|
|
49
76
|
const exportPkgPath = path.join(exportDir, "package.json");
|
|
@@ -51,13 +78,16 @@ export async function deploy(argv) {
|
|
|
51
78
|
const workerName = exportPkg.name;
|
|
52
79
|
|
|
53
80
|
p.note(
|
|
54
|
-
`Your
|
|
81
|
+
`Your app is now live at:
|
|
55
82
|
${pc.cyan(`https://${workerName}.workers.dev/`)}
|
|
56
83
|
|
|
57
|
-
${pc.bold("
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
84
|
+
${pc.bold("What was deployed:")}
|
|
85
|
+
- Static assets (Vite build output)
|
|
86
|
+
- Server exports (export/ directory)
|
|
87
|
+
|
|
88
|
+
${pc.bold("Client imports will resolve to:")}
|
|
89
|
+
${pc.cyan(`https://${workerName}.workers.dev/`)}`,
|
|
90
|
+
"Workers Sites"
|
|
61
91
|
);
|
|
62
92
|
|
|
63
93
|
p.outro("Done!");
|
package/commands/init.js
CHANGED
|
@@ -132,6 +132,15 @@ export class Counter {
|
|
|
132
132
|
fs.writeFileSync(indexPath, template);
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
+
// Detect Vite build output directory from vite.config
|
|
136
|
+
let viteBuildOutDir = "dist"; // default
|
|
137
|
+
const viteConfigPath = path.join(cwd, viteConfig);
|
|
138
|
+
let viteConfigContent = fs.readFileSync(viteConfigPath, "utf8");
|
|
139
|
+
const outDirMatch = viteConfigContent.match(/outDir:\s*['"]([^'"]+)['"]/);
|
|
140
|
+
if (outDirMatch) {
|
|
141
|
+
viteBuildOutDir = outDirMatch[1];
|
|
142
|
+
}
|
|
143
|
+
|
|
135
144
|
// Create export/package.json
|
|
136
145
|
const exportPkgPath = path.join(exportDir, "package.json");
|
|
137
146
|
const exportPkg = {
|
|
@@ -139,6 +148,7 @@ export class Counter {
|
|
|
139
148
|
private: true,
|
|
140
149
|
type: "module",
|
|
141
150
|
exports: "./",
|
|
151
|
+
main: `../${viteBuildOutDir}`, // Static assets from Vite build
|
|
142
152
|
scripts: {
|
|
143
153
|
dev: "generate-export-types && wrangler dev",
|
|
144
154
|
deploy: "generate-export-types && wrangler deploy",
|
|
@@ -160,25 +170,20 @@ export class Counter {
|
|
|
160
170
|
// Update main package.json
|
|
161
171
|
pkg.scripts = pkg.scripts || {};
|
|
162
172
|
|
|
163
|
-
// Add
|
|
164
|
-
if (!pkg.scripts["
|
|
165
|
-
pkg.scripts["
|
|
166
|
-
} else if (!pkg.scripts["deploy"].includes("export")) {
|
|
167
|
-
// Add export deploy to existing deploy script
|
|
168
|
-
pkg.scripts["deploy:export"] = "cd export && npm run deploy";
|
|
173
|
+
// Add export script: build + deploy as Workers Sites
|
|
174
|
+
if (!pkg.scripts["export"]) {
|
|
175
|
+
pkg.scripts["export"] = "vite build && cd export && npm run deploy";
|
|
169
176
|
}
|
|
170
177
|
|
|
171
178
|
// Add exportc to devDependencies
|
|
172
179
|
pkg.devDependencies = pkg.devDependencies || {};
|
|
173
180
|
if (!pkg.devDependencies.exportc) {
|
|
174
|
-
pkg.devDependencies.exportc = "^0.0.
|
|
181
|
+
pkg.devDependencies.exportc = "^0.0.2";
|
|
175
182
|
}
|
|
176
183
|
|
|
177
184
|
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
|
|
178
185
|
|
|
179
186
|
// Update vite.config
|
|
180
|
-
const viteConfigPath = path.join(cwd, viteConfig);
|
|
181
|
-
let viteConfigContent = fs.readFileSync(viteConfigPath, "utf8");
|
|
182
187
|
|
|
183
188
|
// Check if export plugin is already added
|
|
184
189
|
if (!viteConfigContent.includes("exportc/vite")) {
|
|
@@ -305,8 +310,9 @@ ${pc.bold("Next steps:")}
|
|
|
305
310
|
${pc.cyan(`import { hello } from "export:/";`)}
|
|
306
311
|
${pc.cyan(`const message = await hello("World");`)}
|
|
307
312
|
|
|
308
|
-
4. Deploy to Cloudflare:
|
|
309
|
-
${pc.cyan("npm run
|
|
313
|
+
4. Deploy to Cloudflare Workers Sites:
|
|
314
|
+
${pc.cyan("npm run export")}
|
|
315
|
+
${pc.dim("# Builds Vite + deploys everything to Workers")}`,
|
|
310
316
|
"Created"
|
|
311
317
|
);
|
|
312
318
|
|
package/package.json
CHANGED
package/vite-plugin.js
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
import { spawn } from "node:child_process";
|
|
17
|
-
import { existsSync } from "node:fs";
|
|
17
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
18
18
|
import { resolve } from "node:path";
|
|
19
19
|
|
|
20
20
|
const EXPORT_PREFIX = "export:";
|
|
@@ -23,7 +23,7 @@ const DEFAULT_DEV_PORT = 8787;
|
|
|
23
23
|
/**
|
|
24
24
|
* @param {Object} options
|
|
25
25
|
* @param {string} [options.dev] - Development server URL (default: http://localhost:8787)
|
|
26
|
-
* @param {string} [options.production] - Production Worker URL (
|
|
26
|
+
* @param {string} [options.production] - Production Worker URL (auto-detected from export/package.json name if not specified)
|
|
27
27
|
* @param {string} [options.exportDir] - Export directory (default: ./export)
|
|
28
28
|
* @param {boolean} [options.autoStart] - Auto-start Wrangler in dev mode (default: true)
|
|
29
29
|
* @returns {import('vite').Plugin}
|
|
@@ -31,7 +31,7 @@ const DEFAULT_DEV_PORT = 8787;
|
|
|
31
31
|
export function exportPlugin(options = {}) {
|
|
32
32
|
const devPort = options.port || DEFAULT_DEV_PORT;
|
|
33
33
|
const devUrl = options.dev || `http://localhost:${devPort}`;
|
|
34
|
-
|
|
34
|
+
let prodUrl = options.production;
|
|
35
35
|
const exportDir = options.exportDir || "./export";
|
|
36
36
|
const autoStart = options.autoStart !== false;
|
|
37
37
|
|
|
@@ -40,6 +40,21 @@ export function exportPlugin(options = {}) {
|
|
|
40
40
|
let wranglerReady = false;
|
|
41
41
|
let wranglerReadyPromise = null;
|
|
42
42
|
|
|
43
|
+
// Auto-detect production URL from export/package.json
|
|
44
|
+
const detectProductionUrl = (root) => {
|
|
45
|
+
if (prodUrl) return prodUrl;
|
|
46
|
+
try {
|
|
47
|
+
const exportPkgPath = resolve(root, exportDir, "package.json");
|
|
48
|
+
if (existsSync(exportPkgPath)) {
|
|
49
|
+
const exportPkg = JSON.parse(readFileSync(exportPkgPath, "utf8"));
|
|
50
|
+
if (exportPkg.name) {
|
|
51
|
+
return `https://${exportPkg.name}.workers.dev`;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
} catch {}
|
|
55
|
+
return null;
|
|
56
|
+
};
|
|
57
|
+
|
|
43
58
|
const startWrangler = (root) => {
|
|
44
59
|
const exportPath = resolve(root, exportDir);
|
|
45
60
|
|
|
@@ -136,6 +151,11 @@ export function exportPlugin(options = {}) {
|
|
|
136
151
|
|
|
137
152
|
config(config, { command }) {
|
|
138
153
|
isDev = command === "serve";
|
|
154
|
+
// Auto-detect production URL if not specified
|
|
155
|
+
if (!isDev && !prodUrl) {
|
|
156
|
+
const root = config.root || process.cwd();
|
|
157
|
+
prodUrl = detectProductionUrl(root);
|
|
158
|
+
}
|
|
139
159
|
return {};
|
|
140
160
|
},
|
|
141
161
|
|