Help on Windows Support
antfu opened this issue · comments
The current implementation failed on Windows, while unfortunately I don't have a Windows to test out. Would use some help on the fix. Thanks.
Seems using relative paths working, with absolute paths there is no way man (I'll try one last time to see if there's any luck):
F:\work\projects\quini\GitHub\antfu\esbuild-node-loader>pnpm run test
> esbuild-node-loader@0.2.0 test F:\work\projects\quini\GitHub\antfu\esbuild-node-loader
> node --experimental-loader ./loader.mjs test/entry.ts
(node:23624) ExperimentalWarning: --experimental-loader is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
• • • • • • (6 / 6)
Total: 6
Passed: 6
Skipped: 0
Duration: 1146.71ms
test/entry.ts changes
@@ -1,12 +1,20 @@
import assert from 'assert'
import { test } from 'uvu'
import execa from 'execa'
+import { relative } from 'path'
+
+const cwd = process.cwd()
+function relativize(path: string) {
+ const url = relative(cwd, path)
+ // console.log(`FROM ${path} => ${url}`)
+ return `./${url}`
+}
test('register', async() => {
const { stdout } = await execa('node', [
'--experimental-loader',
- `${process.cwd()}/loader.mjs`,
- `${process.cwd()}/test/fixture.ts`,
+ relativize(`${cwd}/loader.mjs`),
+ relativize(`${cwd}/test/fixture.ts`),
])
assert(stdout === 'text')
})
@@ -14,8 +22,8 @@
test('register2', async() => {
const { stdout } = await execa('node', [
'--experimental-loader',
- `${process.cwd()}/loader.mjs`,
- `${process.cwd()}/test/fixture.arrowFunction.ts`,
+ relativize(`${cwd}/loader.mjs`),
+ relativize(`${cwd}/test/fixture.arrowFunction.ts`),
])
assert(stdout === 'hello from ts')
})
@@ -23,8 +31,8 @@
test('register3', async() => {
const { stdout } = await execa('node', [
'--experimental-loader',
- `${process.cwd()}/loader.mjs`,
- `${process.cwd()}/test/fixture.import.ts`,
+ relativize(`${cwd}/loader.mjs`),
+ relativize(`${cwd}/test/fixture.import.ts`),
])
assert(stdout === 'export')
})
@@ -32,8 +40,8 @@
test('register cjs', async() => {
const { stdout } = await execa('node', [
'--experimental-loader',
- `${process.cwd()}/loader.mjs`,
- `${process.cwd()}/test/fixture.cjs.ts`,
+ relativize(`${cwd}/loader.mjs`),
+ relativize(`${cwd}/test/fixture.cjs.ts`),
])
assert(stdout === 'fs imported')
})
@@ -41,8 +49,8 @@
test('package type module', async() => {
const { stdout } = await execa('node', [
'--experimental-loader',
- `${process.cwd()}/loader.mjs`,
- `${process.cwd()}/test/fixture-type-module/index.js`,
+ relativize(`${cwd}/loader.mjs`),
+ relativize(`${cwd}/test/fixture-type-module/index.js`),
])
assert(stdout === 'foo')
})
@@ -50,8 +58,8 @@
test('import type module', async() => {
const { stdout } = await execa('node', [
'--experimental-loader',
- `${process.cwd()}/loader.mjs`,
- `${process.cwd()}/test/import-mjs/index.js`,
+ relativize(`${cwd}/loader.mjs`),
+ relativize(`${cwd}/test/import-mjs/index.js`),
])
assert(stdout === 'foo')
})
loader.mjs changes
@@ -1,8 +1,16 @@
import { URL, pathToFileURL, fileURLToPath } from 'url'
import { transformSync } from 'esbuild'
import fs from 'fs'
+import { relative } from 'path'
-const baseURL = pathToFileURL(`${process.cwd()}/`).href
+const cwd = process.cwd()
+function relativize(path) {
+ const url = relative(cwd, path)
+ //console.log(`FROM ${path} => ${url}`)
+ return `./${url}`
+}
+
+const baseURL = pathToFileURL(relativize(`${cwd}/`)).href
const isWindows = process.platform === "win32"
const extensionsRegex = /\.ts$/
@@ -46,12 +54,12 @@
const { url, format } = context
if (extensionsRegex.test(url)) {
- let filename = fileURLToPath(url)
- if (isWindows)
- filename = filename.slice(1)
+ // let filename = fileURLToPath(url)
+ // if (isWindows)
+ // filename = filename.slice(1)
const { code: js, warnings, map: jsSourceMap } = transformSync(source.toString(), {
- sourcefile: filename,
+ sourcefile: url,
sourcemap: 'both',
loader: 'ts',
target: 'esnext',
@antfu Working, just modify transformSource
from loader.mjs
:
Adjust filename
assigment:
let filename = url
if (!isWindows)
filename = fileURLToPath(url)
To make the tests working you need to use relativize
from previous comment.
transformSource
code:
export function transformSource(source, context, defaultTransformSource) {
const { url, format } = context
if (extensionsRegex.test(url)) {
let filename = url
if (!isWindows)
filename = fileURLToPath(url)
const { code: js, warnings, map: jsSourceMap } = transformSync(source.toString(), {
sourcefile: filename,
sourcemap: 'both',
loader: 'ts',
target: 'esnext',
format: format === 'module' ? 'esm' : 'cjs',
})
if (warnings && warnings.length > 0) {
for (const warning of warnings) {
console.log(warning.location)
console.log(warning.text)
}
}
return {
source: js,
}
}
// Let Node.js handle all other sources.
return defaultTransformSource(source, context, defaultTransformSource)
}
Maybe you need to check if script is provided with absolute path and then relativize from cwd
: using esno
I've never seen provide scripts with absolute paths, always with relative paths, I think if also working previous fix on linux/macosx, just include a warning/hint for windows users to use always relative paths to root directory.
Ideally I think we would like to have absolute path working as well
Found these 2 issues, I have tried with no luck: