1717 * - Externalize bare module imports (e.g., @nuclearplayer/plugin-sdk) so plugins don't
1818 * accidentally try to bundle our runtime dependencies.
1919 */
20- import {
21- dirname ,
22- extname ,
23- isAbsolute ,
24- resolve ,
25- normalize as tauriNormalize ,
26- } from '@tauri-apps/api/path' ;
20+ import { dirname , extname , isAbsolute , resolve } from '@tauri-apps/api/path' ;
2721import { readTextFile } from '@tauri-apps/plugin-fs' ;
2822import type * as EsbuildTypes from 'esbuild-wasm' ;
2923import wasmUrl from 'esbuild-wasm/esbuild.wasm?url' ;
@@ -72,11 +66,6 @@ const cache = new Map<string, string>();
7266
7367const isTs = ( p : string ) => p . endsWith ( '.ts' ) || p . endsWith ( '.tsx' ) ;
7468
75- // esbuild-wasm operates in a forward-slash world. Tauri's path functions
76- // return native separators (backslashes on Windows), so we normalize all
77- // paths to forward slashes before passing them to esbuild.
78- const toForwardSlashes = ( p : string ) => p . replace ( / \\ / g, '/' ) ;
79-
8069/**
8170 * Initialize esbuild-wasm exactly once within this JS context.
8271 *
@@ -127,16 +116,13 @@ export async function compilePlugin(
127116 return undefined ;
128117 }
129118 const entrySource = await readTextFile ( entryPath ) ;
130- const nativeEntryPath = await tauriNormalize ( entryPath ) ;
131- entryPath = toForwardSlashes ( nativeEntryPath ) ;
132119 const key = entryPath + ':' + simpleHash ( entrySource ) ;
133120 if ( cache . has ( key ) ) {
134121 return cache . get ( key ) ;
135122 }
136123
137124 const mod = await getEsbuild ( ) ;
138- const nativeEntryDir = await dirname ( nativeEntryPath ) ;
139- const entryDir = toForwardSlashes ( nativeEntryDir ) ;
125+ const entryDir = await dirname ( entryPath ) ;
140126 const entryLoader : EsbuildTypes . Loader = entryPath . endsWith ( '.tsx' )
141127 ? 'tsx'
142128 : entryPath . endsWith ( '.ts' )
@@ -155,7 +141,6 @@ export async function compilePlugin(
155141 stdin : {
156142 contents : entrySource ,
157143 sourcefile : entryPath ,
158- resolveDir : entryDir ,
159144 loader : entryLoader ,
160145 } ,
161146 bundle : true ,
@@ -169,9 +154,8 @@ export async function compilePlugin(
169154 external : [ '@nuclearplayer/plugin-sdk' ] ,
170155
171156 // Keep a neutral working directory. Real resolution happens inside our
172- // virtual "tauri-fs" plugin (below). Use native path separators here
173- // because esbuild validates this as an OS-native absolute path.
174- absWorkingDir : nativeEntryDir ,
157+ // virtual "tauri-fs" plugin (below).
158+ absWorkingDir : '/' ,
175159
176160 // Inline tsconfig so esbuild doesn't try to read tsconfig.json from disk.
177161 tsconfigRaw : { compilerOptions : { } } ,
@@ -190,54 +174,33 @@ export async function compilePlugin(
190174 // lands in this namespace will be loaded by our onLoad hook below,
191175 // using Tauri's readTextFile instead of Node's fs.
192176 build . onResolve ( { filter : / .* / } , async ( args ) => {
193- // 1) The entry point itself.
194- // Tag it with our namespace to keep it in the virtual fs flow.
195177 if ( args . kind === 'entry-point' ) {
196- return {
197- path : toForwardSlashes ( args . path ) ,
198- namespace : 'tauri-fs' ,
199- } ;
178+ return { path : entryPath , namespace : 'tauri-fs' } ;
200179 }
201180
202- // 2) Absolute paths like "/Users/…/index.ts" or "C:\Users\…\index.ts".
203- // Keep the absolute path as-is, just force the namespace.
204181 if ( await isAbsolute ( args . path ) ) {
205- return {
206- path : toForwardSlashes ( args . path ) ,
207- namespace : 'tauri-fs' ,
208- } ;
182+ return { path : args . path , namespace : 'tauri-fs' } ;
209183 }
210184
211- // 3) Relative paths like "./foo" or "../bar".
212- // Resolve them to an absolute path based on the current file's directory.
213185 if ( / ^ \. \. ? [ / \\ ] / . test ( args . path ) ) {
214- return {
215- path : toForwardSlashes (
216- await resolve ( args . resolveDir || entryDir , args . path ) ,
217- ) ,
218- namespace : 'tauri-fs' ,
219- } ;
186+ const importerDir = args . importer
187+ ? await dirname ( args . importer )
188+ : entryDir ;
189+ const resolved = await resolve ( importerDir , args . path ) ;
190+ return { path : resolved , namespace : 'tauri-fs' } ;
220191 }
221192
222- // 4) Bare module specifiers (e.g., "react", "@nuclearplayer/plugin-sdk").
223- // We do not bundle those. The host app should provide them at runtime.
224- if ( args . path === '@nuclearplayer/plugin-sdk' ) {
225- return { path : args . path , external : true } ;
226- }
227193 return { path : args . path , external : true } ;
228194 } ) ;
229195 // Given a path in our "tauri-fs" namespace, fetch the file content
230196 // via Tauri's filesystem API and tell esbuild how to treat it.
231197 build . onLoad (
232198 { filter : / .* / , namespace : 'tauri-fs' } ,
233199 async ( args ) => {
234- // Special-case the entry file: we already have its contents and loader.
235- if ( toForwardSlashes ( args . path ) === entryPath ) {
236- const thisDir = entryDir ;
200+ if ( args . path === entryPath ) {
237201 return {
238202 contents : entrySource ,
239203 loader : entryLoader ,
240- resolveDir : thisDir ,
241204 } ;
242205 }
243206
@@ -279,8 +242,7 @@ export async function compilePlugin(
279242 : p . endsWith ( '.ts' )
280243 ? 'ts'
281244 : 'js' ;
282- const thisDir = toForwardSlashes ( await dirname ( p ) ) ;
283- return { contents, loader, resolveDir : thisDir } ;
245+ return { contents, loader } ;
284246 }
285247 }
286248
0 commit comments