vite icon indicating copy to clipboard operation
vite copied to clipboard

Support Import Assertions

Open xiaoxiangmoe opened this issue 3 years ago • 25 comments

https://github.com/tc39/proposal-import-assertions

import json from "./foo.json" assert { type: "json" };

Vite should support import-assertions because it has entered stage 3.

xiaoxiangmoe avatar Sep 15 '21 06:09 xiaoxiangmoe

Also note that typescript is planning to include import assertions in 4.5.

IanVS avatar Sep 15 '21 13:09 IanVS

This would also help with environment-specific imports, since the ?client and ?server suffixes cause a lot of issues with intellisense. Import assertions would help alleviate this (and maybe other Vite suffixes too).

EDIT: This is incorrect as that's not what import assertions are for.

bluwy avatar Sep 15 '21 15:09 bluwy

TypeScript has merged import assertion support, so it should be coming relatively soon!

There has been a lot of community interest in using import assertions in Astro. Would love to support this effort!

natemoo-re avatar Sep 22 '21 20:09 natemoo-re

TypeScript has merged import assertion support, so it should be coming relatively soon!

There has been a lot of community interest in using import assertions in Astro. Would love to support this effort!

@natemoo-re Feel free to start a PR that moves alongside the main branch 🙂

Shinigami92 avatar Sep 23 '21 10:09 Shinigami92

Would love to see this added as well. Is there a workaround for the time being?

mkilpatrick avatar Apr 26 '22 19:04 mkilpatrick

🔴 FYI; this issue is participating to quite a few problems, such as surprise crashes late in the release cycle (upon starting in staging or prod for some) .

  • Node LTS is now 16.15.0 LTS and require import assertions for json files, and crashes otherwise.
  • Some companies like Heroku upped their default "buildpacks" to latest LTS.
  • ViteJS force people to not respect the standard (by preventing import assertions usage)

practical consequence for quite a few people with a project on a PaaS like heroku, built with vite, importing json files, and built/tested on non latest-node-LTS-enabled CI server: surprise crash when landing in staging or prod for those without staging.

rvion avatar May 03 '22 14:05 rvion

Is there anything specific Vite has to cover for import assertions? We've updated our dependencies (esbuild, es-module-lexer, etc) to already support import assertions. So right now they should be left as is, as Vite doesn't do anything special with them yet. If there are issues related to it, it would be great to provide a repro to investigate.

bluwy avatar May 03 '22 14:05 bluwy

@rvion one mitigating strategy to prevent these kinds of issues is to use something like nvm or https://volta.sh/ to be sure that everyone is using the same node version, and also you should check that your CI/CD is locked to a specific node version.

IanVS avatar May 03 '22 14:05 IanVS

I'm also interested on seeing this supported by vite, advising users to remain out of date of the environment updates shouldn't be the answer.

As a temporary workaround I'd suggest to pre process your JSON files and convert them into JS modules to avoid the asserts error on build time.

darthega avatar May 09 '22 11:05 darthega

@bluwy it appears to be related to babel

SyntaxError: /Users/mkilpatrick/Desktop/site-starter-react-basic/src/templates/index.tsx?update=1652978858508: Support for the experimental syntax 'importAssertions' isn't currently enabled (23:31):
21 | import { renderToString } from 'react-dom/server';
22 | import '../index.css';
> 23 | import json from './foo.json' assert { type: 'raw' };
| ^
24 |
25 | /**
Add @babel/plugin-syntax-import-assertions (https://github.com/babel/babel/tree/main/packages/babel-plugin-syntax-import-assertions) to the 'plugins' section of your Babel config to enable parsing.
at instantiate (/Users/mkilpatrick/Desktop/site-starter-react-basic/node_modules/@babel/parser/lib/index.js:72:32)
at constructor (/Users/mkilpatrick/Desktop/site-starter-react-basic/node_modules/@babel/parser/lib/index.js:358:12)
at Object.raise (/Users/mkilpatrick/Desktop/site-starter-react-basic/node_modules/@babel/parser/lib/index.js:3335:19)
at Object.expectPlugin (/Users/mkilpatrick/Desktop/site-starter-react-basic/node_modules/@babel/parser/lib/index.js:3384:16)
at Object.maybeParseImportAssertions (/Users/mkilpatrick/Desktop/site-starter-react-basic/node_modules/@babel/parser/lib/index.js:16289:12)
at Object.parseImport (/Users/mkilpatrick/Desktop/site-starter-react-basic/node_modules/@babel/parser/lib/index.js:16160:29)
at Object.parseImport (/Users/mkilpatrick/Desktop/site-starter-react-basic/node_modules/@babel/parser/lib/index.js:10155:30)
at Object.parseStatementContent (/Users/mkilpatrick/Desktop/site-starter-react-basic/node_modules/@babel/parser/lib/index.js:14643:27)
at Object.parseStatementContent (/Users/mkilpatrick/Desktop/site-starter-react-basic/node_modules/@babel/parser/lib/index.js:10267:18)
at Object.parseStatement (/Users/mkilpatrick/Desktop/site-starter-react-basic/node_modules/@babel/parser/lib/index.js:14533:17)

mkilpatrick avatar May 19 '22 16:05 mkilpatrick

@bluwy Here's a minimal example that reproduces the error

jimboHenris avatar May 19 '22 16:05 jimboHenris

Thanks for the example @jimboHenris. It looks like you need to install @babel/plugin-syntax-import-assertions and adjust the vite config to:

export default defineConfig({
  plugins: [
    react({
      babel: {
        plugins: ['@babel/plugin-syntax-import-assertions'],
      },
    }),
  ],
});

For it to work. Perhaps we can add the plugin to plugin-react by default.

But I'm also seeing an error which Vite is returning Javascript when importing ../../package.json. This seems like a bug to me, and Vite should probably leave transforming json if it has assert.

bluwy avatar May 19 '22 17:05 bluwy

Hey @bluwy , Thanks for your quick response! I was able to replicate the issue you described with Vite returning JS. I also believe I found another issue with parsing import assertions when using Server Side Rendering with Vite. Here's the stack trace of the error: 3:34:13 PM [vite] Error when evaluating SSR module /src/entry-server.jsx: Error: Parse failure: Unexpected token (3:40) Contents of line 3: import packageJson from "/package.json" assert { type: "json" }; at ssrTransform (/Users/jhenris/yext-sites-repos/viteSSRReact/playground/ssr-react/node_modules/vite/dist/node/chunks/dep-59dc6e00.js:54480:15) at doTransform (/Users/jhenris/yext-sites-repos/viteSSRReact/playground/ssr-react/node_modules/vite/dist/node/chunks/dep-59dc6e00.js:55879:17)

In order to replicate, I forked the Vite repo here and added an import assertion to the react-ssr playground example. If you clone the repo I linked, cd into the playground/ssr-react directory, then npm run dev and try to open the webpage the error should occur. Please let me know if I can provide any more information that would be helpful when debugging.

jimboHenris avatar May 19 '22 19:05 jimboHenris

Been thinking about this, and I wonder what it really takes to "support import assertions".

On one hand, Vite can preserve the import assertions as is, and return the correct MIME type for it. But that only works in Chrome in dev mode only. In builds, Rollup doesn't support it yet as Acorn (the parser it uses) only implements stage 4 specs.

On the other hand, Vite can "support" it too by stripping off any usage of import assertions as the behaviour would essentially be the same when browser & nodejs support become widespread.

I'm leaning towards the second option for now, but I also wonder why one would reach out to import assertions in the first place if they know what Vite does under the hood.

bluwy avatar May 23 '22 05:05 bluwy

I also wonder why one would reach out to import assertions in the first place if they know what Vite does under the hood

Do you mean why would someone use import assertions if they're using Vite?

The actual use case here is importing a library which uses import assertions into your Vite project.

And import assertions were a security patch added to Node 17 and back-ported to Node 16.

mkilpatrick avatar May 23 '22 14:05 mkilpatrick

I just tried a dependency that uses import assertions and it worked for me, provided that it's being optimized by esbuild. If it's excluded from optimization via optimizeDeps.exclude (e.g. a linked dependency), then it would not work as Vite would process the import assertion than esbuild.

I'm not sure if this is an issue, but maybe it would make sense for Vite to strip it out then if there aren't consequences.

bluwy avatar May 24 '22 05:05 bluwy

My use case is actually loading config files on server start. Instead of a complicated and brittle workaround using fs path and import.meta.url, it is preferable to use import assertions for this.

aMediocreDad avatar Jun 03 '22 15:06 aMediocreDad

Any chance of this making it into 3.0?

mkilpatrick avatar Jul 05 '22 16:07 mkilpatrick

I submitted https://github.com/vitejs/vite/pull/8937 to apply the strip approach, which essentially removes the assert { type: "json" } part so it'll use Vite's default JSON handling. I've added notes in the PR of why I didn't resort to native import assertion, but I'm open to discuss it.

bluwy avatar Jul 05 '22 17:07 bluwy

Any news when this fix will be merged? I'm still getting there error. Screenshot 2022-07-19 at 12 40 50

johannesronaldsson avatar Jul 19 '22 12:07 johannesronaldsson

It was fixed when Vite beta was prebundling in build too, but now it's not. You can bring it back by specifying optimizeDeps.disabled: false but note that it's experimental though. Re-opening as this is still an issue in Vite 3 stable now.

bluwy avatar Jul 19 '22 12:07 bluwy

This doesn't seem to work anymore either. So for now I will grab back to older versions until this is working.

{ optimizeDeps.disabled: false }

johannesronaldsson avatar Jul 26 '22 13:07 johannesronaldsson

I found below code could work for me. You can use dynamic import for json file.

import("xxx/test.json", { 
  assert: {
    type: "json"
  }
})

m430 avatar Aug 05 '22 01:08 m430

I'm looking to import css as a CSSStyleSheet() using assert imports. Theres rollup-plugin-import-assert that enables assert for css. This seems to conflict with the other preconfigured css plugins though. They're all trying to modify **/*.css files and enforcing the plugin order doesn't help.

If the import-assert plugin is added post than it injects some vite js code instead of the CSS text so the CSSStyleSheet has 0 rules:

const sheet = new CSSStyleSheet();sheet.replaceSync(`import { updateStyle as __vite__updateStyle, removeStyle as __vite__removeStyle } from "/@vite/client"
...CSS...
import.meta.hot.prune(() => __vite__removeStyle(__vite__id))`);export default sheet;

If the import-assert plugin is added pre than it converts the plugins transform code into just a string:

import styles from './styles.css`;
console.log(typeof styles);  // "string"
console.log(styles); // "const sheet = new CSSStyleSheet();sheet.replaceSync(...);export default sheet;"

Is there a way to get css assert imports working for the time being until Vite officially supports assert?

joezappie avatar Aug 14 '22 01:08 joezappie

Importing json files does not work for me :/ getting this error Failed to load module script: Expected a JavaScript module script but the server responded with a MIME type of "application/json". Strict MIME type checking is enforced for module scripts per HTML spec. this is my vite.config.ts

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

// https://vitejs.dev/config/
export default defineConfig({
    plugins: [
        react({
            babel: {
                plugins: ['@babel/plugin-syntax-import-assertions'],
            },
        }),
    ],
    base: './',
    optimizeDeps: {
        disabled: false,
    },
});

EDIT: I am also getting this error. The path is './quiz_data/test_quiz.json' which i believe is the correct format

70 |    console.log(path);
71 |    const res = await import(`./${path}`, {
   |                             ^
72 |      assert: {
73 |        type: "json"
The above dynamic import cannot be analyzed by Vite.
See https://github.com/rollup/plugins/tree/master/packages/dynamic-import-vars#limitations for supported dynamic import formats. If this is intended to be left as-is, you can use the /* @vite-ignore */ comment inside the import() call to suppress this warning.

wyvernbw avatar Sep 10 '22 13:09 wyvernbw

It looks like import assertions inside Vue single file components are not yet available, either? I am getting:

[@vue/compiler-sfc] This experimental syntax requires enabling the parser plugin: "importAssertions".

mitar avatar Oct 09 '22 18:10 mitar

It's working in vite dev, but not in vite build. Is there any indication when this will be fixed?

johannesronaldsson avatar Oct 10 '22 15:10 johannesronaldsson

Hm, for me it does not work in vite dev either, I have all the latest stable versions. Do I have to bump something to some dev version?

mitar avatar Oct 10 '22 16:10 mitar

It works with vite.config.ts

piotr-cz avatar Oct 20 '22 18:10 piotr-cz

@wyvernbw Maybe you're hitting this issue? https://github.com/vitejs/vite/issues/10669

It seems that if you import a .json file from a file that is in turn imported using an alias, the import fails with the message you showed.

IanVS avatar Oct 27 '22 20:10 IanVS