https://github.com/substrate-system/esm
Feature detection for modules
https://github.com/substrate-system/esm
esm progressive-enhancement
Last synced: 10 months ago
JSON representation
Feature detection for modules
- Host: GitHub
- URL: https://github.com/substrate-system/esm
- Owner: substrate-system
- License: other
- Created: 2025-05-13T19:09:34.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2025-07-27T00:18:47.000Z (11 months ago)
- Last Synced: 2025-08-08T22:50:37.881Z (11 months ago)
- Topics: esm, progressive-enhancement
- Language: TypeScript
- Homepage: https://substrate-system.github.io/esm/
- Size: 66.4 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# esm
[](https://github.com/substrate-system/esm/actions/workflows/gh-pages.yml)
[](https://semver.org/)
[](README.md)
[](README.md)
[](./CHANGELOG.md)
[](https://bundlephobia.com/package/@substrate-system/esm)
[](https://packagephobia.com/result?p=@substrate-system/esm)
[](package.json)
[](LICENSE)
Feature detection for modules (ESM) + dynamic imports.
Contents
- [Install](#install)
- [API](#api)
* [`ES Modules`](#es-modules)
* [`importMap`](#importmap)
* [`umd(...files:string[])`](#umdfilesstring)
- [Use](#use)
* [ESM + Bundler](#esm--bundler)
* [Common JS](#common-js)
* [pre-built JS](#pre-built-js)
* [CSP](#csp)
- [Example](#example)
- [Build](#build)
* [Application code](#application-code)
* [Dependencies](#dependencies)
- [develop](#develop)
## Install
```sh
npm i -S @substrate-system/esm
```
## API
### `ES Modules`
Dynamic imports?
```ts
function esm ():boolean
```
### `importMap`
Is `importmap` supported?
```ts
function importMap ():boolean
```
### `umd(...files:string[])`
Create script tags in the document, and wait for them to load.
```ts
async function umd (...files:string[]):Promise
```
## Use
### ESM + Bundler
```js
import {
importMap,
esm,
umd
} from '@substrate-system/esm'
```
### Common JS
```js
require('@substrate-system/esm')
```
### pre-built JS
Copy the minified files to a location that is accessible to your web server,
then link to them in HTML.
#### copy
```sh
cp ./node_modules/@substrate-system/esm/dist/index.min.js ./public/esm.min.js
```
#### HTML
```html
```
### CSP
You will need to add `unsafe-eval` to your CSP.
```
script-src 'self' 'unsafe-eval';
```
## Example
> [!NOTE]
> This would be for a script built with a "global name" of `test`,
> e.g. `--global-name=test`. The name you access on `globalThis` depends on your
> build process.
```js
import { importMap, esm, umd } from '@substrate-system/esm'
const importMapOk = importMap()
const dynamic = esm()
if (dynamic) {
const { hello } = await import('/test.js')
hello()
} else {
// load a UMD script
await umd('/test.umd.js')
// now we have a global variable
hello = globalThis.test.hello
hello()
}
```
## Build
If you need to support both newer platforms, and also platforms without
ES modules, then build a UMD version in addition to building modules.
### Application code
> [!NOTE]
> The argument `--external:"./test.js"`
In your top-level module, build it with the relevant dependencies
excluded, not bundled.
```sh
esbuild ./test/index.ts --external:"./test.js" --format=iife --bundle --keep-names > public/bundle.js
```
### Dependencies
> [!NOTE]
> The `--global-name` argument
Given the example above, you would want to build your dependency module
as an `IIFE` function, attached to `window` at `.test`, in addition to building
it as a normal ESM module.
```sh
esbuild ./src/test.ts --global-name=test --format=iife --bundle --keep-names > public/test.umd.js
```
## develop
Three commands:
Build the file, and start a server:
```sh
npm start
```
Build the files in `iife` format, and start a server:
```sh
npm run start:iife
```
Build in `2016` compatibility mode:
```sh
npm run start:2016
```
Development is a little bit janky because there is not an easy way to start
an old version of a browser.
That's why, in the iife and `2016` versions, we do an extra check, besides
looking at `esm()`.