Skip to content

Commit

Permalink
feat: build support for data uri import
Browse files Browse the repository at this point in the history
  • Loading branch information
yyx990803 committed Jan 8, 2021
1 parent 79e964e commit 4fd0b86
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 3 deletions.
16 changes: 16 additions & 0 deletions packages/playground/data-uri/__tests__/data-uri.spec.ts
@@ -0,0 +1,16 @@
import { isBuild, findAssetFile } from '../../testUtils'

test('plain', async () => {
expect(await page.textContent('.plain')).toBe('hi')
})

test('base64', async () => {
expect(await page.textContent('.base64')).toBe('hi')
})

if (isBuild) {
test('should compile away the import for build', async () => {
const file = findAssetFile('index')
expect(file).not.toMatch('import')
})
}
10 changes: 10 additions & 0 deletions packages/playground/data-uri/index.html
@@ -0,0 +1,10 @@
<div class="plain"></div>
<div class="base64"></div>

<script type="module">
import msg from "data:text/javascript, export default 'hi'"
document.querySelector('.plain').textContent = msg

import base64Msg from 'data:text/javascript;base64, ZXhwb3J0IGRlZmF1bHQgJ2hpJw=='
document.querySelector('.base64').textContent = base64Msg
</script>
10 changes: 10 additions & 0 deletions packages/playground/data-uri/package.json
@@ -0,0 +1,10 @@
{
"name": "test-data-uri",
"private": true,
"version": "0.0.0",
"scripts": {
"dev": "vite",
"build": "vite build",
"debug": "node --inspect-brk ../../vite/bin/vite"
}
}
56 changes: 56 additions & 0 deletions packages/vite/src/node/plugins/dataUri.ts
@@ -0,0 +1,56 @@
// This is based on @rollup/plugin-data-uri
// MIT Licensed https://github.com/rollup/plugins/blob/master/LICENSE
// ref https://github.com/vitejs/vite/issues/1428#issuecomment-757033808
import { Plugin } from '../plugin'
import { URL } from 'url'

const dataUriRE = /^([^/]+\/[^;,]+)(;base64)?,([\s\S]*)$/

const dataUriPrefix = `/@data-uri/`

export function dataURIPlugin(): Plugin {
const resolved: {
[key: string]: string
} = {}

return {
name: 'vite:data-uri',
resolveId(id) {
if (!dataUriRE.test(id)) {
return null
}

const uri = new URL(id)
if (uri.protocol !== 'data:') {
return null
}

const match = uri.pathname.match(dataUriRE)
if (!match) {
return null
}

const [, mime, format, data] = match
if (mime !== 'text/javascript') {
throw new Error(
`data URI with non-JavaScript mime type is not supported.`
)
}

// decode data
const base64 = format && /base64/i.test(format.substring(1))
const content = base64
? Buffer.from(data, 'base64').toString('utf-8')
: data
resolved[id] = content
return dataUriPrefix + id
},

load(id) {
if (id.startsWith(dataUriPrefix)) {
id = id.slice(dataUriPrefix.length)
return resolved[id] || null
}
}
}
}
2 changes: 2 additions & 0 deletions packages/vite/src/node/plugins/index.ts
Expand Up @@ -12,6 +12,7 @@ import { htmlPlugin } from './html'
import { wasmPlugin } from './wasm'
import { webWorkerPlugin } from './worker'
import { dynamicImportPolyfillPlugin } from './dynamicImportPolyfill'
import { dataURIPlugin } from './dataUri'

export async function resolvePlugins(
config: ResolvedConfig,
Expand Down Expand Up @@ -44,6 +45,7 @@ export async function resolvePlugins(
preferConst: true,
namedExports: true
}),
isBuild ? dataURIPlugin() : null,
wasmPlugin(config),
webWorkerPlugin(config),
assetPlugin(config),
Expand Down
12 changes: 9 additions & 3 deletions packages/vite/src/node/plugins/resolve.ts
Expand Up @@ -8,12 +8,12 @@ import {
createDebugger,
deepImportRE,
injectQuery,
isDataUrl,
isExternalUrl,
isObject,
normalizePath,
fsPathFromId,
resolveFrom
resolveFrom,
isDataUrl
} from '../utils'
import { ResolvedConfig, ViteDevServer } from '..'
import slash from 'slash'
Expand Down Expand Up @@ -131,13 +131,19 @@ export function resolvePlugin({
}

// external
if (isExternalUrl(id) || isDataUrl(id)) {
if (isExternalUrl(id)) {
return {
id,
external: true
}
}

// data uri: pass through (this only happens during build and will be
// handled by dedicated plugin)
if (isDataUrl(id)) {
return null
}

// bare package imports, perform node resolve
if (bareImportRE.test(id)) {
// externalize node built-ins only when building for ssr
Expand Down

0 comments on commit 4fd0b86

Please sign in to comment.