Skip to content

Commit

Permalink
feat(assets): allow new URL to resolve package assets
Browse files Browse the repository at this point in the history
  • Loading branch information
kherock committed Apr 22, 2022
1 parent f506315 commit 099f2b8
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 9 deletions.
4 changes: 4 additions & 0 deletions packages/playground/assets/__tests__/assets.spec.ts
Expand Up @@ -234,6 +234,10 @@ test('new URL(..., import.meta.url)', async () => {
expect(await page.textContent('.import-meta-url')).toMatch(assetMatch)
})

test('new URL(@/..., import.meta.url)', async () => {
expect(await page.textContent('.import-meta-url-dep')).toMatch(assetMatch)
})

test('new URL(/..., import.meta.url)', async () => {
expect(await page.textContent('.import-meta-url-base-path')).toMatch(
iconMatch
Expand Down
8 changes: 8 additions & 0 deletions packages/playground/assets/index.html
Expand Up @@ -141,6 +141,10 @@ <h2>new URL('...', import.meta.url)</h2>
<img class="import-meta-url-img" />
<code class="import-meta-url"></code>

<h2>new URL('@/...', import.meta.url)</h2>
<img class="import-meta-url-dep-img" />
<code class="import-meta-url-dep"></code>

<h2>new URL('/...', import.meta.url)</h2>
<img class="import-meta-url-base-path-img" />
<code class="import-meta-url-base-path"></code>
Expand Down Expand Up @@ -280,6 +284,10 @@ <h3 class="raw-query"></h3>
text('.import-meta-url', metaUrl)
document.querySelector('.import-meta-url-img').src = metaUrl

const metaUrlDep = new URL('@/asset.png', import.meta.url)
text('.import-meta-url-dep', metaUrlDep)
document.querySelector('.import-meta-url-dep-img').src = metaUrlDep

// testing URLs for public assets served at the public base path
// equivalent to `new URL(`${import.meta.env.BASE_URL}/icon.png`, self.location)
const metaUrlBasePath = new URL('/icon.png', import.meta.url)
Expand Down
2 changes: 0 additions & 2 deletions packages/vite/src/node/build.ts
Expand Up @@ -36,7 +36,6 @@ import { resolveSSRExternal, shouldExternalizeForSSR } from './ssr/ssrExternal'
import { ssrManifestPlugin } from './ssr/ssrManifestPlugin'
import type { DepOptimizationMetadata } from './optimizer'
import { getDepsCacheDir, findKnownImports } from './optimizer'
import { assetImportMetaUrlPlugin } from './plugins/assetImportMetaUrl'
import { loadFallbackPlugin } from './plugins/loadFallback'
import { watchPackageDataPlugin } from './packages'
import { ensureWatchPlugin } from './plugins/ensureWatch'
Expand Down Expand Up @@ -314,7 +313,6 @@ export function resolveBuildPlugins(config: ResolvedConfig): {
commonjsPlugin(options.commonjsOptions),
dataURIPlugin(),
dynamicImportVars(options.dynamicImportVarsOptions),
assetImportMetaUrlPlugin(config),
...(options.rollupOptions.plugins
? (options.rollupOptions.plugins.filter(Boolean) as Plugin[])
: [])
Expand Down
32 changes: 25 additions & 7 deletions packages/vite/src/node/plugins/assetImportMetaUrl.ts
@@ -1,9 +1,10 @@
import type { Plugin } from '../plugin'
import MagicString from 'magic-string'
import path from 'path'
import { fileToUrl } from './asset'
import type { ResolvedConfig } from '../config'
import { emptyString } from '../cleanString'
import type { ResolveFn } from '../'
import { isParentDirectory, normalizePath } from '../utils'

/**
* Convert `new URL('./foo.png', import.meta.url)` to its resolved built URL
Expand All @@ -16,6 +17,8 @@ import { emptyString } from '../cleanString'
* ```
*/
export function assetImportMetaUrlPlugin(config: ResolvedConfig): Plugin {
let assetResolver: ResolveFn

return {
name: 'vite:asset-import-meta-url',
async transform(code, id, options) {
Expand Down Expand Up @@ -62,16 +65,31 @@ export function assetImportMetaUrlPlugin(config: ResolvedConfig): Plugin {
}

const url = rawUrl.slice(1, -1)
const file = path.resolve(path.dirname(id), url)
// Get final asset URL. Catch error if the file does not exist,
// in which we can resort to the initial URL and let it resolve in runtime
const builtUrl = await fileToUrl(file, config, this).catch(() => {
assetResolver ??= config.createResolver({
root: config.publicDir,
extensions: [],
mainFields: [],
tryIndex: false,
preferRelative: true
})
const resolved = await assetResolver(url, id)
if (!resolved) {
const rawExp = code.slice(index, index + exp.length)
config.logger.warnOnce(
`\n${rawExp} doesn't exist at build time, it will remain unchanged to be resolved at runtime`
)
return url
})
}
// Get final asset URL. If the file does not exist,
// we fall back to the initial URL and let it resolve in runtime
const builtUrl = resolved
? await fileToUrl(
isParentDirectory(normalizePath(config.publicDir), resolved)
? url
: resolved,
config,
this
)
: url
s.overwrite(
index,
index + exp.length,
Expand Down
2 changes: 2 additions & 0 deletions packages/vite/src/node/plugins/index.ts
Expand Up @@ -17,6 +17,7 @@ import { preAliasPlugin } from './preAlias'
import { definePlugin } from './define'
import { ssrRequireHookPlugin } from './ssrRequireHook'
import { workerImportMetaUrlPlugin } from './workerImportMetaUrl'
import { assetImportMetaUrlPlugin } from './assetImportMetaUrl'
import { ensureWatchPlugin } from './ensureWatch'
import { metadataPlugin } from './metadata'

Expand Down Expand Up @@ -71,6 +72,7 @@ export async function resolvePlugins(
config.build.ssr ? ssrRequireHookPlugin(config) : null,
isBuild && buildHtmlPlugin(config),
workerImportMetaUrlPlugin(config),
assetImportMetaUrlPlugin(config),
...buildPlugins.pre,
...postPlugins,
...buildPlugins.post,
Expand Down

0 comments on commit 099f2b8

Please sign in to comment.