- calculate maths e.g. tax rates
- talk to other APIs
- render HTML
- minify and bundle assets
- render SVGs
- parse and process CSVs
- const
- number
- string
- arrays
- UInt8Array
- sets
- maps
- symbols
- generator functions
- URLs
- fetch
- Request
- Response
- JSON doesn't allow richer data types: dates, colors, paths, sets,
- JSON doesn't allow comments
- JSON imports are awkward
- JSON is awkward to write manually
- ES Modules imports are fantastic
- ES Modules allows richer data types
- ES Modules allows comments
- Leverage existing modules
- Lever tooling such as TypeScript and JSDoc
- Great for design tokens
- Leverage existing tooling for minification, etc
- Works in modern browsers
- Take advantage of HTTP caching at the edge
- Can export members with a name
- Exports are JSON objects, must strictly be JSON syntax (double quotes)
- Only
const
is supported, no variables - Must have semicolons at end of statements
- Can use JSDoc as annotations
- Can do dynamic imports:
import("some url")
- Can import CSS?
/**
* Pi to 8 decimal places
*/
export const pi = 3.14159265;
export const dateFormat = "YYYY/MM/DD";
export const isEnabled = true;
export const flavors = ["vanilla", "chocolate", "caramel", "raspberry"];
export const foo = null;
- Swift
- Cloudflare Workers with caching of imported modules
- Go
- Elixir
- Python
let data = …
let module = try? ESModule.parse(data)
module.exports.names // ["pi", "dateFormat", "isEnabled", "flavors", "foo"]
module["pi"] // 3.14159265
module.pi // Dynamic member lookup
ESModule.loadAndEvaluate(URL("some url"))
.sink { exports in … }
const data = await importData(someURL)
- Set, Map
- Import from URL
- Export from other modules
- Maybe functions or generator functions
- Can pass custom functions that can be imported and used
export const imageURL = new URL("./image.png", import.meta.url)
import { Set } from "es2015";
export const flavors = new Set(["vanilla", "chocolate", "caramel", "raspberry"]);
import someDataset from "https://cooldatasets.org/foo.json";
export * from "otherModule";
export function* sequence() {
yield 1;
yield 2;
yield 3;
yield 5;
yield* otherGenerator;
}
export const home = new URL('/');
export const dashboard = new URL('/dashboard');
export const account = new URL('/account');
import { rgb } from 'css-values';
export const primaryColor = rgb(45, 91, 12);
export const secondaryColor = rgb(12, 34, 56);
/some-design-token.mjs.css
:root {
--primaryColor: rgb(45, 91, 12);
--secondaryColor: rgb(12, 34, 56);
}
export { default as plus } from "image/svg+xml/8f43b18ca…";
export { default as profile } from "image/svg+xml/372db66…";
export { default as edit } from "image/svg+xml/1aeb067…";
- Show preview inline of the images with VSCode extension
new URL(import.meta.url).searchParams.get('color');
const input = new URL(import.meta.url).searchParams;
const income = searchParams.get('income');
export const gst = income * 0.10;
export const incomeTax = income * 0.37;
export default crypto.subtle.digest('SHA-256', import.meta.params['content']);
export
let decoder = JSONDecoder()
dataProvider
.tryMap { parseModule($0) }
.flatMap { module in
MergeMany([
Just(module["profile"])
.decode(type: Profile.self, using: decoder),
Just(module["preferences"])
.decode(type: Preferences.self, using: decoder),
Just(module["pi"])
.decode(type: Float.self, using: decoder)
])
}