exportc 0.0.1 → 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 +21 -12
- package/commands/deploy.js +45 -15
- package/commands/init.js +25 -15
- package/package.json +1 -1
- package/vite-plugin.d.ts +22 -1
- package/vite-plugin.js +166 -49
package/README.md
CHANGED
|
@@ -8,12 +8,14 @@ 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 dependencies
|
|
12
|
-
cd export && npm install
|
|
11
|
+
# Install export dependencies
|
|
12
|
+
cd export && npm install && cd ..
|
|
13
13
|
|
|
14
|
-
# Start development (
|
|
15
|
-
npm run
|
|
16
|
-
|
|
14
|
+
# Start development (Wrangler starts automatically!)
|
|
15
|
+
npm run dev
|
|
16
|
+
|
|
17
|
+
# Deploy to Cloudflare Workers Sites
|
|
18
|
+
npm run export
|
|
17
19
|
```
|
|
18
20
|
|
|
19
21
|
## Usage
|
|
@@ -49,7 +51,7 @@ Deploy your exports to Cloudflare Workers.
|
|
|
49
51
|
|
|
50
52
|
## Vite Plugin
|
|
51
53
|
|
|
52
|
-
The `exportPlugin` transforms `export:/` imports:
|
|
54
|
+
The `exportPlugin` automatically starts Wrangler and transforms `export:/` imports:
|
|
53
55
|
|
|
54
56
|
```typescript
|
|
55
57
|
// vite.config.ts
|
|
@@ -58,16 +60,23 @@ import { exportPlugin } from "exportc/vite";
|
|
|
58
60
|
|
|
59
61
|
export default defineConfig({
|
|
60
62
|
plugins: [
|
|
61
|
-
exportPlugin(
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
// Production Worker URL (required for production builds)
|
|
65
|
-
production: "https://my-api.workers.dev",
|
|
66
|
-
}),
|
|
63
|
+
exportPlugin(),
|
|
64
|
+
// Production URL is auto-detected from export/package.json name
|
|
65
|
+
// Override with: exportPlugin({ production: "https://custom.workers.dev" })
|
|
67
66
|
],
|
|
68
67
|
});
|
|
69
68
|
```
|
|
70
69
|
|
|
70
|
+
**Development** (`npm run dev`):
|
|
71
|
+
1. Automatically starts Wrangler dev server
|
|
72
|
+
2. Waits for it to be ready
|
|
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`
|
|
79
|
+
|
|
71
80
|
## Project Structure
|
|
72
81
|
|
|
73
82
|
After running `exportc init`:
|
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",
|
|
@@ -157,26 +167,23 @@ export class Counter {
|
|
|
157
167
|
|
|
158
168
|
fs.writeFileSync(exportPkgPath, JSON.stringify(exportPkg, null, 2) + "\n");
|
|
159
169
|
|
|
160
|
-
// Update main package.json
|
|
170
|
+
// Update main package.json
|
|
161
171
|
pkg.scripts = pkg.scripts || {};
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
pkg.scripts["export:deploy"] = "cd export && npm run deploy";
|
|
172
|
+
|
|
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";
|
|
167
176
|
}
|
|
168
177
|
|
|
169
178
|
// Add exportc to devDependencies
|
|
170
179
|
pkg.devDependencies = pkg.devDependencies || {};
|
|
171
180
|
if (!pkg.devDependencies.exportc) {
|
|
172
|
-
pkg.devDependencies.exportc = "^0.0.
|
|
181
|
+
pkg.devDependencies.exportc = "^0.0.2";
|
|
173
182
|
}
|
|
174
183
|
|
|
175
184
|
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
|
|
176
185
|
|
|
177
186
|
// Update vite.config
|
|
178
|
-
const viteConfigPath = path.join(cwd, viteConfig);
|
|
179
|
-
let viteConfigContent = fs.readFileSync(viteConfigPath, "utf8");
|
|
180
187
|
|
|
181
188
|
// Check if export plugin is already added
|
|
182
189
|
if (!viteConfigContent.includes("exportc/vite")) {
|
|
@@ -293,16 +300,19 @@ ${pc.cyan("export-env.d.ts")} ${pc.dim("# Type declarations for export:/ imp
|
|
|
293
300
|
|
|
294
301
|
${pc.bold("Next steps:")}
|
|
295
302
|
|
|
296
|
-
1. Install dependencies:
|
|
297
|
-
${pc.cyan("cd export && npm install")}
|
|
303
|
+
1. Install export dependencies:
|
|
304
|
+
${pc.cyan("cd export && npm install && cd ..")}
|
|
298
305
|
|
|
299
|
-
2. Start development:
|
|
300
|
-
${pc.cyan("npm run
|
|
301
|
-
${pc.cyan("npm run dev")} ${pc.dim("# In another terminal")}
|
|
306
|
+
2. Start development (Vite + Wrangler auto-start):
|
|
307
|
+
${pc.cyan("npm run dev")}
|
|
302
308
|
|
|
303
309
|
3. Import in your client code:
|
|
304
310
|
${pc.cyan(`import { hello } from "export:/";`)}
|
|
305
|
-
${pc.cyan(`const message = await hello("World");`)}
|
|
311
|
+
${pc.cyan(`const message = await hello("World");`)}
|
|
312
|
+
|
|
313
|
+
4. Deploy to Cloudflare Workers Sites:
|
|
314
|
+
${pc.cyan("npm run export")}
|
|
315
|
+
${pc.dim("# Builds Vite + deploys everything to Workers")}`,
|
|
306
316
|
"Created"
|
|
307
317
|
);
|
|
308
318
|
|
package/package.json
CHANGED
package/vite-plugin.d.ts
CHANGED
|
@@ -7,18 +7,38 @@ export interface ExportPluginOptions {
|
|
|
7
7
|
*/
|
|
8
8
|
dev?: string;
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Development server port
|
|
12
|
+
* @default 8787
|
|
13
|
+
*/
|
|
14
|
+
port?: number;
|
|
15
|
+
|
|
10
16
|
/**
|
|
11
17
|
* Production Worker URL
|
|
12
18
|
* Required for production builds
|
|
13
19
|
* @example "https://my-api.workers.dev"
|
|
14
20
|
*/
|
|
15
21
|
production?: string;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Export directory path (relative to project root)
|
|
25
|
+
* @default "./export"
|
|
26
|
+
*/
|
|
27
|
+
exportDir?: string;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Auto-start Wrangler dev server when running Vite in dev mode
|
|
31
|
+
* @default true
|
|
32
|
+
*/
|
|
33
|
+
autoStart?: boolean;
|
|
16
34
|
}
|
|
17
35
|
|
|
18
36
|
/**
|
|
19
37
|
* Vite plugin for export integration
|
|
20
38
|
*
|
|
21
|
-
*
|
|
39
|
+
* Automatically starts Wrangler when you run `npm run dev` and allows
|
|
40
|
+
* importing server exports using the "export:/" prefix:
|
|
41
|
+
*
|
|
22
42
|
* ```ts
|
|
23
43
|
* import { hello } from "export:/";
|
|
24
44
|
* import { utils } from "export:/utils";
|
|
@@ -31,6 +51,7 @@ export interface ExportPluginOptions {
|
|
|
31
51
|
* export default defineConfig({
|
|
32
52
|
* plugins: [
|
|
33
53
|
* exportPlugin({
|
|
54
|
+
* // Required for production builds
|
|
34
55
|
* production: "https://my-api.workers.dev"
|
|
35
56
|
* })
|
|
36
57
|
* ]
|
package/vite-plugin.js
CHANGED
|
@@ -5,51 +5,195 @@
|
|
|
5
5
|
* import { hello } from "export:/";
|
|
6
6
|
* import { utils } from "export:/utils";
|
|
7
7
|
*
|
|
8
|
-
* In development
|
|
9
|
-
*
|
|
8
|
+
* In development:
|
|
9
|
+
* - Automatically starts Wrangler dev server
|
|
10
|
+
* - Proxies to local Wrangler (localhost:8787)
|
|
11
|
+
*
|
|
12
|
+
* In production:
|
|
13
|
+
* - Resolves to the deployed Worker URL
|
|
10
14
|
*/
|
|
11
15
|
|
|
16
|
+
import { spawn } from "node:child_process";
|
|
17
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
18
|
+
import { resolve } from "node:path";
|
|
19
|
+
|
|
12
20
|
const EXPORT_PREFIX = "export:";
|
|
13
|
-
const
|
|
21
|
+
const DEFAULT_DEV_PORT = 8787;
|
|
14
22
|
|
|
15
23
|
/**
|
|
16
24
|
* @param {Object} options
|
|
17
25
|
* @param {string} [options.dev] - Development server URL (default: http://localhost:8787)
|
|
18
|
-
* @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
|
+
* @param {string} [options.exportDir] - Export directory (default: ./export)
|
|
28
|
+
* @param {boolean} [options.autoStart] - Auto-start Wrangler in dev mode (default: true)
|
|
19
29
|
* @returns {import('vite').Plugin}
|
|
20
30
|
*/
|
|
21
31
|
export function exportPlugin(options = {}) {
|
|
22
|
-
const
|
|
23
|
-
const
|
|
32
|
+
const devPort = options.port || DEFAULT_DEV_PORT;
|
|
33
|
+
const devUrl = options.dev || `http://localhost:${devPort}`;
|
|
34
|
+
let prodUrl = options.production;
|
|
35
|
+
const exportDir = options.exportDir || "./export";
|
|
36
|
+
const autoStart = options.autoStart !== false;
|
|
24
37
|
|
|
25
38
|
let isDev = true;
|
|
39
|
+
let wranglerProcess = null;
|
|
40
|
+
let wranglerReady = false;
|
|
41
|
+
let wranglerReadyPromise = null;
|
|
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
|
+
|
|
58
|
+
const startWrangler = (root) => {
|
|
59
|
+
const exportPath = resolve(root, exportDir);
|
|
60
|
+
|
|
61
|
+
if (!existsSync(exportPath)) {
|
|
62
|
+
console.warn(`[exportc] Export directory not found: ${exportPath}`);
|
|
63
|
+
console.warn(`[exportc] Run 'npx exportc init' to initialize.`);
|
|
64
|
+
return Promise.resolve();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const nodeModulesPath = resolve(exportPath, "node_modules");
|
|
68
|
+
if (!existsSync(nodeModulesPath)) {
|
|
69
|
+
console.warn(`[exportc] Dependencies not installed in ${exportPath}`);
|
|
70
|
+
console.warn(`[exportc] Run 'cd ${exportDir} && npm install' first.`);
|
|
71
|
+
return Promise.resolve();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return new Promise((resolveReady) => {
|
|
75
|
+
console.log(`[exportc] Starting Wrangler dev server...`);
|
|
76
|
+
|
|
77
|
+
// Generate types first, then start wrangler
|
|
78
|
+
const generateTypes = spawn("npm", ["run", "dev"], {
|
|
79
|
+
cwd: exportPath,
|
|
80
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
81
|
+
shell: true,
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
wranglerProcess = generateTypes;
|
|
85
|
+
|
|
86
|
+
generateTypes.stdout.on("data", (data) => {
|
|
87
|
+
const output = data.toString();
|
|
88
|
+
process.stdout.write(`[export] ${output}`);
|
|
89
|
+
|
|
90
|
+
// Detect when wrangler is ready
|
|
91
|
+
if (output.includes("Ready on") || output.includes("Listening on") || output.includes("localhost")) {
|
|
92
|
+
if (!wranglerReady) {
|
|
93
|
+
wranglerReady = true;
|
|
94
|
+
console.log(`[exportc] Wrangler ready at ${devUrl}`);
|
|
95
|
+
resolveReady();
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
generateTypes.stderr.on("data", (data) => {
|
|
101
|
+
const output = data.toString();
|
|
102
|
+
// Filter out noisy warnings
|
|
103
|
+
if (!output.includes("ExperimentalWarning")) {
|
|
104
|
+
process.stderr.write(`[export] ${output}`);
|
|
105
|
+
}
|
|
106
|
+
// Also check stderr for ready message
|
|
107
|
+
if (output.includes("Ready on") || output.includes("Listening on") || output.includes("localhost:8787")) {
|
|
108
|
+
if (!wranglerReady) {
|
|
109
|
+
wranglerReady = true;
|
|
110
|
+
console.log(`[exportc] Wrangler ready at ${devUrl}`);
|
|
111
|
+
resolveReady();
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
generateTypes.on("error", (err) => {
|
|
117
|
+
console.error(`[exportc] Failed to start Wrangler:`, err.message);
|
|
118
|
+
resolveReady();
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
generateTypes.on("close", (code) => {
|
|
122
|
+
if (code !== 0 && code !== null) {
|
|
123
|
+
console.error(`[exportc] Wrangler exited with code ${code}`);
|
|
124
|
+
}
|
|
125
|
+
wranglerProcess = null;
|
|
126
|
+
resolveReady();
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
// Timeout after 30 seconds
|
|
130
|
+
setTimeout(() => {
|
|
131
|
+
if (!wranglerReady) {
|
|
132
|
+
console.warn(`[exportc] Wrangler startup timeout, continuing anyway...`);
|
|
133
|
+
wranglerReady = true;
|
|
134
|
+
resolveReady();
|
|
135
|
+
}
|
|
136
|
+
}, 30000);
|
|
137
|
+
});
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
const stopWrangler = () => {
|
|
141
|
+
if (wranglerProcess) {
|
|
142
|
+
console.log(`[exportc] Stopping Wrangler...`);
|
|
143
|
+
wranglerProcess.kill("SIGTERM");
|
|
144
|
+
wranglerProcess = null;
|
|
145
|
+
wranglerReady = false;
|
|
146
|
+
}
|
|
147
|
+
};
|
|
26
148
|
|
|
27
149
|
return {
|
|
28
150
|
name: "vite-plugin-export",
|
|
29
151
|
|
|
30
152
|
config(config, { command }) {
|
|
31
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
|
+
}
|
|
159
|
+
return {};
|
|
160
|
+
},
|
|
161
|
+
|
|
162
|
+
configureServer(server) {
|
|
163
|
+
if (isDev && autoStart) {
|
|
164
|
+
const root = server.config.root || process.cwd();
|
|
165
|
+
wranglerReadyPromise = startWrangler(root);
|
|
32
166
|
|
|
33
|
-
|
|
167
|
+
// Cleanup on server close
|
|
168
|
+
server.httpServer?.on("close", stopWrangler);
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
|
|
172
|
+
async buildStart() {
|
|
34
173
|
if (isDev) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
},
|
|
44
|
-
},
|
|
45
|
-
},
|
|
46
|
-
};
|
|
174
|
+
if (autoStart && wranglerReadyPromise) {
|
|
175
|
+
await wranglerReadyPromise;
|
|
176
|
+
}
|
|
177
|
+
this.info(`Development mode - using ${devUrl}`);
|
|
178
|
+
} else if (prodUrl) {
|
|
179
|
+
this.info(`Production mode - using ${prodUrl}`);
|
|
180
|
+
} else {
|
|
181
|
+
this.warn(`Production URL not configured. Add 'production' option to exportPlugin().`);
|
|
47
182
|
}
|
|
48
183
|
},
|
|
49
184
|
|
|
185
|
+
buildEnd() {
|
|
186
|
+
if (!isDev) {
|
|
187
|
+
stopWrangler();
|
|
188
|
+
}
|
|
189
|
+
},
|
|
190
|
+
|
|
191
|
+
closeBundle() {
|
|
192
|
+
stopWrangler();
|
|
193
|
+
},
|
|
194
|
+
|
|
50
195
|
resolveId(source) {
|
|
51
196
|
if (source.startsWith(EXPORT_PREFIX)) {
|
|
52
|
-
// Mark as external - we'll handle it in load
|
|
53
197
|
return { id: source, external: false };
|
|
54
198
|
}
|
|
55
199
|
return null;
|
|
@@ -60,28 +204,20 @@ export function exportPlugin(options = {}) {
|
|
|
60
204
|
return null;
|
|
61
205
|
}
|
|
62
206
|
|
|
63
|
-
// Extract the path after "export:"
|
|
64
207
|
const exportPath = id.slice(EXPORT_PREFIX.length) || "/";
|
|
65
|
-
|
|
66
|
-
// In development, use the local dev server
|
|
67
|
-
// In production, use the configured production URL
|
|
68
208
|
const baseUrl = isDev ? devUrl : prodUrl;
|
|
69
209
|
|
|
70
210
|
if (!baseUrl) {
|
|
71
211
|
if (!isDev) {
|
|
72
212
|
this.error(
|
|
73
|
-
`[exportc] Production URL not configured. Add { production: "https://your-worker.workers.dev" } to exportPlugin()
|
|
213
|
+
`[exportc] Production URL not configured. Add { production: "https://your-worker.workers.dev" } to exportPlugin().`
|
|
74
214
|
);
|
|
75
215
|
}
|
|
76
216
|
this.error(`[exportc] Could not resolve base URL for export imports.`);
|
|
77
217
|
}
|
|
78
218
|
|
|
79
|
-
// Build the full URL
|
|
80
219
|
const fullUrl = new URL(exportPath, baseUrl).href;
|
|
81
220
|
|
|
82
|
-
// Generate a module that re-exports from the Worker URL
|
|
83
|
-
// For development, we dynamically import from the Worker
|
|
84
|
-
// For production, we use the deployed URL
|
|
85
221
|
const code = `
|
|
86
222
|
// Auto-generated by exportc/vite
|
|
87
223
|
// Importing from: ${fullUrl}
|
|
@@ -92,24 +228,18 @@ export { default } from "${fullUrl}";
|
|
|
92
228
|
return code;
|
|
93
229
|
},
|
|
94
230
|
|
|
95
|
-
// Transform import statements in the final bundle for production
|
|
96
231
|
transform(code, id) {
|
|
97
|
-
// Skip node_modules and non-JS files
|
|
98
232
|
if (id.includes("node_modules") || !/\.(js|ts|jsx|tsx|vue|svelte)$/.test(id)) {
|
|
99
233
|
return null;
|
|
100
234
|
}
|
|
101
235
|
|
|
102
|
-
// Replace dynamic imports of export: URLs
|
|
103
236
|
if (code.includes('import("export:') || code.includes("import('export:")) {
|
|
104
237
|
const baseUrl = isDev ? devUrl : prodUrl;
|
|
105
238
|
if (!baseUrl && !isDev) {
|
|
106
|
-
this.warn(
|
|
107
|
-
`[exportc] Production URL not configured for dynamic imports in ${id}`
|
|
108
|
-
);
|
|
239
|
+
this.warn(`[exportc] Production URL not configured for dynamic imports in ${id}`);
|
|
109
240
|
return null;
|
|
110
241
|
}
|
|
111
242
|
|
|
112
|
-
// Replace export:/ with the actual URL
|
|
113
243
|
const transformed = code.replace(
|
|
114
244
|
/import\((['"])export:([^'"]*)\1\)/g,
|
|
115
245
|
(match, quote, path) => {
|
|
@@ -125,19 +255,6 @@ export { default } from "${fullUrl}";
|
|
|
125
255
|
|
|
126
256
|
return null;
|
|
127
257
|
},
|
|
128
|
-
|
|
129
|
-
// Generate TypeScript declarations hint
|
|
130
|
-
buildStart() {
|
|
131
|
-
if (isDev) {
|
|
132
|
-
this.info(
|
|
133
|
-
`[exportc] Development mode - proxying to ${devUrl}`
|
|
134
|
-
);
|
|
135
|
-
} else if (prodUrl) {
|
|
136
|
-
this.info(
|
|
137
|
-
`[exportc] Production mode - using ${prodUrl}`
|
|
138
|
-
);
|
|
139
|
-
}
|
|
140
|
-
},
|
|
141
258
|
};
|
|
142
259
|
}
|
|
143
260
|
|