rollup-plugin-import-maps v0.2.4
rollup-plugin-import-maps
A plugin to resolve ECMAScript module bare/url import specifiers at build-time for browsers which don't support import-maps, mostly based on WICG's import-maps reference implementation.
This plugin plays a role of polyfill for browsers but is used at build-time rather than at run-time. If some day (maybe in 2023) all major browsers support import-maps then this plugin can be retired.
Contents:
Install
npm install --save-dev rollup-plugin-import-mapsUsage
Basic Usage
edit rollup.config.js, import and use the plugin
import { importMapsPlugin } from 'rollup-plugin-import-maps';
// import { readFileSync } from 'fs';
export default {
input: './src/index.js',
plugins: [
importMapsPlugin({
srcPath: './index.importmap',
// srcText: readFileSync('./index.importmap', { encoding: 'utf8' }),
// srcObject: JSON.parse(readFileSync('./index.importmap', { encoding: 'utf8' })),
}),
],
output: [
{
file: './dist/index.js',
format: 'es'
}
]
};Plugin Options
srcPath:string optionalfile path to importmap
srcText:string optionalplain text of importmap
srcObject:Object optionalparsed object of importmap
Note: One of
srcObject,srcText,srcPathshould be specified, if multiple of them specified, then precedence order is: srcObject, srcText, srcPath.baseDir: string defaultprocess.cwd()baseDir to calculate scope paths in order to match scopes defined in importmap
transformingReport:string defaultundefinedset a file path to save transforming report as a JSON file, will output to Console if value set to
"-"noTransforming:boolean defaultfalseif value set to
true, then the plugin will mark specifiers defined in importmap as external, and won't transform those specifiers. useful if you want to build for browsers which already support import-maps and "set external list" with importmap.exclude:string|RegExp|Function defaultundefinedskip bare/url specifiers from resolving / transforming according to importmap.
e.g.
.json,.wasm,.css,/\.(json|wasm|css)$/,(source, importer)=> /\.(json|wasm|css)$/.test(source)
Caveats
This plugin doesn't yet support transforming module specifiers defined in data url. example data url:
import {foo, bar} from "data:application/javascript;charset=utf-8,import%20%7Bdefault%20as%20foo%7D%20from%20'foo'%3B%0Aexport%20%7Bfoo%7D%3B%0Aexport%20%7Bdefault%20as%20bar%7D%20from%20'bar'%3B";which can be decoded as
import {default as foo} from 'foo'; export {foo}; export {default as bar} from 'bar';When tansforming specifiers in dynamic imports, only string literal can be transformed. example specifiers:
import('foo/locales/en/messages.js') // Yes import("foo/locales/en/messages.js") // Yes let lang = 'en'; import('foo/locales/'+lang+'/messages.js') // No let modulePath = 'foo/locales/en/messages.js' import(modulePath) // No import(`foo/locales/en/messages.js`) // No
Use Cases
Bare Specifiers Transforming
importmap
{
"imports": {
"three": "/node_modules/three/build/three.module.js",
"three/": "/node_modules/three/",
"underscore": "data:application/javascript;charset=utf-8,export%20default%20window._%3B",
"~/": "//mysite.com/packages/myapp/"
}
}input code
import * as THREE from 'three';
import GLTFLoader from 'three/examples/jsm/loaders/GLTFLoader.js';
import _ from 'underscore';
import '~/polyfills/navigator.userAgentData.js';
console.log(THREE, GLTFLoader, _);output code
import * as THREE from '/node_modules/three/build/three.module.js';
import GLTFLoader from '/node_modules/three/examples/jsm/loaders/GLTFLoader.js';
import _ from 'data:application/javascript;charset=utf-8,export%20default%20window._%3B';
import '//mysite.com/packages/myapp/polyfills/navigator.userAgentData.js';
console.log(THREE, GLTFLoader, _);URL Specifiers Transforming
importmap
{
"imports": {
"https://unpkg.com/three@0.141.0/build/three.module.js": "/node_modules/three/build/three.module.js",
"node-modules:/": "/node_modules/",
"data:application/javascript;charset=utf-8,export%20default%20window._%3B": "/underscore/underscore-esm-min.js",
"app-home:/": "//mysite.com/packages/myapp/"
}
}input code
import * as THREE from 'https://unpkg.com/three@0.141.0/build/three.module.js';
import GLTFLoader from 'node-modules:/three/examples/jsm/loaders/GLTFLoader.js';
import _ from 'data:application/javascript;charset=utf-8,export%20default%20window._%3B';
import 'app-home:/polyfills/navigator.userAgentData.js';
console.log(THREE, GLTFLoader, _);output code
import * as THREE from '/node_modules/three/build/three.module.js';
import GLTFLoader from '/node_modules/three/examples/jsm/loaders/GLTFLoader.js';
import _ from '/underscore/underscore-esm-min.js';
import '//mysite.com/packages/myapp/polyfills/navigator.userAgentData.js';
console.log(THREE, GLTFLoader, _);No Transforming
You may use rollup to build two distributions, for browsers with or without import-maps support, and load corresponding distribution conditionally. e.g.
// rollup.config.js
export default [
{
input: './src/index.js',
plugins: [
importMapsPlugin({
srcPath: './index.importmap',
transformingReport: '-',
}),
],
output: [
{
file: './dist/index.js',
format: 'es'
}
]
},
{
input: './src/index.js',
plugins: [
importMapsPlugin({
srcPath: './index.importmap',
noTransforming: true,
}),
],
output: [
{
file: './dist/index-experimental.js',
format: 'es'
}
]
}
];<script type="importmap">
put content of ./index.importmap here
</script>
<script type="module">
if (HTMLScriptElement.supports && HTMLScriptElement.supports('importmap')) {
console.log('Your browser supports import maps.');
import('/dist/index-experimental.js');
}else{
console.log('Your browser doesn\'t support import maps.');
import('/dist/index.js');
}
</script>Related Efforts
- import-maps - Reference implementation playground for import maps proposal
Maintainers
License
Other licenses of dependencies
- import-maps: W3C Software and Document License and W3C CLA