Skip to content

Commit

Permalink
fix: enforce generating module params when needed in relative url r…
Browse files Browse the repository at this point in the history
…esolving (fixes vitejs#9807)
  • Loading branch information
Tal500 committed Aug 23, 2022
1 parent b2c0ee0 commit f0f8f44
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 35 deletions.
57 changes: 49 additions & 8 deletions packages/vite/src/node/build.ts
Expand Up @@ -21,6 +21,7 @@ import commonjsPlugin from '@rollup/plugin-commonjs'
import type { RollupCommonJSOptions } from 'types/commonjs'
import type { RollupDynamicImportVarsOptions } from 'types/dynamicImportVars'
import type { TransformOptions } from 'esbuild'
import type MagicString from 'magic-string'
import type { InlineConfig, ResolvedConfig } from './config'
import { isDepsOptimizerEnabled, resolveConfig } from './config'
import { buildReporterPlugin } from './plugins/reporter'
Expand Down Expand Up @@ -902,7 +903,10 @@ export type RenderBuiltAssetUrl = (
hostType: 'js' | 'css' | 'html'
ssr: boolean
}
) => string | { relative?: boolean; runtime?: string } | undefined
) =>
| string
| { relative?: boolean; runtime?: string; needModuleParam?: boolean }
| undefined

export function toOutputFilePathInString(
filename: string,
Expand All @@ -914,10 +918,13 @@ export function toOutputFilePathInString(
toRelative: (
filename: string,
hostType: string
) => string | { runtime: string } = getToImportMetaURLBasedRelativePath(
format
)
): string | { runtime: string } {
) =>
| string
| {
runtime: string
needModuleParam: boolean
} = getToImportMetaURLBasedRelativePath(format)
): string | { runtime: string; needModuleParam: boolean } {
const { renderBuiltUrl } = config.experimental
let relative = config.base === '' || config.base === './'
if (renderBuiltUrl) {
Expand All @@ -929,7 +936,10 @@ export function toOutputFilePathInString(
})
if (typeof result === 'object') {
if (result.runtime) {
return { runtime: result.runtime }
return {
runtime: result.runtime,
needModuleParam: !!result.needModuleParam
}
}
if (typeof result.relative === 'boolean') {
relative = result.relative
Expand All @@ -944,14 +954,45 @@ export function toOutputFilePathInString(
return config.base + filename
}

export function ensureHavingSystemJSModuleParam(
s: MagicString,
code: string
): void {
const wrapIdx = code.indexOf('System.register')
if (wrapIdx < 0) return
const functionStr = 'function ('
const functionIdx = code.indexOf(functionStr, wrapIdx)
if (functionIdx < 0) return
const functionParameterStartIdx = functionIdx + functionStr.length
const functionParameterEndIdx = code.indexOf(')', functionParameterStartIdx)
const functionParameterModuleIdx = code.indexOf(
'module',
functionParameterStartIdx
)
const hasModuleParameter =
functionParameterModuleIdx >= 0 &&
functionParameterModuleIdx < functionParameterEndIdx
if (!hasModuleParameter) {
s.overwrite(
functionParameterStartIdx - 1,
functionParameterEndIdx + 1,
'(exports, module)'
)
}
}

function getToImportMetaURLBasedRelativePath(
format: InternalModuleFormat
): (filename: string, importer: string) => { runtime: string } {
): (
filename: string,
importer: string
) => { runtime: string; needModuleParam: boolean } {
const toRelativePath = relativeUrlMechanisms[format]
return (filename, importer) => ({
runtime: toRelativePath(
path.posix.relative(path.dirname(importer), filename)
)
),
needModuleParam: format === 'system'
})
}

Expand Down
40 changes: 27 additions & 13 deletions packages/vite/src/node/plugins/asset.ts
Expand Up @@ -10,7 +10,10 @@ import type {
RenderedChunk
} from 'rollup'
import MagicString from 'magic-string'
import { toOutputFilePathInString } from '../build'
import {
ensureHavingSystemJSModuleParam,
toOutputFilePathInString
} from '../build'
import type { Plugin } from '../plugin'
import type { ResolvedConfig } from '../config'
import { cleanUrl, getHash, normalizePath } from '../utils'
Expand Down Expand Up @@ -48,9 +51,10 @@ export function renderAssetUrlInJS(
chunk: RenderedChunk,
opts: NormalizedOutputOptions,
code: string
): MagicString | undefined {
): { s: MagicString; needModuleParam: boolean } | undefined {
let match: RegExpExecArray | null
let s: MagicString | undefined
let needModuleParam = false

// Urls added with JS using e.g.
// imgElement.src = "__VITE_ASSET__5aa0ddc0__" are using quotes
Expand All @@ -76,10 +80,13 @@ export function renderAssetUrlInJS(
config,
opts.format
)
const replacementString =
typeof replacement === 'string'
? JSON.stringify(replacement).slice(1, -1)
: `"+${replacement.runtime}+"`
let replacementString: string
if (typeof replacement === 'string') {
replacementString = JSON.stringify(replacement).slice(1, -1)
} else {
replacementString = `"+${replacement.runtime}+"`
needModuleParam ||= replacement.needModuleParam
}
s.overwrite(match.index, match.index + full.length, replacementString, {
contentOnly: true
})
Expand All @@ -100,16 +107,19 @@ export function renderAssetUrlInJS(
config,
opts.format
)
const replacementString =
typeof replacement === 'string'
? JSON.stringify(replacement).slice(1, -1)
: `"+${replacement.runtime}+"`
let replacementString: string
if (typeof replacement === 'string') {
replacementString = JSON.stringify(replacement).slice(1, -1)
} else {
replacementString = `"+${replacement.runtime}+"`
needModuleParam ||= replacement.needModuleParam
}
s.overwrite(match.index, match.index + full.length, replacementString, {
contentOnly: true
})
}

return s
return s && { s, needModuleParam }
}

/**
Expand Down Expand Up @@ -167,9 +177,13 @@ export function assetPlugin(config: ResolvedConfig): Plugin {
},

renderChunk(code, chunk, opts) {
const s = renderAssetUrlInJS(this, config, chunk, opts, code)
const result = renderAssetUrlInJS(this, config, chunk, opts, code)

if (s) {
if (result) {
const { s, needModuleParam } = result
if (needModuleParam) {
ensureHavingSystemJSModuleParam(s, code)
}
return {
code: s.toString(),
map: config.build.sourcemap ? s.generateMap({ hires: true }) : null
Expand Down
24 changes: 15 additions & 9 deletions packages/vite/src/node/plugins/css.ts
Expand Up @@ -25,7 +25,10 @@ import type { RawSourceMap } from '@ampproject/remapping'
import { getCodeWithSourcemap, injectSourcesContent } from '../server/sourcemap'
import type { ModuleNode } from '../server/moduleGraph'
import type { ResolveFn, ViteDevServer } from '../'
import { toOutputFilePathInCss } from '../build'
import {
ensureHavingSystemJSModuleParam,
toOutputFilePathInCss
} from '../build'
import { CLIENT_PUBLIC_PATH, SPECIAL_QUERY_RE } from '../constants'
import type { ResolvedConfig } from '../config'
import type { Plugin } from '../plugin'
Expand Down Expand Up @@ -567,14 +570,14 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin {
}
chunkCSS = await finalizeCss(chunkCSS, true, config)
let cssString = JSON.stringify(chunkCSS)
cssString =
renderAssetUrlInJS(
this,
config,
chunk,
opts,
cssString
)?.toString() || cssString
const cssRendered = renderAssetUrlInJS(
this,
config,
chunk,
opts,
cssString
)
cssString = cssRendered?.s.toString() || cssString
const style = `__vite_style__`
const injectCode =
`var ${style} = document.createElement('style');` +
Expand All @@ -585,6 +588,9 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin {
const insertIdx = code.indexOf(insertMark, wrapIdx)
const s = new MagicString(code)
s.appendLeft(insertIdx + insertMark.length, injectCode)
if (cssRendered?.needModuleParam) {
ensureHavingSystemJSModuleParam(s, code)
}
if (config.build.sourcemap) {
// resolve public URL from CSS paths, we need to use absolute paths
return {
Expand Down
21 changes: 16 additions & 5 deletions packages/vite/src/node/plugins/worker.ts
Expand Up @@ -6,7 +6,11 @@ import type { Plugin } from '../plugin'
import type { ViteDevServer } from '../server'
import { ENV_ENTRY, ENV_PUBLIC_PATH } from '../constants'
import { cleanUrl, getHash, injectQuery, parseRequest } from '../utils'
import { onRollupWarning, toOutputFilePathInString } from '../build'
import {
ensureHavingSystemJSModuleParam,
onRollupWarning,
toOutputFilePathInString
} from '../build'
import { getDepsOptimizer } from '../optimizer'
import { fileToUrl } from './asset'

Expand Down Expand Up @@ -320,6 +324,7 @@ export function webWorkerPlugin(config: ResolvedConfig): Plugin {
if (code.match(workerAssetUrlRE) || code.includes('import.meta.url')) {
let match: RegExpExecArray | null
s = new MagicString(code)
let needModuleParam = false

// Replace "__VITE_WORKER_ASSET__5aa0ddc0__" using relative paths
const workerMap = workerCache.get(config.mainConfig || config)!
Expand All @@ -336,10 +341,13 @@ export function webWorkerPlugin(config: ResolvedConfig): Plugin {
config,
outputOptions.format
)
const replacementString =
typeof replacement === 'string'
? JSON.stringify(replacement).slice(1, -1)
: `"+${replacement.runtime}+"`
let replacementString: string
if (typeof replacement === 'string') {
replacementString = JSON.stringify(replacement).slice(1, -1)
} else {
replacementString = `"+${replacement.runtime}+"`
needModuleParam ||= replacement.needModuleParam
}
s.overwrite(
match.index,
match.index + full.length,
Expand All @@ -349,6 +357,9 @@ export function webWorkerPlugin(config: ResolvedConfig): Plugin {
}
)
}
if (needModuleParam) {
ensureHavingSystemJSModuleParam(s, code)
}
}
return result()
},
Expand Down

0 comments on commit f0f8f44

Please sign in to comment.