swc-project / swc

Rust-based platform for the Web
https://swc.rs
Apache License 2.0
31.21k stars 1.23k forks source link

@swc-node/register — Files are not transpiled on Windows with tsconfig.json present #8639

Open fire332 opened 9 months ago

fire332 commented 9 months ago

Describe the bug

I cannot reproduce this with the playground or CLI, only with @swc-node/register

node --import @swc-node/register/esm-register ./index.ts

file:///C:/New%20folder/index.ts:1
declare global {
        ^^^^^^

SyntaxError: Unexpected identifier 'global'
    at ModuleLoader.moduleStrategy (node:internal/modules/esm/translators:167:18)
    at callTranslator (node:internal/modules/esm/loader:285:14)
    at ModuleLoader.moduleProvider (node:internal/modules/esm/loader:291:30)
    at async link (node:internal/modules/esm/module_job:76:21)

This issue ONLY occurs when a tsconfig.json is present. Even if it is completely blank (0 bytes; not even {}). Same issue occurs with recommended tsconfig.json compilerOptions. If tsconfig.json is deleted, this issue doesn't occur.

Steps to reproduce

  1. pnpm init
  2. pnpm add -D @swc-node/register
  3. Paste input code from below into ./index.ts.
  4. touch tsconfig.json
  5. node --import @swc-node/register/esm-register ./index.ts

Input code

// Also happens with declare module 'xxx'
declare global {
  namespace Express {
    interface Locals {
      cspNonce?: string
    }
  }
}

Config

No config.

Playground link (or link to the minimal reproduction)

https://play.swc.rs/?version=1.4.0&code=H4sIAAAAAAAAAz2OzQrCMBCE74W8w9yqr2ART97Ed4jrtgbyx24OQum7a5roZZaZD3bGhZykgN9ZWBWzpICxu3Eyg2v8xT5w6biZSs3wZPJWGItPD%2BuxmgGINrBmS4xrf7vHgIuFZa7glsj6fw6Q5nuKxJcTtIiLy9TIVs9XttpFKWqBzRnn3%2BDDcV%2FxAXF5lWHGAAAA&config=H4sIAAAAAAAAA1VPOw7DIAzdOQXy3KFi6NA79BCIOhERAYQdqSjK3QsJpM1mv4%2Ff8yqkhIkMPOVaxrJEnQjTuReEsmf9KQhwjkgm2chw6yxTpQbtCHdoOxhgnUbk6kJSd6WaA1wIhN3RsNl6O%2BT%2FTBPmmJDoKqxS7UeH10TRUmEO72Un2y%2B179HgAT9RDzsPg6VXd3JaUGxfBMLf3xcBAAA%3D

SWC Info output

Operating System:
        Platform: win32
        Arch: x64
        Machine Type: x86_64
        Version: Windows 11 Enterprise
        CPU: (24 cores)
            Models: AMD Ryzen 9 5900X 12-Core Processor

    Binaries:
        Node: 20.11.0
        npm: N/A
        Yarn: N/A
        pnpm: N/A

    Relevant Packages:
        @swc/core: N/A
        @swc/helpers: N/A
        @swc/types: N/A

    SWC Config:
        output: N/A
        .swcrc path: N/A

    Next.js info:
        output: N/A

Above output seems broken. pnpm --version: 18.15.2

pnpm list --depth Infinity

New folder@1.0.0 C:\New folder

devDependencies:
@swc-node/register 1.8.0
├─┬ @swc-node/core 1.12.0
│ ├─┬ @swc/core 1.4.1 peer
│ │ ├── @swc/core-darwin-arm64 1.4.1
│ │ ├── @swc/core-darwin-x64 1.4.1
│ │ ├── @swc/core-linux-arm-gnueabihf 1.4.1
│ │ ├── @swc/core-linux-arm64-gnu 1.4.1
│ │ ├── @swc/core-linux-arm64-musl 1.4.1
│ │ ├── @swc/core-linux-x64-gnu 1.4.1
│ │ ├── @swc/core-linux-x64-musl 1.4.1
│ │ ├── @swc/core-win32-arm64-msvc 1.4.1
│ │ ├── @swc/core-win32-ia32-msvc 1.4.1
│ │ ├── @swc/core-win32-x64-msvc 1.4.1
│ │ ├── @swc/counter 0.1.3
│ │ └── @swc/types 0.1.5
│ └── @swc/types 0.1.5 peer
├─┬ @swc-node/sourcemap-support 0.4.0
│ ├─┬ source-map-support 0.5.21
│ │ ├── buffer-from 1.1.2
│ │ └── source-map 0.6.1
│ └── tslib 2.6.2
├─┬ @swc/core 1.4.1 peer
│ ├── @swc/core-darwin-arm64 1.4.1
│ ├── @swc/core-darwin-x64 1.4.1
│ ├── @swc/core-linux-arm-gnueabihf 1.4.1
│ ├── @swc/core-linux-arm64-gnu 1.4.1
│ ├── @swc/core-linux-arm64-musl 1.4.1
│ ├── @swc/core-linux-x64-gnu 1.4.1
│ ├── @swc/core-linux-x64-musl 1.4.1
│ ├── @swc/core-win32-arm64-msvc 1.4.1
│ ├── @swc/core-win32-ia32-msvc 1.4.1
│ ├── @swc/core-win32-x64-msvc 1.4.1
│ ├── @swc/counter 0.1.3
│ └── @swc/types 0.1.5
├── colorette 2.0.20
├─┬ debug 4.3.4
│ └── ms 2.1.2
├── pirates 4.0.6
├── tslib 2.6.2
└── typescript 5.3.3 peer

Expected behavior

Node shouldn't throw a syntax error.

Actual behavior

No response

Version

See above.

Additional context

No response

kdy1 commented 9 months ago

cc @Brooooooklyn

fire332 commented 8 months ago

I've narrowed the issue down.

TL;DR

compile function here checks to see if filename is contained in options.files to determine whether to transpile but that will always be true as the string passed by Node.JS to filename starts with file:/// while the string it checks against doesn't.

This issue isn't present without tsconfig.json because options.files is not set when tsconfig.json is not present.

Detailed Description

The string passed to the filename parameter of the compile function here starts with file:///. When a tsconfig is parsed, files is attached to options argument of compile here. When the files property is present, compile will check to see if filename is contained in files. However, on the PLATFORM === 'win32' branch, filename !== resolve(process.cwd(), file) will always be true as the right hand side of the conditional expression does not start with file:/// while the left hand side does. That means files will never be transpiled.

fire332 commented 8 months ago

On a second note, the check on Windows will never work anyways because path.resolve converts the separators to the Windows version while filename uses POSIX-style separators. Maybe instead of filename !== resolve(process.cwd(), file), use !normalize(filename).endsWith(resolve(process.cwd(), file)).

Related: https://github.com/swc-project/swc-node/issues/710#issuecomment-1755713552

psychobolt commented 8 months ago

I've mentioned in my comment here, to fix the issue the protocol can be removed using fileUrlToPath