Skip to content

Commit

Permalink
feat: add optimizeDeps.esbuildOptions (#2991)
Browse files Browse the repository at this point in the history
Co-authored-by: Shinigami <chrissi92@hotmail.de>
  • Loading branch information
nihalgonsalves and Shinigami92 committed May 3, 2021
1 parent 7464f62 commit 77a882a
Show file tree
Hide file tree
Showing 11 changed files with 167 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getColor } from '../../testUtils'
import { getColor, isBuild } from '../../testUtils'

test('default + named imports from cjs dep (react)', async () => {
expect(await page.textContent('.cjs button')).toBe('count is 0')
Expand Down Expand Up @@ -61,3 +61,9 @@ test('dep w/ non-js files handled via plugin', async () => {
test('vue + vuex', async () => {
expect(await page.textContent('.vue')).toMatch(`[success]`)
})

test('esbuild-plugin', async () => {
expect(await page.textContent('.esbuild-plugin')).toMatch(
isBuild ? `Hello from a package` : `Hello from an esbuild plugin`
)
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// will be replaced by an esbuild plugin

export const hello = () => `Hello from a package`
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "dep-esbuild-plugin-transform",
"version": "0.0.0",
"main": "index.js"
}
6 changes: 6 additions & 0 deletions packages/playground/optimize-deps/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ <h2>Dep w/ special file format supported via plugins</h2>
<h2>Vue & Vuex</h2>
<div class="vue"></div>

<h2>Dep with changes from esbuild plugin</h2>
<div>This should show a greeting: <span class="esbuild-plugin"></span></div>

<script type="module">
// test dep detection in globbed files
const globbed = import.meta.globEager('./glob/*.js')
Expand All @@ -64,4 +67,7 @@ <h2>Vue & Vuex</h2>
if (typeof createApp === 'function' && typeof createStore === 'function') {
document.querySelector('.vue').textContent = '[success]'
}

import { hello } from 'dep-esbuild-plugin-transform'
document.querySelector('.esbuild-plugin').textContent = hello()
</script>
1 change: 1 addition & 0 deletions packages/playground/optimize-deps/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"dep-cjs-named-only": "link:./dep-cjs-named-only",
"dep-linked": "link:./dep-linked",
"dep-linked-include": "link:./dep-linked-include",
"dep-esbuild-plugin-transform": "link:./dep-esbuild-plugin-transform",
"phoenix": "^1.5.7",
"react": "^17.0.1",
"react-dom": "^17.0.1",
Expand Down
23 changes: 21 additions & 2 deletions packages/playground/optimize-deps/vite.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,27 @@ module.exports = {
},

optimizeDeps: {
include: ['dep-linked-include'],
plugins: [vue()]
include: [
'dep-linked-include',
// required since it isn't in node_modules and is ignored by the optimizer otherwise
'dep-esbuild-plugin-transform'
],
esbuildOptions: {
plugins: [
{
name: 'replace-a-file',
setup(build) {
build.onLoad(
{ filter: /dep-esbuild-plugin-transform(\\|\/)index\.js$/ },
() => ({
contents: `export const hello = () => 'Hello from an esbuild plugin'`,
loader: 'js'
})
)
}
}
]
}
},

build: {
Expand Down
49 changes: 48 additions & 1 deletion packages/vite/src/node/__tests__/config.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { mergeConfig, UserConfigExport } from '../config'
import { InlineConfig } from '..'
import { mergeConfig, resolveConfig, UserConfigExport } from '../config'

describe('mergeConfig', () => {
test('handles configs with different alias schemas', () => {
Expand Down Expand Up @@ -92,3 +93,49 @@ describe('mergeConfig', () => {
expect(mergeConfig(baseConfig, newConfig)).toEqual(mergedConfig)
})
})

describe('resolveConfig', () => {
beforeAll(() => {
// silence deprecation warning
jest.spyOn(console, 'warn').mockImplementation(() => {})
})

afterAll(() => {
jest.clearAllMocks()
})

test('copies optimizeDeps.keepNames to esbuildOptions.keepNames', async () => {
const config: InlineConfig = {
optimizeDeps: {
keepNames: false
}
}

expect(await resolveConfig(config, 'serve')).toMatchObject({
optimizeDeps: {
esbuildOptions: {
keepNames: false
}
}
})
})

test('uses esbuildOptions.keepNames if set', async () => {
const config: InlineConfig = {
optimizeDeps: {
keepNames: true,
esbuildOptions: {
keepNames: false
}
}
}

expect(await resolveConfig(config, 'serve')).toMatchObject({
optimizeDeps: {
esbuildOptions: {
keepNames: false
}
}
})
})
})
35 changes: 32 additions & 3 deletions packages/vite/src/node/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,10 @@ export interface InlineConfig extends UserConfig {
}

export type ResolvedConfig = Readonly<
Omit<UserConfig, 'plugins' | 'alias' | 'dedupe' | 'assetsInclude'> & {
Omit<
UserConfig,
'plugins' | 'alias' | 'dedupe' | 'assetsInclude' | 'optimizeDeps'
> & {
configFile: string | undefined
configFileDependencies: string[]
inlineConfig: InlineConfig
Expand All @@ -193,6 +196,7 @@ export type ResolvedConfig = Readonly<
assetsInclude: (file: string) => boolean
logger: Logger
createResolver: (options?: Partial<InternalResolveOptions>) => ResolveFn
optimizeDeps: Omit<DepOptimizationOptions, 'keepNames'>
}
>

Expand Down Expand Up @@ -381,10 +385,17 @@ export async function resolveConfig(
return DEFAULT_ASSETS_RE.test(file) || assetsFilter(file)
},
logger,
createResolver
createResolver,
optimizeDeps: {
...config.optimizeDeps,
esbuildOptions: {
keepNames: config.optimizeDeps?.keepNames,
...config.optimizeDeps?.esbuildOptions
}
}
}

;(resolved as any).plugins = await resolvePlugins(
;(resolved.plugins as Plugin[]) = await resolvePlugins(
resolved,
prePlugins,
normalPlugins,
Expand Down Expand Up @@ -466,6 +477,24 @@ export async function resolveConfig(
}
})

if (config.optimizeDeps?.keepNames) {
logDeprecationWarning(
'optimizeDeps.keepNames',
'Use "optimizeDeps.esbuildOptions.keepNames" instead.'
)
}
Object.defineProperty(resolved.optimizeDeps, 'keepNames', {
enumerable: false,
get() {
logDeprecationWarning(
'optimizeDeps.keepNames',
'Use "optimizeDeps.esbuildOptions.keepNames" instead.',
new Error()
)
return resolved.optimizeDeps.esbuildOptions?.keepNames
}
})

return resolved
}

Expand Down
41 changes: 35 additions & 6 deletions packages/vite/src/node/optimizer/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import fs from 'fs'
import path from 'path'
import chalk from 'chalk'
import { createHash } from 'crypto'
import { build } from 'esbuild'
import { build, BuildOptions as EsbuildBuildOptions } from 'esbuild'
import { ResolvedConfig } from '../config'
import {
createDebugger,
Expand Down Expand Up @@ -47,9 +47,32 @@ export interface DepOptimizationOptions {
*/
exclude?: string[]
/**
* The bundler sometimes needs to rename symbols to avoid collisions.
* Set this to `true` to keep the `name` property on functions and classes.
* https://esbuild.github.io/api/#keep-names
* Options to pass to esbuild during the dep scanning and optimization
*
* Certain options are omitted since changing them would not be compatible
* with Vite's dep optimization.
*
* - `external` is also omitted, use Vite's `optimizeDeps.exclude` option
* - `plugins` are merged with Vite's dep plugin
* - `keepNames` takes precedence over the deprecated `optimizeDeps.keepNames`
*
* https://esbuild.github.io/api
*/
esbuildOptions?: Omit<
EsbuildBuildOptions,
| 'bundle'
| 'entryPoints'
| 'external'
| 'write'
| 'watch'
| 'outdir'
| 'outfile'
| 'outbase'
| 'outExtension'
| 'metafile'
>
/**
* @deprecated use `esbuildOptions.keepNames`
*/
keepNames?: boolean
}
Expand Down Expand Up @@ -233,10 +256,12 @@ export async function optimizeDeps(

const start = Date.now()

const { plugins = [], ...esbuildOptions } =
config.optimizeDeps?.esbuildOptions ?? {}

const result = await build({
entryPoints: Object.keys(flatIdDeps),
bundle: true,
keepNames: config.optimizeDeps?.keepNames,
format: 'esm',
external: config.optimizeDeps?.exclude,
logLevel: 'error',
Expand All @@ -246,7 +271,11 @@ export async function optimizeDeps(
treeShaking: 'ignore-annotations',
metafile: true,
define,
plugins: [esbuildDepPlugin(flatIdDeps, flatIdToExports, config)]
plugins: [
...plugins,
esbuildDepPlugin(flatIdDeps, flatIdToExports, config)
],
...esbuildOptions
})

const meta = result.metafile!
Expand Down
6 changes: 5 additions & 1 deletion packages/vite/src/node/optimizer/scan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ export async function scanImports(
const container = await createPluginContainer(config)
const plugin = esbuildScanPlugin(config, container, deps, missing, entries)

const { plugins = [], ...esbuildOptions } =
config.optimizeDeps?.esbuildOptions ?? {}

await Promise.all(
entries.map((entry) =>
build({
Expand All @@ -97,7 +100,8 @@ export async function scanImports(
bundle: true,
format: 'esm',
logLevel: 'error',
plugins: [plugin]
plugins: [...plugins, plugin],
...esbuildOptions
})
)
)
Expand Down
4 changes: 4 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2707,6 +2707,10 @@ delegate@^3.1.2:
version "0.0.0"
uid ""

"dep-esbuild-plugin-transform@link:./packages/playground/optimize-deps/dep-esbuild-plugin-transform":
version "0.0.0"
uid ""

"dep-import-type@link:./packages/playground/ssr-vue/dep-import-type":
version "0.0.0"
uid ""
Expand Down

0 comments on commit 77a882a

Please sign in to comment.