Skip to content

Commit

Permalink
feat: support import rewriting in index.html
Browse files Browse the repository at this point in the history
  • Loading branch information
yyx990803 committed Apr 21, 2020
1 parent a307eeb commit 4ed433a
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 9 deletions.
12 changes: 3 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,12 @@ Create the following files:

```html
<div id="app"></div>
<script type="module" src="/main.js"></script>
```

**main.js**

```js
<script type="module">
import { createApp } from 'vue'
import Comp from './Comp.vue'
createApp(Comp).mount('#app')
</script>
```

**Comp.vue**
Expand Down Expand Up @@ -54,9 +50,7 @@ Go to `http://localhost:3000`, edit the `.vue` file to see changes hot-updated i

- The server intercepts requests to `*.vue` files, compiles them on the fly, and sends them back as JavaScript.

- Imports to npm packages inside `.js` files are re-written on the fly to point to locally installed files (only packages that provide ES module builds will work - `"module"` field will be used if present in `package.json`). There is also plans to integrate with [Snowpack](https://www.snowpack.dev/) to leverage its `web_modules`.

Note this rewrite currently doesn't work in `index.html`, but can probably be made to.
- Imports to npm packages inside `.js` files (and in `<script>` of `index.html`) are re-written on the fly to point to locally installed files (only packages that provide ES module builds will work - `"module"` field will be used if present in `package.json`). There is also plans to integrate with [Snowpack](https://www.snowpack.dev/) to leverage its `web_modules`.

- For libraries that provide ES modules builds that work in browsers, you can also directly import them from a CDN.

Expand Down
30 changes: 30 additions & 0 deletions src/server/middlewares/modules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,28 @@ import path from 'path'
import { promises as fs, createReadStream } from 'fs'
import resolve from 'resolve-from'
import { rewrite } from '../moduleRewriter'
import { Readable } from 'stream'

const idToFileMap = new Map()
const fileToIdMap = new Map()

export const moduleResolverMiddleware: Middleware = ({ cwd, app }) => {
// rewrite <script> imports in index.html
app.use(async (ctx, next) => {
await next()
if (ctx.url === '/index.html') {
const html = ctx.body.pipe ? await readStream(ctx.body) : String(ctx.body)
ctx.body = html.replace(
/(<script\b[^>]*>)([\s\S]*?)<\/script>/gm,
(_, openTag, script) => {
return `${openTag}${rewrite(script)}</script>`
}
)
console.log(ctx.body)
}
})

// rewrite imports in all js files to /__modules/:id
app.use(async (ctx, next) => {
if (!ctx.path.endsWith('.js')) {
return next()
Expand All @@ -26,6 +43,7 @@ export const moduleResolverMiddleware: Middleware = ({ cwd, app }) => {
}
})

// handle /__modules/:id requests
const moduleRE = /^\/__modules\//
app.use(async (ctx, next) => {
if (!moduleRE.test(ctx.path)) {
Expand Down Expand Up @@ -94,3 +112,15 @@ export const moduleResolverMiddleware: Middleware = ({ cwd, app }) => {
}
})
}

async function readStream(stream: Readable): Promise<string> {
return new Promise((resolve, reject) => {
let res = ''
stream
.on('data', (chunk) => (res += chunk))
.on('error', reject)
.on('end', () => {
resolve(res)
})
})
}

0 comments on commit 4ed433a

Please sign in to comment.