Skip to content

Commit

Permalink
Merge branch 'main' into fix(html)/replace-define-dev
Browse files Browse the repository at this point in the history
  • Loading branch information
patak-dev committed Mar 4, 2022
2 parents a598ebb + 6cb0647 commit eabf6ae
Show file tree
Hide file tree
Showing 8 changed files with 77 additions and 51 deletions.
2 changes: 2 additions & 0 deletions docs/config/index.md
Expand Up @@ -139,9 +139,11 @@ export default defineConfig(async ({ command, mode }) => {

- Replacements are performed only when the match is surrounded by word boundaries (`\b`).

::: warning
Because it's implemented as straightforward text replacements without any syntax analysis, we recommend using `define` for CONSTANTS only.

For example, `process.env.FOO` and `__APP_VERSION__` are good fits. But `process` or `global` should not be put into this option. Variables can be shimmed or polyfilled instead.
:::

::: tip NOTE
For TypeScript users, make sure to add the type declarations in the `env.d.ts` or `vite-env.d.ts` file to get type checks and Intellisense.
Expand Down
9 changes: 0 additions & 9 deletions packages/playground/define/__tests__/define.spec.ts
Expand Up @@ -22,13 +22,4 @@ test('string', async () => {
)
// html would't need to define replacement
expect(await page.textContent('.exp-define')).toBe('__EXP__')
expect(await page.textContent('.import-file')).not.toBe(
`import * from "${defines.__IMPORT_FILE_NAME__}"`
)
expect(await page.textContent('.export-file')).not.toBe(
`export * from "${defines.__EXPORT_FILE_NAME__}"`
)
expect(await page.textContent('.path')).not.toBe(
`import * from "xxxx/${defines.PATH}"`
)
})
6 changes: 0 additions & 6 deletions packages/playground/define/index.html
Expand Up @@ -10,9 +10,6 @@ <h1>Define</h1>
<p>spread object: <code class="spread-object"></code></p>
<p>spread array: <code class="spread-array"></code></p>
<p>define variable in html: <code class="exp-define">__EXP__</code></p>
<p>import file: <code class="import-file"></code></p>
<p>export file: <code class="export-file"></code></p>
<p>path: <code class="path"></code></p>

<script type="module">
const __VAR_NAME__ = true // ensure define doesn't replace var name
Expand All @@ -30,9 +27,6 @@ <h1>Define</h1>
})
)
text('.spread-array', JSON.stringify([...`"${__STRING__}"`]))
text('.import-file', `import * from "__IMPORT_FILE_NAME__"`)
text('.export-file', `export * from "__EXPORT_FILE_NAME__"`)
text('.path', `import * from "xxxx/PATH"`)

function text(el, text) {
document.querySelector(el).textContent = text
Expand Down
5 changes: 1 addition & 4 deletions packages/playground/define/vite.config.js
Expand Up @@ -16,9 +16,6 @@ module.exports = {
}
},
__VAR_NAME__: false,
'process.env.SOMEVAR': '"SOMEVAR"',
__IMPORT_FILE_NAME__: '"importFileName"',
__EXPORT_FILE_NAME__: '"exportFileName"',
PATH: '"filePath"'
'process.env.SOMEVAR': '"SOMEVAR"'
}
}
39 changes: 39 additions & 0 deletions packages/vite/src/node/__tests__/plugins/define.spec.ts
@@ -0,0 +1,39 @@
import { definePlugin } from '../../plugins/define'
import { resolveConfig } from '../../config'

async function createDefinePluginTransform(
define: Record<string, any> = {},
build = true,
ssr = false
) {
const config = await resolveConfig({ define }, build ? 'build' : 'serve')
const instance = definePlugin(config)
return async (code: string) => {
const result = await instance.transform.call({}, code, 'foo.ts', { ssr })
return result?.code || result
}
}

describe('definePlugin', () => {
test('replaces custom define', async () => {
const transform = await createDefinePluginTransform({
__APP_VERSION__: JSON.stringify('1.0')
})
expect(await transform('const version = __APP_VERSION__ ;')).toBe(
'const version = "1.0" ;'
)
expect(await transform('const version = __APP_VERSION__;')).toBe(
'const version = "1.0";'
)
})

test('replaces import.meta.env.SSR with false', async () => {
const transform = await createDefinePluginTransform()
expect(await transform('const isSSR = import.meta.env.SSR ;')).toBe(
'const isSSR = false ;'
)
expect(await transform('const isSSR = import.meta.env.SSR;')).toBe(
'const isSSR = false;'
)
})
})
24 changes: 16 additions & 8 deletions packages/vite/src/node/optimizer/index.ts
@@ -1,5 +1,6 @@
import fs from 'fs'
import path from 'path'
import _debug from 'debug'
import colors from 'picocolors'
import { createHash } from 'crypto'
import type { BuildOptions as EsbuildBuildOptions } from 'esbuild'
Expand All @@ -21,6 +22,7 @@ import { transformWithEsbuild } from '../plugins/esbuild'
import { performance } from 'perf_hooks'

const debug = createDebugger('vite:deps')
const isDebugEnabled = _debug('vite:deps').enabled

export type ExportsData = ReturnType<typeof parse> & {
// es-module-lexer has a facade detection but isn't always accurate for our
Expand Down Expand Up @@ -339,14 +341,20 @@ export async function createOptimizeDepsRun(
return
}

const total = qualifiedIds.length
const maxListed = 5
const listed = Math.min(total, maxListed)
const extra = Math.max(0, total - maxListed)
const depsString = colors.yellow(
qualifiedIds.slice(0, listed).join(`\n `) +
(extra > 0 ? `\n (...and ${extra} more)` : ``)
)
let depsString: string
if (isDebugEnabled) {
depsString = colors.yellow(qualifiedIds.join(`\n `))
} else {
const total = qualifiedIds.length
const maxListed = 5
const listed = Math.min(total, maxListed)
const extra = Math.max(0, total - maxListed)
depsString = colors.yellow(
qualifiedIds.slice(0, listed).join(`\n `) +
(extra > 0 ? `\n (...and ${extra} more)` : ``)
)
}

if (!asCommand) {
if (!newDeps) {
// This is auto run on server start - let the user know that we are
Expand Down
39 changes: 15 additions & 24 deletions packages/vite/src/node/plugins/define.ts
Expand Up @@ -54,6 +54,7 @@ export function definePlugin(config: ResolvedConfig): Plugin {
'globalThis.process.env.': `({}).`
})
}

const replacements: Record<string, string> = {
...(isNeedProcessEnv ? processNodeEnv : {}),
...userDefine,
Expand All @@ -62,30 +63,20 @@ export function definePlugin(config: ResolvedConfig): Plugin {
}

const replacementsKeys = Object.keys(replacements)

if (!replacementsKeys.length) {
return [replacements, null]
}

const replacementsStr = replacementsKeys
.map((str) => {
return str.replace(/[-[\]/{}()*+?.\\^$|]/g, '\\$&')
})
.join('|')

// The following characters are not allowed because they are String boundaries
const characters = '[\'"`\\/-_]'

const pattern = new RegExp(
`(?<!${characters})` +
// Do not allow preceding '.', but do allow preceding '...' for spread operations
'(?<!(?<!\\.\\.)\\.)' +
`\\b(${replacementsStr})\\b` +
`(?!${characters})` +
// prevent trailing assignments
'(?!\\s*?=[^=])',
'g'
)
const pattern = replacementsKeys.length
? new RegExp(
// Do not allow preceding '.', but do allow preceding '...' for spread operations
'(?<!(?<!\\.\\.)\\.)\\b(' +
replacementsKeys
.map((str) => {
return str.replace(/[-[\]/{}()*+?.\\^$|]/g, '\\$&')
})
.join('|') +
// prevent trailing assignments
')\\b(?!\\s*?=[^=])',
'g'
)
: null

return [replacements, pattern]
}
Expand Down
4 changes: 4 additions & 0 deletions packages/vite/src/node/plugins/importAnalysis.ts
Expand Up @@ -213,6 +213,10 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin {
const resolved = await this.resolve(url, importerFile)

if (!resolved) {
// in ssr, we should let node handle the missing modules
if (ssr) {
return [url, url]
}
this.error(
`Failed to resolve import "${url}" from "${path.relative(
process.cwd(),
Expand Down

0 comments on commit eabf6ae

Please sign in to comment.