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

Cannot import external JSON in vite.config.ts on Node v22 #17291

Closed
7 tasks done
SegaraRai opened this issue May 23, 2024 · 4 comments · Fixed by #17307
Closed
7 tasks done

Cannot import external JSON in vite.config.ts on Node v22 #17291

SegaraRai opened this issue May 23, 2024 · 4 comments · Fixed by #17307

Comments

@SegaraRai
Copy link
Contributor

SegaraRai commented May 23, 2024

Describe the bug

EDIT: I thought I was trying to switch between Node.js versions using Volta, but in fact when I called vite from pnpm it was fixed at Node v22.
I tried again with v20 and found no problem when using import assertions, so I have corrected the title.
Import assertions have been disabled since Node v22.0.0, so we can import JSON up to Node v20 or v21 with no problem if we use the conventional notation: assert { type: "json" }.


I am trying to use @iconify-json/meteocons in my Vite plugin.
I tried the following import methods, but none of them worked:

import data from "@iconify-json/meteocons";
import data from "@iconify-json/meteocons/icons.json";
import data from "@iconify-json/meteocons/icons.json" assert { type: "json" };
import data from "@iconify-json/meteocons/icons.json" with { type: "json" };

Those will fail with one of the following errors:

TypeError [ERR_IMPORT_ATTRIBUTE_MISSING]: Module "file:///.../node_modules/@iconify-json/meteocons/icons.json" needs an import attribute of "type: json"

or

SyntaxError: Unexpected identifier 'assert'

I believe that importing JSON in ESM style config files is no longer possible in Node.js v22 because Node.js v22 only supports import attributes instead of deprecated import assertions, and because esbuild removes import attributes under certain conditions (at least with target: ["node18"]).

I have verified that by patching the following line to target: ["node22"], it works correctly for both Node v20 and Node v22.

target: ['node18'],

Reproduction

https://github.com/SegaraRai/vite-config-import-json

Steps to reproduce

Run pnpm i followed by pnpm build with Node.js v22.
An error log is also available in GitHub Actions.

System Info

System:
    OS: Windows 11 10.0.22631
    CPU: (12) x64 AMD Ryzen 5 2600X Six-Core Processor
    Memory: 6.00 GB / 31.93 GB
  Binaries:
    Node: 22.2.0 - ~\AppData\Local\Volta\tools\image\node\22.2.0\node.EXE
    Yarn: 1.22.18 - ~\AppData\Local\Volta\tools\image\yarn\1.22.18\bin\yarn.CMD
    npm: 10.5.2 - ~\AppData\Local\Volta\tools\image\node\20.13.1\npm.CMD
    pnpm: 9.0.6 - C:\Program Files\Volta\pnpm.EXE
    bun: 1.1.8 - ~\.bun\bin\bun.EXE
  Browsers:
    Edge: Chromium (123.0.2420.97)
    Internet Explorer: 11.0.22621.3527
  npmPackages:
    vite: ^5.2.11 => 5.2.11

Used Package Manager

pnpm

Logs

Click to expand! - ERR_IMPORT_ATTRIBUTE_MISSING version
> vite build "--debug"

failed to load config from ...\vite-config-import-json\vite.config.ts
error during build:
TypeError [ERR_IMPORT_ATTRIBUTE_MISSING]: Module "file:///.../vite-config-import-json/node_modules/.pnpm/@iconify-json+meteocons@1.1.4/node_modules/@iconify-json/meteocons/icons.json" needs an import attribute of "type: json"
    at validateAttributes (node:internal/modules/esm/assert:88:15)
    at defaultLoad (node:internal/modules/esm/load:153:3)
    at async ModuleLoader.load (node:internal/modules/esm/loader:541:7)
    at async ModuleLoader.moduleProvider (node:internal/modules/esm/loader:422:45)
 ELIFECYCLE  Command failed with exit code 1.
Click to expand! - SyntaxError version
> vite build "--debug"

failed to load config from ...\vite-config-import-json\vite.config.ts
error during build:
SyntaxError: Unexpected identifier 'assert'
    at compileSourceTextModule (node:internal/modules/esm/utils:337:16)
    at ModuleLoader.moduleStrategy (node:internal/modules/esm/translators:166:18)
    at callTranslator (node:internal/modules/esm/loader:416:14)
    at ModuleLoader.moduleProvider (node:internal/modules/esm/loader:422:30)
    at async link (node:internal/modules/esm/module_job:88:21)
 ELIFECYCLE  Command failed with exit code 1.

Validations

@silverwind
Copy link

silverwind commented May 23, 2024

Maybe duplicate of #14674, at least I noticed the same bug that vite incorrectly strips import assertions during compilation against a node18 target. esbuild alone preserves it fine with a node18 target.

@SegaraRai
Copy link
Contributor Author

SegaraRai commented May 24, 2024

In my case, I feel the problem in processing vite.config.ts, not in the bundling of app itself.
Config files are bundled in a different manner than the app itself, and their settings are hard-coded.

BTW, there seems to be no doubt that esbuild is erasing import attributes.

@SegaraRai SegaraRai changed the title Cannot import external JSON in vite.config.ts on Node v20+ Cannot import external JSON in vite.config.ts on Node v22 May 24, 2024
@silverwind
Copy link

silverwind commented May 24, 2024

BTW, there seems to be no doubt that esbuild is erasing import attributes.

That looks like a bug in esbuild. They were initially introduced in node 21 but recently backported into 18 and 20. I opened evanw/esbuild#3778.

@SegaraRai
Copy link
Contributor Author

For anyone having trouble: dynamic import is not converted by esbuild, so the following code will import JSON in Node v22 as well:

const { default: meteocons } = await import(
  "@iconify-json/meteocons/icons.json",
  {
    with: { type: "json" },
  }
);

@github-actions github-actions bot locked and limited conversation to collaborators Aug 14, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants