Did you know you can import JSON and CSS files just like you import JavaScript Modules? Thanks to Import Assertions, it’s as easy as this:
Building upon "Import Assertions" we recently saw JSON Modules land in V8/Chromium 91:
“`
import json from './foo.json' assert { type: 'json' };
“`In Chromium 93 the same thing for CSS lands (“CSS Modules”):
“`
import styles from "./styles.css" assert { type: "css" };
“` https://t.co/Bpy60PwR3a— Bramus (@bramus) July 30, 2021
It’s a regular import
statement with an extra assert { "type": … }
part added to it. That way you can tell the browser to treat and parse the referenced file to be of a certain type. Once imported you can use the contents further down in your JavaScript code, just like you do with regular ES Module imports.
{
"appName": "My App"
}
import configData from './config-data.json' assert { type: 'json' };
console.log(configData.appName); // "MyApp"
~
Import Assertions is currently at Stage-3, and is expected to become part of the upcoming ES2022.
💁♂️ Stage-3?
The Technical Committee which is concerned with the standardization of ECMAScript (i.e. TC39) has a 5 stage process in place, ranging from stage-0 to stage-4, by which it develops a new language feature.
Stage-3 is the Candidate Stage where the feature is considered complete and only critical changes will happen based on implementation experience. If all goes well the proposal will advance to Stage 4 without any changes, after which it will to become part of the ECMAScript Specification.
Import Assertions are supported in Chromium 91+. For browsers that don’t support it, you can use the es-module-shims
polyfill which provides this functionality (and more nice tings)
~
In the most recent episode of CodePen Radio, just a little after the 10-minute mark, you can see host Chris Coyier demonstrate this (along with importing packages directly from Skypack):
The CSS example Chris shows there uses Lit. In a non-framework environment, add the imported styles using Constructed Stylesheets:
import styles from "./styles.css" assert { type: "css" };
document.adoptedStyleSheets = [...document.adoptedStyleSheets, styles];
💡 Do note that adoptedStyleSheets
is only supported in Chromium browsers at the time of writing (CanIUse).
~
If you’re wondering why we can’t simply import those files directly, without the assertions, Axel Rauschmayer has the answer:
Browsers never look at filename extensions, they look at content types. And servers are responsible for providing content types for files.
[…]
With an external server, things are even more risky: If it sends the file with the content type text/javascript, it could execute code inside our app.
~
And oh, Import Assertions can be used with dynamic import()
. Pass in the assertion as the second parameter:
const configData = await import('./config-data.json', {
assert: { type: 'json' },
});
console.log(configData.appName); // "MyApp"
~
A future without a Build System is lurking around the corner, especially when you combine these Import Assertions with a follow-up Evaluator Attributes proposal and Import Maps 🤩
~
~
🔥 Like what you see? Want to stay in the loop? Here's how: