Skip to content

A Koa middleware module that can rewrite import specifiers for JavaScript modules based on the reference/presence of an importmap in the HTML document originating the request.

Notifications You must be signed in to change notification settings

PolymerLabs/koa-importmap

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 

Repository files navigation

koa-importmap

A Koa middleware module that can rewrite import specifiers for JavaScript modules based on the reference/presence of an importmap in the HTML document originating the request.

The middleware persists a reference to the importmap to requests for all transitive imports in the graph by use of a query parameter which is appended and consumed by the middleware.

Usage

Here's a quick Koa server which serves static files and rewrites import specifiers based on import maps.

./server.js

const app = new require('koa')
const root = __dirname
app.use(require('koa-importmap')(root))
app.use(require('koa-static')(root))
app.listen(3000)

Example

Consider a project folder with the following contents.

importmap.json
index.html
node_modules/mod-a/index.js
node_modules/mod-a/node_modules/mod-b/index.js
node_modules/mod-b/index.js

The importmap.json file contains both "imports" and "scopes" to demonstrate the behavior of each:

{
  "imports": {
    "mod-a": "/node_modules/mod-a/index.js",
    "mod-b": "/node_modules/mod-b/index.js"
  },
  "scopes": {
    "/node_modules/mod-a/": {
      "mod-b": "/node_modules/mod-a/node_modules/mod-b/index.js"
    }
  }
}

The JavaScript modules are simple. Top-level mod-a simply re-exports the default export of its nested mod-b. The nested mod-b exports a function that single-quotes its string argument. Top-level mod-b exports a function the double-quotes its string argument:

// node_modules/mod-a/index.js
import b from 'mod-b'
export default b
// node_modules/mod-a/node_modules/mod-b/index.js
export default (text) => `'${text}'`
// node_modules/mod-b/index.js
export default (text) => `"${text}"`

The main HTML file ./index.html references the import map and contains module script which uses bare name specifiers.

<script type="importmap" src="importmap.json"></script>

<script type="module">
  import a from 'mod-a'
  import b from 'mod-b'
  console.log(a('singlequoted'))
  console.log(b('doublequoted'))
</script>

The expected console output when loading /index.html in a browser which supports import maps natively would be:

'singlequoted'
"doublequoted"

When requested and processed through the koa-importmap middleware, the import map is fetched/cached or read-from-cache, processed and HTML is rewritten:

<script type="module">
  import a from '/node_modules/mod-a/index.js?koa-importmap=6a83b08a'
  import b from '/node_modules/mod-b/index.js?koa-importmap=6a83b08a'
  console.log(a('singlequoted'))
  console.log(b('doublequoted'))
</script>

JavaScript requested with the koa-importmap=6a83b08a is then processed using the cached import map referenced and is rewritten as well. For example, request for /node_modules/mod-a/index.js?koa-importmap=6a83b08a returns:

import b from './node_modules/mod-b/index.js?koa-importmap=6a83b08a'
export default b

Gotchas

Initially, this middleware is intended primarily for use in a development context and has shortcomings in production scenarios. It can be quite expensive in terms of memory and processing to parse every HTML and JavaScript document returned through the middleware.

Additionally, the koa-importmap query parameter is a digest of the content of a processed import map. The digest is used as a key for the default in-memory LRU cache that stores the parsed importmap. If this middleware was to be used in a production environment running multiple instances of the server, it would need to either use a shared cache or ensure that requests were bound to same server.

About

A Koa middleware module that can rewrite import specifiers for JavaScript modules based on the reference/presence of an importmap in the HTML document originating the request.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published