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
Plan for import assertions and non-JS module types #3799
Comments
If there is an acorn plugin for import assertions, then we can include this in the Rollup build even if it is not part of acorn core. But I did not see one, so maybe this requires some community effort to drive forward. |
Yeah, there doesn't appear to be an acorn plugin yet. After that exists though, what would be the plan for Rollup support of the module types that the web platform supports? Would these be built-in? |
There are basically two main cases for RollupJS - handling these module types for externals and handling these module types for RollupJS inlining. For all types of modules, when they are externals, the import statement just stays in the chunk just the same. For the inlining cases:
It's worth noting that all of the above are already possible today - the syntax is if anything a restriction in forcing RolllupJS behaviour for inlining or errors at runtime. Would be good to hear your thoughts on CSS chunking further. |
It might be better to use |
The story is to transform them to JS and do explicit
The semantics are all wrong though. We need to be able to access each stylesheet individually, and importantly not apply them to the main document. The non-standard CSS imports do not support that. |
Do you mean having the stylesheet strings inline in the JS to do this? That sounds like it could work just fine actually! Would it be worth getting a RollupJS plugin going that can do this work? @tivac has previously done a lot of work in this space as well. We don't yet have any official style / css plugin AFAICT, and there's nothing to stop this sort of workflow from becoming a standard one already now even without import assertions. |
If it's just a straight transform of CSS to JS string as the default export that seems really trivial. Feels like you would still want some sort of .css file outputting and bundling though for SSR/progressive enhancement workflows? |
Basically. The transform wouldn't export the CSS text though, just a stylesheet. p {
color: red;
} would transform to: const stylesheet = new CSSStyleSheet();
stylesheet.replaceSync(`p {
color: red;
}`);
export default stylesheet; |
FYI, I just filed: w3c/csswg-drafts#5629 to propose multiple stylesheets per .css file, which would address the bundling question even without Web bundles. |
an acron plugin seems to be available for import assertions. In order to support somehow load this acorn plugin and it should work? or are there more steps? 🤔 |
@daKmoR just the import assertion plugin should be necessary. We could then possibly look at supporting JSON imports by default in RollupJS further perhaps just based on file extension. |
I am running into two issues as I try to use import assertions with dynamic imports:
TypeError: Cannot read property 'bind' of undefined
at ImportExpression.bind (file:///D:/myproj/node_modules/.pnpm/rollup@2.56.2/node_modules/rollup/dist/es/shared/rollup.js:2425:23) There is also a plugin (https://github.com/calebdwilliams/rollup-plugin-import-assert) for this but that tries to interpret the import path even for dynamic and import the file while bundling (all I want to achieve is for the dynamic import statement to be left alone)! |
@dasa I don't think |
I'm thinking the another thing is also that the spec disallows named imports and expects a syntax error being thrown when import { foo } from './foo.json' assert { type: 'json' } currently the json plugin is required to import json and it allows named imports, when plain "objects" are being imported, and a property with the same name as the named import exists, otherwise it throws (also throws for any other valid json: I would assume that the syntax would be disallowed when using assertion syntax, and I think it should probably be retired altogether, as named imports are not allowed anywhere [for json] (as far as I know), even in |
@dnalborczyk I'm only referring to if it's embedded, then how it's embedded. According to this blog post, surprisingly it can be faster in some cases to embed it as a string and use |
ah, ok, gotcha, that makes sense. I don't know where my mind has been 😄 for some reason I thought you suggested omitting inlining altogether. |
I recently spent some time to add support for import assertions and CSS/JSON modules to our application at work, I figured I'd write down the experience in case anybody is looking to do the same, and hopefully it'll help rollup in supporting them better. I've put it in a separate gist, because it got a bit long and didnt want to pollute this issue too much. https://gist.github.com/thepassle/d46a7cabf2dd15ba3bb43397430e182f Most notably and relevant to this thread is that:
import styles from './styles.css' assert { type: 'css' }; Always becomes: import styles from './styles.css'; See the gist for more info. Hopefully it's helpful. |
Why not just say - as it is currently - rollup supports only js out of the box and change the resolveID hook to get an extra argument with the contents of assertion this would allow the following in plugins: Assume style.css contains a class "red". import {red} from './styles.css' assert { type: 'css', module: true }; The proposal is not limited to a type field (that is only what other proposals currently use / need) The resolveId hook could get the folowing type type resolveId = (source: string, importer: string | undefined, options: {isEntry: boolean, custom?: {[plugin: string]: any}, assertions: Record<string, any>) => string | false | null | {id: string, external?: boolean | "relative" | "absolute", moduleSideEffects?: boolean | "no-treeshake" | null, syntheticNamedExports?: boolean | string | null, meta?: {[plugin: string]: any} | null} this should be a small but powerfull change in the syntax. A lot of plugins could change there syntax to a specific assertion. For example the comlink-plugin you could use import worker from './myworker.js' assert { type: 'comlink' }; For rollup we don't need the |
I think its a bad idea to have to adhere to custom build-time conventions/syntax to support native browser functionality. Plugins will definitely start to abuse the assertion, but I dont think it should be the default behavior. |
A browser understands the following and I hope rollup too one day (for now I have a fat custom plugin to allow that): import style from 'https://cdn.com/styles.css' assert { type: 'css' }; In that scenario code fetching the ressource still have to check the content type received from server is "text/css" as a browser would. |
To match browser behavior you absolutely do need the assertion. If you assume standard mime-types and someone writes: import * as foo from 'foo.js' assert {type: 'json'}; Then Rollup should fail, since that's what the browser would do. |
import {red} from './styles.css' assert { type: 'css', module: true }; This would be bad to support for two reasons:
|
I agree that my idea was bad :D. |
the same is currently true for |
Initial support in #4646 |
This issue has been resolved via #4646 as part of rollup@3.0.0-8. Note that this is a pre-release, so to test it, you need to install Rollup via |
This issue has been resolved via #4646 as part of rollup@3.0.0. You can test it via |
Feature Use Case
Importing JSON, CSS, and HTML according to upcoming JavaScript and HTML standards.
Feature Proposal
Import assertions are a Stage 3 TC39 proposal to allow source code to assert that an import has a specific type (among other possible assertions): https://github.com/tc39/proposal-import-assertions
Assertions are being added to unblock the JSON, CSS, and HTML modules proposals which allow importing those file type as JavaScript modules.
This means that we'll be able to import JSON, CSS and HTML into JavaScript natively, and ideally in bundlers without any specific loaders (or perhaps a "web standard loader" that implements all web-native module types?):
I filed an issue on Acorn for import assertion support.
The JSON and CSS proposals are furthest along, with implementations in Chromium behind flags.
The text was updated successfully, but these errors were encountered: