@multiplatform.one/vite-plugin-vscode 6.4.3 → 6.6.0

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/lib/index.cjs CHANGED
@@ -66,9 +66,11 @@ async function createVscodeConfig(options) {
66
66
  const workspaceRoot = options.workspaceRoot ?? (0, _multiplatform_one_utils_dev.lookupProjectRoot)();
67
67
  const isDev = options.isDev ?? process.env.NODE_ENV !== "production";
68
68
  const { tamaguiPlugin } = await import("@tamagui/vite-plugin");
69
+ const outputCSS = node_path.default.join(options.targetDir, "tamagui.css");
70
+ if (!node_fs.default.existsSync(outputCSS)) node_fs.default.writeFileSync(outputCSS, "/* generated by @tamagui/vite-plugin during build */\n");
69
71
  return {
70
72
  root: options.targetDir,
71
- base: isDev ? "/" : "./",
73
+ base: "/",
72
74
  build: {
73
75
  outDir: options.outDir,
74
76
  emptyOutDir: true,
@@ -177,10 +179,41 @@ async function createVscodeConfig(options) {
177
179
  }
178
180
  };
179
181
  }
182
+ /** Correct the webview dist path baked into the extension-host bundle.
183
+ *
184
+ * @tomjs/vite-plugin-vscode computes `VITE_WEBVIEW_DIST` (the segment its
185
+ * runtime joins onto `context.extensionUri` to form the webview base URI)
186
+ * by stripping `process.cwd()` off the resolved outDir. That model assumes
187
+ * the extension is packaged from the vite project root; with an
188
+ * out-of-tree staging dir (ours: apps/<name>/dist-vscode + generated
189
+ * manifest) the strip misses and the BUILD MACHINE'S ABSOLUTE PATH gets
190
+ * baked into the bundle — at runtime the webview base URI doubles into
191
+ * `…/dist-vscode/Users/…/dist-vscode/webview` and every asset 404s.
192
+ *
193
+ * In the staging layout the correct value is always the literal
194
+ * `"webview"` (the assets dir next to the generated package.json), so the
195
+ * staging step rewrites the joinPath call site — anchored on the
196
+ * `.extensionUri` property read, which survives minification. */
197
+ async function fixWebviewDistPath(stagingDir) {
198
+ const bundles = ["extension/index.js", "extension/index.cjs"].map((file) => node_path.default.join(stagingDir, file));
199
+ let fixed = false;
200
+ for (const bundle of bundles) {
201
+ if (!node_fs.default.existsSync(bundle)) continue;
202
+ const source = await node_fs.default.promises.readFile(bundle, "utf-8");
203
+ const rewritten = source.replace(/joinPath\(([A-Za-z_$][\w$]*\.extensionUri),\s*("[^"\n]*"|'[^'\n]*'|`[^`\n]*`)\)/g, "joinPath($1, \"webview\")");
204
+ if (rewritten !== source) {
205
+ await node_fs.default.promises.writeFile(bundle, rewritten, "utf-8");
206
+ fixed = true;
207
+ }
208
+ }
209
+ return fixed;
210
+ }
180
211
  /** Write the extension-manifest package.json into the staging dir. A VS
181
212
  * Code extension's package.json IS its manifest — the product app's own
182
213
  * package.json (an Expo/One app manifest) can't double as it, so `vsce
183
- * package` runs against the staging dir instead. */
214
+ * package` runs against the staging dir instead. Also applies
215
+ * `fixWebviewDistPath` — staging is the earliest race-free point after
216
+ * the plugin's detached extension-host build has finished. */
184
217
  async function writeVsceManifest(stagingDir, manifest) {
185
218
  const { engines, main, ...rest } = manifest;
186
219
  const packageJson = {
@@ -193,10 +226,12 @@ async function writeVsceManifest(stagingDir, manifest) {
193
226
  };
194
227
  await node_fs.default.promises.mkdir(stagingDir, { recursive: true });
195
228
  await node_fs.default.promises.writeFile(node_path.default.join(stagingDir, "package.json"), `${JSON.stringify(packageJson, null, 2)}\n`, "utf-8");
229
+ await fixWebviewDistPath(stagingDir);
196
230
  }
197
231
 
198
232
  //#endregion
199
233
  exports.DEFAULT_WEBVIEW_CSP = DEFAULT_WEBVIEW_CSP;
200
234
  exports.createVscodeConfig = createVscodeConfig;
235
+ exports.fixWebviewDistPath = fixWebviewDistPath;
201
236
  exports.resolveSeamOneAdapter = resolveSeamOneAdapter;
202
237
  exports.writeVsceManifest = writeVsceManifest;
package/lib/index.mjs CHANGED
@@ -34,9 +34,11 @@ async function createVscodeConfig(options) {
34
34
  const workspaceRoot = options.workspaceRoot ?? lookupProjectRoot();
35
35
  const isDev = options.isDev ?? process.env.NODE_ENV !== "production";
36
36
  const { tamaguiPlugin } = await import("@tamagui/vite-plugin");
37
+ const outputCSS = path.join(options.targetDir, "tamagui.css");
38
+ if (!fs.existsSync(outputCSS)) fs.writeFileSync(outputCSS, "/* generated by @tamagui/vite-plugin during build */\n");
37
39
  return {
38
40
  root: options.targetDir,
39
- base: isDev ? "/" : "./",
41
+ base: "/",
40
42
  build: {
41
43
  outDir: options.outDir,
42
44
  emptyOutDir: true,
@@ -145,10 +147,41 @@ async function createVscodeConfig(options) {
145
147
  }
146
148
  };
147
149
  }
150
+ /** Correct the webview dist path baked into the extension-host bundle.
151
+ *
152
+ * @tomjs/vite-plugin-vscode computes `VITE_WEBVIEW_DIST` (the segment its
153
+ * runtime joins onto `context.extensionUri` to form the webview base URI)
154
+ * by stripping `process.cwd()` off the resolved outDir. That model assumes
155
+ * the extension is packaged from the vite project root; with an
156
+ * out-of-tree staging dir (ours: apps/<name>/dist-vscode + generated
157
+ * manifest) the strip misses and the BUILD MACHINE'S ABSOLUTE PATH gets
158
+ * baked into the bundle — at runtime the webview base URI doubles into
159
+ * `…/dist-vscode/Users/…/dist-vscode/webview` and every asset 404s.
160
+ *
161
+ * In the staging layout the correct value is always the literal
162
+ * `"webview"` (the assets dir next to the generated package.json), so the
163
+ * staging step rewrites the joinPath call site — anchored on the
164
+ * `.extensionUri` property read, which survives minification. */
165
+ async function fixWebviewDistPath(stagingDir) {
166
+ const bundles = ["extension/index.js", "extension/index.cjs"].map((file) => path.join(stagingDir, file));
167
+ let fixed = false;
168
+ for (const bundle of bundles) {
169
+ if (!fs.existsSync(bundle)) continue;
170
+ const source = await fs.promises.readFile(bundle, "utf-8");
171
+ const rewritten = source.replace(/joinPath\(([A-Za-z_$][\w$]*\.extensionUri),\s*("[^"\n]*"|'[^'\n]*'|`[^`\n]*`)\)/g, "joinPath($1, \"webview\")");
172
+ if (rewritten !== source) {
173
+ await fs.promises.writeFile(bundle, rewritten, "utf-8");
174
+ fixed = true;
175
+ }
176
+ }
177
+ return fixed;
178
+ }
148
179
  /** Write the extension-manifest package.json into the staging dir. A VS
149
180
  * Code extension's package.json IS its manifest — the product app's own
150
181
  * package.json (an Expo/One app manifest) can't double as it, so `vsce
151
- * package` runs against the staging dir instead. */
182
+ * package` runs against the staging dir instead. Also applies
183
+ * `fixWebviewDistPath` — staging is the earliest race-free point after
184
+ * the plugin's detached extension-host build has finished. */
152
185
  async function writeVsceManifest(stagingDir, manifest) {
153
186
  const { engines, main, ...rest } = manifest;
154
187
  const packageJson = {
@@ -161,7 +194,8 @@ async function writeVsceManifest(stagingDir, manifest) {
161
194
  };
162
195
  await fs.promises.mkdir(stagingDir, { recursive: true });
163
196
  await fs.promises.writeFile(path.join(stagingDir, "package.json"), `${JSON.stringify(packageJson, null, 2)}\n`, "utf-8");
197
+ await fixWebviewDistPath(stagingDir);
164
198
  }
165
199
 
166
200
  //#endregion
167
- export { DEFAULT_WEBVIEW_CSP, createVscodeConfig, resolveSeamOneAdapter, writeVsceManifest };
201
+ export { DEFAULT_WEBVIEW_CSP, createVscodeConfig, fixWebviewDistPath, resolveSeamOneAdapter, writeVsceManifest };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@multiplatform.one/vite-plugin-vscode",
3
- "version": "6.4.3",
3
+ "version": "6.6.0",
4
4
  "description": "Vite config factory for building a VS Code extension (extension host + Tamagui webview) as a target of a multiplatform.one One app — wraps @tomjs/vite-plugin-vscode with the workspace source aliases, the one-router seam alias, React dedupe against one's vendored copy, and a vsce staging-manifest writer.",
5
5
  "keywords": [
6
6
  "multiplatform.one",
@@ -46,7 +46,7 @@
46
46
  "access": "public"
47
47
  },
48
48
  "dependencies": {
49
- "@multiplatform.one/utils": "6.4.3"
49
+ "@multiplatform.one/utils": "6.6.0"
50
50
  },
51
51
  "devDependencies": {
52
52
  "@tamagui/vite-plugin": "2.0.0-rc.41",
package/src/index.ts CHANGED
@@ -85,9 +85,20 @@ export async function createVscodeConfig(options: VscodeTargetOptions): Promise<
85
85
  const workspaceRoot = options.workspaceRoot ?? lookupProjectRoot();
86
86
  const isDev = options.isDev ?? process.env.NODE_ENV !== "production";
87
87
  const { tamaguiPlugin } = await import("@tamagui/vite-plugin");
88
+ // The webview entry imports tamagui.css, but the tamagui plugin only
89
+ // writes outputCSS DURING the build — seed it so a fresh clone's first
90
+ // build doesn't die on an unresolvable import.
91
+ const outputCSS = path.join(options.targetDir, "tamagui.css");
92
+ if (!fs.existsSync(outputCSS)) {
93
+ fs.writeFileSync(outputCSS, "/* generated by @tamagui/vite-plugin during build */\n");
94
+ }
88
95
  return {
89
96
  root: options.targetDir,
90
- base: isDev ? "/" : "./",
97
+ // Always root-absolute: the vscode plugin rewrites built asset URLs as
98
+ // `{{baseUri}}${attr}` (string concatenation), so a "./"-relative base
99
+ // would produce `<baseUri>./assets/…` — a literal `webview./assets`
100
+ // path segment the webview resource host 404s.
101
+ base: "/",
91
102
  build: {
92
103
  outDir: options.outDir,
93
104
  emptyOutDir: true,
@@ -213,10 +224,49 @@ export interface VsceManifest {
213
224
  license?: string;
214
225
  }
215
226
 
227
+ /** Correct the webview dist path baked into the extension-host bundle.
228
+ *
229
+ * @tomjs/vite-plugin-vscode computes `VITE_WEBVIEW_DIST` (the segment its
230
+ * runtime joins onto `context.extensionUri` to form the webview base URI)
231
+ * by stripping `process.cwd()` off the resolved outDir. That model assumes
232
+ * the extension is packaged from the vite project root; with an
233
+ * out-of-tree staging dir (ours: apps/<name>/dist-vscode + generated
234
+ * manifest) the strip misses and the BUILD MACHINE'S ABSOLUTE PATH gets
235
+ * baked into the bundle — at runtime the webview base URI doubles into
236
+ * `…/dist-vscode/Users/…/dist-vscode/webview` and every asset 404s.
237
+ *
238
+ * In the staging layout the correct value is always the literal
239
+ * `"webview"` (the assets dir next to the generated package.json), so the
240
+ * staging step rewrites the joinPath call site — anchored on the
241
+ * `.extensionUri` property read, which survives minification. */
242
+ export async function fixWebviewDistPath(stagingDir: string): Promise<boolean> {
243
+ const bundles = ["extension/index.js", "extension/index.cjs"].map((file) =>
244
+ path.join(stagingDir, file),
245
+ );
246
+ let fixed = false;
247
+ for (const bundle of bundles) {
248
+ if (!fs.existsSync(bundle)) continue;
249
+ const source = await fs.promises.readFile(bundle, "utf-8");
250
+ const rewritten = source.replace(
251
+ // The dist segment may be emitted as a quoted string OR a template
252
+ // literal (tsdown's env define does both depending on content).
253
+ /joinPath\(([A-Za-z_$][\w$]*\.extensionUri),\s*("[^"\n]*"|'[^'\n]*'|`[^`\n]*`)\)/g,
254
+ 'joinPath($1, "webview")',
255
+ );
256
+ if (rewritten !== source) {
257
+ await fs.promises.writeFile(bundle, rewritten, "utf-8");
258
+ fixed = true;
259
+ }
260
+ }
261
+ return fixed;
262
+ }
263
+
216
264
  /** Write the extension-manifest package.json into the staging dir. A VS
217
265
  * Code extension's package.json IS its manifest — the product app's own
218
266
  * package.json (an Expo/One app manifest) can't double as it, so `vsce
219
- * package` runs against the staging dir instead. */
267
+ * package` runs against the staging dir instead. Also applies
268
+ * `fixWebviewDistPath` — staging is the earliest race-free point after
269
+ * the plugin's detached extension-host build has finished. */
220
270
  export async function writeVsceManifest(stagingDir: string, manifest: VsceManifest): Promise<void> {
221
271
  const { engines, main, ...rest } = manifest;
222
272
  const packageJson = {
@@ -230,4 +280,5 @@ export async function writeVsceManifest(stagingDir: string, manifest: VsceManife
230
280
  `${JSON.stringify(packageJson, null, 2)}\n`,
231
281
  "utf-8",
232
282
  );
283
+ await fixWebviewDistPath(stagingDir);
233
284
  }
package/types/index.d.ts CHANGED
@@ -49,9 +49,27 @@ export interface VsceManifest {
49
49
  repository?: unknown;
50
50
  license?: string;
51
51
  }
52
+ /** Correct the webview dist path baked into the extension-host bundle.
53
+ *
54
+ * @tomjs/vite-plugin-vscode computes `VITE_WEBVIEW_DIST` (the segment its
55
+ * runtime joins onto `context.extensionUri` to form the webview base URI)
56
+ * by stripping `process.cwd()` off the resolved outDir. That model assumes
57
+ * the extension is packaged from the vite project root; with an
58
+ * out-of-tree staging dir (ours: apps/<name>/dist-vscode + generated
59
+ * manifest) the strip misses and the BUILD MACHINE'S ABSOLUTE PATH gets
60
+ * baked into the bundle — at runtime the webview base URI doubles into
61
+ * `…/dist-vscode/Users/…/dist-vscode/webview` and every asset 404s.
62
+ *
63
+ * In the staging layout the correct value is always the literal
64
+ * `"webview"` (the assets dir next to the generated package.json), so the
65
+ * staging step rewrites the joinPath call site — anchored on the
66
+ * `.extensionUri` property read, which survives minification. */
67
+ export declare function fixWebviewDistPath(stagingDir: string): Promise<boolean>;
52
68
  /** Write the extension-manifest package.json into the staging dir. A VS
53
69
  * Code extension's package.json IS its manifest — the product app's own
54
70
  * package.json (an Expo/One app manifest) can't double as it, so `vsce
55
- * package` runs against the staging dir instead. */
71
+ * package` runs against the staging dir instead. Also applies
72
+ * `fixWebviewDistPath` — staging is the earliest race-free point after
73
+ * the plugin's detached extension-host build has finished. */
56
74
  export declare function writeVsceManifest(stagingDir: string, manifest: VsceManifest): Promise<void>;
57
75
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAiCA,OAAO,KAAK,EAAE,KAAK,EAAU,UAAU,EAAE,MAAM,MAAM,CAAC;AAEtD;;;0CAG0C;AAC1C,eAAO,MAAM,mBAAmB,yRAAqR,CAAC;AAEtT,MAAM,WAAW,mBAAmB;IAClC;kCAC8B;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB;kEAC8D;IAC9D,MAAM,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,aAAa,EAAE,MAAM,CAAC;IACtB,qDAAqD;IACrD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,0DAA0D;IAC1D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,sDAAsD;IACtD,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,0DAA0D;IAC1D,OAAO,CAAC,EAAE,KAAK,EAAE,CAAC;CACnB;AAgBD;kEACkE;AAClE,wBAAgB,qBAAqB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAInE;AAED,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC,CA4G1F;AAID,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sEAAsE;IACtE,IAAI,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAC;IAC7B,2CAA2C;IAC3C,OAAO,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IACpD,6DAA6D;IAC7D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;qDAGqD;AACrD,wBAAsB,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAajG"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAiCA,OAAO,KAAK,EAAE,KAAK,EAAU,UAAU,EAAE,MAAM,MAAM,CAAC;AAEtD;;;0CAG0C;AAC1C,eAAO,MAAM,mBAAmB,yRAAqR,CAAC;AAEtT,MAAM,WAAW,mBAAmB;IAClC;kCAC8B;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB;kEAC8D;IAC9D,MAAM,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,aAAa,EAAE,MAAM,CAAC;IACtB,qDAAqD;IACrD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,0DAA0D;IAC1D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,sDAAsD;IACtD,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,0DAA0D;IAC1D,OAAO,CAAC,EAAE,KAAK,EAAE,CAAC;CACnB;AAgBD;kEACkE;AAClE,wBAAgB,qBAAqB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAInE;AAED,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC,CAuH1F;AAID,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sEAAsE;IACtE,IAAI,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAC;IAC7B,2CAA2C;IAC3C,OAAO,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IACpD,6DAA6D;IAC7D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;;;kEAckE;AAClE,wBAAsB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAoB7E;AAED;;;;;+DAK+D;AAC/D,wBAAsB,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAcjG"}