Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@sveltejs/adapter-node failure due to ES version #1667

Closed
Darth-Knoppix opened this issue Jun 10, 2021 · 13 comments · Fixed by #1675
Closed

@sveltejs/adapter-node failure due to ES version #1667

Darth-Knoppix opened this issue Jun 10, 2021 · 13 comments · Fixed by #1675
Labels
bug Something isn't working

Comments

@Darth-Knoppix
Copy link

Describe the bug
When creating the skeleton project with TypeScript and using @sveltejs/adapter-node, the build succeeds with warnings and fails to run when using node build.

Logs

Build warning
> Using @sveltejs/adapter-node
 > .svelte-kit/node/index.js:18:31: warning: "import.meta" is not available in the configured target environment ("es2019") and will be empty
    18 │ global.require = createRequire(import.meta.url);~~~~~~~~~~~
   tsconfig.json:6:12: note: The target environment was set to "es2019" here
     6 │     "target": "es2019",
       ╵               ~~~~~~~~

 > .svelte-kit/node/index.js:15792:40: warning: "import.meta" is not available in the configured target environment ("es2019") and will be empty
    15792 │ const __dirname = dirname(fileURLToPath(import.meta.url));~~~~~~~~~~~
   tsconfig.json:6:12: note: The target environment was set to "es2019" here
        6 │     "target": "es2019",
          ╵               ~~~~~~~~

  ✔ done
✨  Done in 2.01s.
Run error
╰─$ node build
node:internal/process/esm_loader:74
    internalBinding('errors').triggerUncaughtException(
                              ^

TypeError [ERR_INVALID_ARG_VALUE]: The argument 'filename' must be a file URL object, file URL string, or absolute path string. Received undefined
    at new NodeError (node:internal/errors:363:5)
    at createRequire (node:internal/modules/cjs/loader:1203:11)
    at file:///Users/seth.corker/projects/mfe-example/blog/build/index.js:1566:18
    at ModuleJob.run (node:internal/modules/esm/module_job:175:25)
    at async Loader.import (node:internal/modules/esm/loader:178:24)
    at async Object.loadESM (node:internal/process/esm_loader:68:5) {
  code: 'ERR_INVALID_ARG_VALUE'
}

To Reproduce

  1. Create a new sveltekit project with the skeleton template
  2. Add @sveltejs/adapter-node as a dev dependency
  3. Update svelte.config.js to use the adapter
  4. npm run build
  5. node build

Expected behavior
The server runs as expected when using node build

Stacktraces

Stack trace
node:internal/process/esm_loader:74
    internalBinding('errors').triggerUncaughtException(
                              ^

TypeError [ERR_INVALID_ARG_VALUE]: The argument 'filename' must be a file URL object, file URL string, or absolute path string. Received undefined
    at new NodeError (node:internal/errors:363:5)
    at createRequire (node:internal/modules/cjs/loader:1203:11)
    at file:///Users/seth.corker/projects/mfe-example/blog/build/index.js:1566:18
    at ModuleJob.run (node:internal/modules/esm/module_job:175:25)
    at async Loader.import (node:internal/modules/esm/loader:178:24)
    at async Object.loadESM (node:internal/process/esm_loader:68:5) {
  code: 'ERR_INVALID_ARG_VALUE'
}

Information about your SvelteKit Installation:

Diagnostics
  System:
    OS: macOS 11.4
    CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
    Memory: 1.07 GB / 32.00 GB
    Shell: 5.8 - /bin/zsh
  Binaries:
    Node: 16.3.0 - ~/.nvm/versions/node/v16.3.0/bin/node
    Yarn: 1.22.5 - /usr/local/bin/yarn
    npm: 7.15.1 - ~/.nvm/versions/node/v16.3.0/bin/npm
    Watchman: 4.9.0 - /usr/local/bin/watchman
  Browsers:
    Chrome: 91.0.4472.101
    Firefox: 86.0.1
    Firefox Developer Edition: 77.0
    Safari: 14.1.1
  npmPackages:
    @sveltejs/adapter-node: next => 1.0.0-next.25 
    @sveltejs/kit: next => 1.0.0-next.114 
    svelte: ^3.34.0 => 3.38.2

Severity
I found a workaround:

Update the tsconfig.json and change the target to match the target version specified in@sveltejs/adapter-node. I suspect es2020 should be used for SvelteKit and the adapter to work together as expected.

//tsconfig.json
{
    "compilerOptions": {
-        "target": "es2019"
+        "target": "es2020"
    }
}
@bjon
Copy link
Contributor

bjon commented Jun 11, 2021

I think a better fix for this would be to add esbuild.build({..., target: 'es2020'}), in adapter-node.

@bjon bjon mentioned this issue Jun 11, 2021
5 tasks
@Darth-Knoppix
Copy link
Author

Sounds like a plan, I haven't investigated the codebase too much so this was the easiest workaround I could find with my limited knowledge.

@benmccann
Copy link
Member

Will that work on older versions of Node? #772 (comment)

@Conduitry
Copy link
Member

Conduitry commented Jun 11, 2021

Hm. Is there something we could do instead of import.meta.url that works in es2019? Otherwise I'm not sure how to avoid compiling to es2020. It'd be nice if we could target 2019 but still enable import.meta.url but I don't know that esbuild would allow that.

Edit: Oh, I guess it's TypeScript that's compiling import.meta.url away in es2019 mode? I'm not sure.

@Conduitry
Copy link
Member

Okay, it is esbuild that's displaying this warning, because it's looking at tsconfig.json and overriding its compilation target based on what's in the file.

We can use the tsconfig option to esbuild.build() point to a different file (say, one embedded in the @sveltejs/adapter-node package) so that esbuild doesn't see the target: 'es2019' in the user's tsconfig.json. This lets the build proceed without warnings (which means it doesn't remove import.meta stuff), and (at least in my tests) the built, adapted app works on Node 12.

This is a little hacky, but I think this is a better solution than changing tsconfig.json to es2020, which would mean the built app wouldn't necessarily work on Node 12. I'll open a PR with this change shortly.

@Conduitry
Copy link
Member

I think there's actually a much simpler way of achieving this same result: by explicitly setting target: 'es2020' when calling esbuild.build(). I think the tsconfig.json's target was only being looked at because adapter-node wasn't specifying one when calling esbuild.build().

The question then is whether that's safe to do. I don't think I have an answer to that. As far as I know, all of the user's code would already be going through TypeScript, and so would be getting compiled to ES2019, and the code being introduced by the adapter works on Node 12 (despite using some ES2020 features, like import.meta), but I don't know about npm dependencies of the user's app. They might be using features that aren't supported in Node 12, and I don't think esbuild would bother transpiling them if it were told target: 'es2020'.

We may have to eventually drop es2019 / Node 12 support, but for now, what we have is definitely broken on all versions of Node because of the es2019/es2020 mismatch and the reliance on import.meta. I think my vote is for now to add an explicit target: 'es2020' to the esbuild.build() call in @sveltejs/adapter-node, and then see what other issues arise or still remain.

@Conduitry
Copy link
Member

Specifying target: 'node12' in the call to esbuild.build() in the adapter might be a reasonable way to handle this. This allows the use of import.meta but will still transpile things that aren't supported in Node 12 - e.g., optional chaining.

@benmccann
Copy link
Member

I wonder if that would also start letting us convert some SvelteKit code to use ?. which is a common stumbling point for community contributors

@Conduitry
Copy link
Member

Even if we changed the esbuild.build() call in other adapters as well, I think that would still be a problem in development mode. There is (I believe) no build step in the @sveltejs/kit package currently, and so users would still be getting the ?. syntax in what Node is trying to run, which would be a problem for Node 12.

@Conduitry
Copy link
Member

I've opened #1675 with the target: 'node12' change I mentioned above. I'd appreciate it if folks could take a look and try that out with their projects.

@joidegn
Copy link

joidegn commented Jun 12, 2021

Tried it out and can confirm that it fixes the issue for me.

I have "target": "es2018" in my tsconfig.json.

@benmccann benmccann added the bug Something isn't working label Jun 12, 2021
@benmccann benmccann changed the title Build with @sveltejs/adapter-node does not run correctly @sveltejs/adapter-node failure due to ES version Jun 12, 2021
@Conduitry
Copy link
Member

This should be fixed now in version 1.0.0-next.26 of the Node adapter.

@cupcakearmy
Copy link

@Conduitry I still have the issue 1.0.0-next.27

"devDependencies": {
    "@sveltejs/adapter-node": "^1.0.0-next.27",
    "@sveltejs/kit": "^1.0.0-next.115",
  }

Node: v14.17.0

Build

npm run build
> Using @sveltejs/adapter-node
 > .svelte-kit/node/index.js:18:31: warning: "import.meta" is not available in the configured target environment ("es2019") and will be empty
    18 │ global.require = createRequire(import.meta.url);
       ╵                                ~~~~~~~~~~~
   tsconfig.json:6:12: note: The target environment was set to "es2019" here
     6 │     "target": "es2019",
       ╵               ~~~~~~~~

 > .svelte-kit/node/index.js:15792:40: warning: "import.meta" is not available in the configured target environment ("es2019") and will be empty
    15792 │ const __dirname = dirname(fileURLToPath(import.meta.url));
          ╵                                         ~~~~~~~~~~~
   tsconfig.json:6:12: note: The target environment was set to "es2019" here
        6 │     "target": "es2019",
          ╵               ~~~~~~~~

  ✔ done

Run

node build
internal/process/esm_loader.js:74
    internalBinding('errors').triggerUncaughtException(
                              ^

TypeError [ERR_INVALID_ARG_VALUE]: The argument 'filename' must be a file URL object, file URL string, or absolute path string. Received undefined

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants