Skip to content

Commit

Permalink
refactor: opt-in optimizeDeps during build and SSR (#8965)
Browse files Browse the repository at this point in the history
  • Loading branch information
patak-dev committed Jul 8, 2022
1 parent b835699 commit f8c8cf2
Show file tree
Hide file tree
Showing 10 changed files with 54 additions and 70 deletions.
23 changes: 9 additions & 14 deletions docs/guide/migration.md
Expand Up @@ -31,26 +31,12 @@ A small fraction of users will now require using [@vitejs/plugin-legacy](https:/

This section describes the biggest architecture changes in Vite v3. To allow projects to migrate from v2 in case of a compat issue, legacy options have been added to revert to the Vite v2 strategies.

:::warning
These options are marked as experimental and deprecated. They may be removed in a future v3 minor without respecting semver. Please pin the Vite version when using them.

- `legacy.buildRollupPluginCommonjs`
- `legacy.buildSsrCjsExternalHeuristics`

:::

### Dev Server Changes

Vite's default dev server port is now 5173. You can use [`server.port`](../config/server-options.md#server-port) to set it to 3000.

Vite's default dev server host is now `localhost`. You can use [`server.host`](../config/server-options.md#server-host) to set it to `127.0.0.1`.

### Build Changes

In v3, Vite uses esbuild to optimize dependencies by default. Doing so, it removes one of the most significant differences between dev and prod present in v2. Because esbuild converts CJS-only dependencies to ESM, [`@rollupjs/plugin-commonjs`](https://github.com/rollup/plugins/tree/master/packages/commonjs) is no longer used.

If you need to get back to the v2 strategy, you can use `legacy.buildRollupPluginCommonjs`.

### SSR Changes

Vite v3 uses ESM for the SSR build by default. When using ESM, the [SSR externalization heuristics](https://vitejs.dev/guide/ssr.html#ssr-externals) are no longer needed. By default, all dependencies are externalized. You can use [`ssr.noExternal`](../config/ssr-options.md#ssr-noexternal) to control what dependencies to include in the SSR bundle.
Expand Down Expand Up @@ -114,6 +100,15 @@ export default {
}
```

## Experimental

### Using esbuild deps optimization at build time

In v3, Vite allows the use of esbuild to optimize dependencies during build time. If enabled, it removes one of the most significant differences between dev and prod present in v2. [`@rollupjs/plugin-commonjs`](https://github.com/rollup/plugins/tree/master/packages/commonjs) is no longer needed in this case since esbuild converts CJS-only dependencies to ESM.

If you want to try this build strategy, you can use `optimizeDeps.disabled: false` (the default in v3 is `disabled: 'build'`). `@rollup/plugin-commonjs`
can be removed by passing `build.commonjsOptions: { include: [] }`

## Advanced

There are some changes which only affects plugin/tool creators.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -21,7 +21,7 @@
"test": "run-s test-unit test-serve test-build",
"test-serve": "vitest run -c vitest.config.e2e.ts",
"test-build": "cross-env VITE_TEST_BUILD=1 vitest run -c vitest.config.e2e.ts",
"test-build-legacy-cjs": "cross-env VITE_TEST_LEGACY_CJS_PLUGIN=1 pnpm test-build",
"test-build-without-plugin-commonjs": "cross-env VITE_TEST_WITHOUT_PLUGIN_COMMONJS=1 pnpm test-build",
"test-unit": "vitest run",
"test-docs": "pnpm run docs-build",
"debug-serve": "cross-env VITE_DEBUG_SERVE=1 vitest run -c vitest.config.e2e.ts",
Expand Down
9 changes: 5 additions & 4 deletions packages/vite/src/node/build.ts
Expand Up @@ -297,14 +297,15 @@ export function resolveBuildPlugins(config: ResolvedConfig): {
post: Plugin[]
} {
const options = config.build

const { commonjsOptions } = options
const usePluginCommonjs =
!Array.isArray(commonjsOptions?.include) ||
commonjsOptions?.include.length !== 0
return {
pre: [
...(options.watch ? [ensureWatchPlugin()] : []),
watchPackageDataPlugin(config),
...(config.legacy?.buildRollupPluginCommonjs
? [commonjsPlugin(options.commonjsOptions)]
: []),
...(usePluginCommonjs ? [commonjsPlugin(options.commonjsOptions)] : []),
dataURIPlugin(),
assetImportMetaUrlPlugin(config),
...(options.rollupOptions.plugins
Expand Down
39 changes: 10 additions & 29 deletions packages/vite/src/node/config.ts
Expand Up @@ -280,14 +280,6 @@ export interface ExperimentalOptions {
}

export interface LegacyOptions {
/**
* Revert vite build to the v2.9 strategy. Disable esbuild deps optimization and adds `@rollup/plugin-commonjs`
*
* @experimental
* @deprecated
* @default false
*/
buildRollupPluginCommonjs?: boolean
/**
* Revert vite build --ssr to the v2.9 strategy. Use CJS SSR build and v2.9 externalization heuristics
*
Expand Down Expand Up @@ -571,11 +563,14 @@ export async function resolveConfig(

const optimizeDeps = config.optimizeDeps || {}

if (process.env.VITE_TEST_LEGACY_CJS_PLUGIN) {
config.legacy = {
...config.legacy,
buildRollupPluginCommonjs: true
}
if (process.env.VITE_TEST_WITHOUT_PLUGIN_COMMONJS) {
config.build ??= {}
config.build.commonjsOptions = { include: [] }
config.optimizeDeps ??= {}
config.optimizeDeps.disabled = false
config.ssr ??= {}
config.ssr.optimizeDeps ??= {}
config.ssr.optimizeDeps.disabled = false
}

const BASE_URL = resolvedBase
Expand Down Expand Up @@ -616,14 +611,15 @@ export async function resolveConfig(
packageCache: new Map(),
createResolver,
optimizeDeps: {
disabled: 'build',
...optimizeDeps,
esbuildOptions: {
preserveSymlinks: config.resolve?.preserveSymlinks,
...optimizeDeps.esbuildOptions
}
},
worker: resolvedWorkerOptions,
appType: config.appType ?? middlewareMode === 'ssr' ? 'custom' : 'spa',
appType: config.appType ?? (middlewareMode === 'ssr' ? 'custom' : 'spa'),
experimental: {
importGlobRestoreExtension: false,
hmrPartialAccept: false,
Expand Down Expand Up @@ -661,21 +657,6 @@ export async function resolveConfig(
)
}

if (resolved.legacy?.buildRollupPluginCommonjs) {
const optimizerDisabled = resolved.optimizeDeps.disabled
if (!optimizerDisabled) {
resolved.optimizeDeps.disabled = 'build'
} else if (optimizerDisabled === 'dev') {
resolved.optimizeDeps.disabled = true // Also disabled during build
}
const ssrOptimizerDisabled = resolved.ssr.optimizeDeps.disabled
if (!ssrOptimizerDisabled) {
resolved.ssr.optimizeDeps.disabled = 'build'
} else if (ssrOptimizerDisabled === 'dev') {
resolved.ssr.optimizeDeps.disabled = true // Also disabled during build
}
}

// Some plugins that aren't intended to work in the bundling of workers (doing post-processing at build time for example).
// And Plugins may also have cached that could be corrupted by being used in these extra rollup calls.
// So we need to separate the worker plugin from the plugin that vite needs to run.
Expand Down
3 changes: 1 addition & 2 deletions packages/vite/src/node/optimizer/index.ts
Expand Up @@ -564,8 +564,7 @@ export async function runOptimizeDeps(
rollupOptionsExternal.some((ext) => typeof ext !== 'string')
) {
throw new Error(
`[vite] 'build.rollupOptions.external' can only be an array of strings or a string.\n` +
`You can turn on 'legacy.buildRollupPluginCommonjs' to support more advanced options.`
`[vite] 'build.rollupOptions.external' can only be an array of strings or a string when using esbuild optimization at build time.`
)
}
external.push(...(rollupOptionsExternal as string[]))
Expand Down
1 change: 1 addition & 0 deletions packages/vite/src/node/ssr/index.ts
Expand Up @@ -61,6 +61,7 @@ export function resolveSSROptions(
target,
...ssr,
optimizeDeps: {
disabled: true,
...optimizeDeps,
esbuildOptions: {
preserveSymlinks,
Expand Down
12 changes: 12 additions & 0 deletions playground/import-assertion/vite.config.js
@@ -0,0 +1,12 @@
import { defineConfig } from 'vite'

export default defineConfig({
build: {
commonjsOptions: {
include: []
}
},
optimizeDeps: {
disabled: false
}
})
13 changes: 5 additions & 8 deletions playground/optimize-deps/__tests__/optimize-deps.spec.ts
Expand Up @@ -105,14 +105,11 @@ test('vue + vuex', async () => {

// When we use the Rollup CommonJS plugin instead of esbuild prebundling,
// the esbuild plugins won't apply to dependencies
test.skipIf(isBuild && process.env.VITE_TEST_LEGACY_CJS_PLUGIN)(
'esbuild-plugin',
async () => {
expect(await page.textContent('.esbuild-plugin')).toMatch(
`Hello from an esbuild plugin`
)
}
)
test('esbuild-plugin', async () => {
expect(await page.textContent('.esbuild-plugin')).toMatch(
`Hello from an esbuild plugin`
)
})

test('import from hidden dir', async () => {
expect(await page.textContent('.hidden-dir')).toBe('hello!')
Expand Down
8 changes: 6 additions & 2 deletions playground/optimize-deps/vite.config.js
Expand Up @@ -14,8 +14,8 @@ module.exports = {
'node:url': 'url'
}
},

optimizeDeps: {
disabled: false,
include: [
'dep-linked-include',
'nested-exclude > nested-include',
Expand Down Expand Up @@ -44,7 +44,11 @@ module.exports = {

build: {
// to make tests faster
minify: false
minify: false,
// Avoid @rollup/plugin-commonjs
commonjsOptions: {
include: []
}
},

plugins: [
Expand Down
14 changes: 4 additions & 10 deletions playground/ssr-deps/server.js
Expand Up @@ -36,16 +36,10 @@ export async function createServer(root = process.cwd(), hmrPort) {
appType: 'custom',
ssr: {
noExternal: ['no-external-cjs', 'import-builtin-cjs', 'no-external-css'],
external: ['nested-external']
},
optimizeDeps: {
include: [
'no-external-cjs',
'import-builtin-cjs',
'optimized-with-nested-external',
'optimized-cjs-with-nested-external'
],
exclude: ['nested-external']
external: ['nested-external'],
optimizeDeps: {
disabled: 'build'
}
}
})
// use vite's connect instance as middleware
Expand Down

0 comments on commit f8c8cf2

Please sign in to comment.