Skip to content
This repository was archived by the owner on Feb 28, 2026. It is now read-only.

Commit 66f48bc

Browse files
authored
Merge pull request #37 from NuclearPlayer/fix/windows-plugins-fix
Fix/windows plugins fix
2 parents 784da1d + f53d115 commit 66f48bc

File tree

1 file changed

+13
-51
lines changed

1 file changed

+13
-51
lines changed

packages/player/src/services/plugins/pluginCompiler.ts

Lines changed: 13 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,7 @@
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';
2721
import { readTextFile } from '@tauri-apps/plugin-fs';
2822
import type * as EsbuildTypes from 'esbuild-wasm';
2923
import wasmUrl from 'esbuild-wasm/esbuild.wasm?url';
@@ -72,11 +66,6 @@ const cache = new Map<string, string>();
7266

7367
const 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

Comments
 (0)