Skip to content

Commit 08123d4

Browse files
committed
refactor: make esbuild optional peer dependency
1 parent 60c0a02 commit 08123d4

File tree

11 files changed

+76
-52
lines changed

11 files changed

+76
-52
lines changed

eslint.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ export default tseslint.config(
9191
{
9292
allowModules: [
9393
'vite',
94+
'esbuild',
9495
'less',
9596
'sass',
9697
'sass-embedded',

packages/vite/package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@
8686
"//": "READ CONTRIBUTING.md to understand what to put under deps vs. devDeps!",
8787
"dependencies": {
8888
"@oxc-project/runtime": "^0.53.0",
89-
"esbuild": "^0.25.0",
9089
"lightningcss": "^1.29.1",
9190
"postcss": "^8.5.3",
9291
"rolldown": "1.0.0-beta.3-commit.62fba31"
@@ -120,6 +119,7 @@
120119
"dotenv": "^16.4.7",
121120
"dotenv-expand": "^12.0.1",
122121
"es-module-lexer": "^1.6.0",
122+
"esbuild": "^0.25.0",
123123
"escape-html": "^1.0.3",
124124
"estree-walker": "^3.0.3",
125125
"etag": "^1.8.1",
@@ -158,6 +158,7 @@
158158
},
159159
"peerDependencies": {
160160
"@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
161+
"esbuild": "^0.25.0",
161162
"jiti": ">=1.21.0",
162163
"less": "*",
163164
"sass": "*",
@@ -172,6 +173,9 @@
172173
"@types/node": {
173174
"optional": true
174175
},
176+
"esbuild": {
177+
"optional": true
178+
},
175179
"jiti": {
176180
"optional": true
177181
},

packages/vite/rollup.dts.config.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,8 @@ const identifierReplacements: Record<string, Record<string, string>> = {
5555
TransformResult$1: 'rolldown.TransformResult',
5656
},
5757
'rolldown/experimental': {
58-
TransformOptions$2: 'rolldown_experimental_TransformOptions',
59-
TransformResult$3: 'rolldown_experimental_TransformResult',
60-
},
61-
esbuild: {
62-
TransformResult$2: 'esbuild_TransformResult',
63-
TransformOptions$1: 'esbuild_TransformOptions',
64-
BuildOptions$1: 'esbuild_BuildOptions',
58+
TransformOptions$1: 'rolldown_experimental_TransformOptions',
59+
TransformResult$2: 'rolldown_experimental_TransformResult',
6560
},
6661
'node:https': {
6762
Server$1: 'HttpsServer',

packages/vite/src/node/build.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import type {
2323
} from 'rolldown'
2424
import type { RollupCommonJSOptions } from 'dep-types/commonjs'
2525
import type { RollupDynamicImportVarsOptions } from 'dep-types/dynamicImportVars'
26-
import type { TransformOptions } from 'esbuild'
26+
import type { EsbuildTarget } from 'types/internal/esbuildOptions'
2727
import type { ChunkMetadata } from 'types/metadata'
2828
import { withTrailingSlash } from '../shared/utils'
2929
import {
@@ -104,7 +104,7 @@ export interface BuildEnvironmentOptions {
104104
* https://esbuild.github.io/content-types/#javascript for more details.
105105
* @default 'modules'
106106
*/
107-
target?: 'modules' | TransformOptions['target'] | false
107+
target?: 'modules' | EsbuildTarget | false
108108
/**
109109
* whether to inject module preload polyfill.
110110
* Note: does not apply to library mode.
@@ -157,7 +157,7 @@ export interface BuildEnvironmentOptions {
157157
* doesn't support the #RGBA syntax.
158158
* @default target
159159
*/
160-
cssTarget?: TransformOptions['target'] | false
160+
cssTarget?: EsbuildTarget | false
161161
/**
162162
* Override CSS minification specifically instead of defaulting to `build.minify`,
163163
* so you can configure minification for JS and CSS separately.

packages/vite/src/node/index.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,7 @@ export type {
138138
StylusPreprocessorOptions,
139139
} from './plugins/css'
140140
export type { JsonOptions } from './plugins/json'
141-
export type { TransformOptions as EsbuildTransformOptions } from 'esbuild'
142-
export type { ESBuildOptions, ESBuildTransformResult } from './plugins/esbuild'
141+
export type { EsbuildTransformOptions } from 'types/internal/esbuildOptions'
143142
export type { OxcOptions } from './plugins/oxc'
144143
export type { Manifest, ManifestChunk } from './plugins/manifest'
145144
export type { ResolveOptions, InternalResolveOptions } from './plugins/resolve'

packages/vite/src/node/optimizer/index.ts

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import path from 'node:path'
44
import { promisify } from 'node:util'
55
import { performance } from 'node:perf_hooks'
66
import colors from 'picocolors'
7-
import type { BuildOptions as EsbuildBuildOptions } from 'esbuild'
7+
import type { DepsOptimizerEsbuildOptions } from 'types/internal/esbuildOptions'
88
import { init, parse } from 'es-module-lexer'
99
import { isDynamicPattern } from 'tinyglobby'
1010
import {
@@ -96,19 +96,7 @@ export interface DepOptimizationConfig {
9696
*
9797
* https://esbuild.github.io/api
9898
*/
99-
esbuildOptions?: Omit<
100-
EsbuildBuildOptions,
101-
| 'bundle'
102-
| 'entryPoints'
103-
| 'external'
104-
| 'write'
105-
| 'watch'
106-
| 'outdir'
107-
| 'outfile'
108-
| 'outbase'
109-
| 'outExtension'
110-
| 'metafile'
111-
>
99+
esbuildOptions?: DepsOptimizerEsbuildOptions
112100
rollupOptions?: Omit<RolldownOptions, 'input' | 'logLevel' | 'output'> & {
113101
output?: Omit<
114102
RolldownOutputOptions,

packages/vite/src/node/plugins/css.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@ import type Stylus from 'stylus'
2222
import type Less from 'less'
2323
import type { Alias } from 'dep-types/alias'
2424
import type { LightningCSSOptions } from 'types/internal/lightningcssOptions'
25-
import type { TransformOptions } from 'esbuild'
26-
import { formatMessages, transform } from 'esbuild'
2725
import type { RawSourceMap } from '@ampproject/remapping'
2826
import { WorkerWithFallback } from 'artichokie'
2927
import { globSync } from 'tinyglobby'
@@ -37,6 +35,7 @@ import type {
3735
TransformAttributeResult as LightningCssTransformAttributeResult,
3836
TransformResult as LightningCssTransformResult,
3937
} from 'lightningcss'
38+
import type { EsbuildTransformOptions } from 'types/internal/esbuildOptions'
4039
import { getCodeWithSourcemap, injectSourcesContent } from '../server/sourcemap'
4140
import type { EnvironmentModuleNode } from '../server/moduleGraph'
4241
import {
@@ -2055,6 +2054,7 @@ async function minifyCSS(
20552054
// See https://github.com/vitejs/vite/pull/13893#issuecomment-1678628198
20562055

20572056
if (config.build.cssMinify === 'esbuild') {
2057+
const { transform, formatMessages } = await importEsbuild()
20582058
try {
20592059
const { code, warnings } = await transform(css, {
20602060
loader: 'css',
@@ -2125,8 +2125,8 @@ async function minifyCSS(
21252125

21262126
function resolveMinifyCssEsbuildOptions(
21272127
options: ESBuildOptions,
2128-
): TransformOptions {
2129-
const base: TransformOptions = {
2128+
): EsbuildTransformOptions {
2129+
const base: EsbuildTransformOptions = {
21302130
charset: options.charset ?? 'utf8',
21312131
logLevel: options.logLevel,
21322132
logLimit: options.logLimit,
@@ -3319,6 +3319,8 @@ function isPreProcessor(lang: any): lang is PreprocessLang {
33193319
return lang && preprocessorSet.has(lang)
33203320
}
33213321

3322+
const importEsbuild = createCachedImport(() => import('esbuild'))
3323+
33223324
const importLightningCSS = createCachedImport(() => import('lightningcss'))
33233325
async function compileLightningCSS(
33243326
id: string,

packages/vite/src/node/plugins/esbuild.ts

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
import path from 'node:path'
22
import colors from 'picocolors'
33
import type {
4-
Loader,
5-
Message,
6-
TransformOptions,
7-
TransformResult,
8-
} from 'esbuild'
9-
import { transform } from 'esbuild'
4+
EsbuildLoader,
5+
EsbuildMessage,
6+
EsbuildTransformOptions,
7+
EsbuildTransformResult as RawEsbuildTransformResult,
8+
} from 'types/internal/esbuildOptions'
109
import type { RawSourceMap } from '@ampproject/remapping'
1110
import type { InternalModuleFormat, SourceMap } from 'rolldown'
1211
import type { TSConfckParseResult } from 'tsconfck'
@@ -43,7 +42,7 @@ export const defaultEsbuildSupported = {
4342
'import-meta': true,
4443
}
4544

46-
export interface ESBuildOptions extends TransformOptions {
45+
export interface ESBuildOptions extends EsbuildTransformOptions {
4746
include?: string | RegExp | ReadonlyArray<string | RegExp>
4847
exclude?: string | RegExp | ReadonlyArray<string | RegExp>
4948
jsxInject?: string
@@ -53,7 +52,7 @@ export interface ESBuildOptions extends TransformOptions {
5352
minify?: never
5453
}
5554

56-
export type ESBuildTransformResult = Omit<TransformResult, 'map'> & {
55+
export type ESBuildTransformResult = Omit<RawEsbuildTransformResult, 'map'> & {
5756
map: SourceMap
5857
}
5958

@@ -76,10 +75,16 @@ type TSConfigJSON = {
7675
}
7776
type TSCompilerOptions = NonNullable<TSConfigJSON['compilerOptions']>
7877

78+
let esbuild: Promise<typeof import('esbuild')> | undefined
79+
const importEsbuild = () => {
80+
esbuild ||= import('esbuild')
81+
return esbuild
82+
}
83+
7984
export async function transformWithEsbuild(
8085
code: string,
8186
filename: string,
82-
options?: TransformOptions,
87+
options?: EsbuildTransformOptions,
8388
inMap?: object,
8489
config?: ResolvedConfig,
8590
watcher?: FSWatcher,
@@ -98,7 +103,7 @@ export async function transformWithEsbuild(
98103
} else if (ext === 'cts' || ext === 'mts') {
99104
loader = 'ts'
100105
} else {
101-
loader = ext as Loader
106+
loader = ext as EsbuildLoader
102107
}
103108
}
104109

@@ -179,7 +184,7 @@ export async function transformWithEsbuild(
179184
}
180185
}
181186

182-
const resolvedOptions: TransformOptions = {
187+
const resolvedOptions: EsbuildTransformOptions = {
183188
sourcemap: true,
184189
// ensure source file name contains full query
185190
sourcefile: filename,
@@ -198,6 +203,7 @@ export async function transformWithEsbuild(
198203
delete resolvedOptions.jsxInject
199204

200205
try {
206+
const { transform } = await importEsbuild()
201207
const result = await transform(code, resolvedOptions)
202208
let map: SourceMap
203209
if (inMap && resolvedOptions.sourcemap) {
@@ -222,7 +228,7 @@ export async function transformWithEsbuild(
222228
// patch error information
223229
if (e.errors) {
224230
e.frame = ''
225-
e.errors.forEach((m: Message) => {
231+
e.errors.forEach((m: EsbuildMessage) => {
226232
if (
227233
m.text === 'Experimental decorators are not currently enabled' ||
228234
m.text ===
@@ -247,7 +253,7 @@ export function esbuildPlugin(config: ResolvedConfig): Plugin {
247253

248254
// Remove optimization options for dev as we only need to transpile them,
249255
// and for build as the final optimization is in `buildEsbuildPlugin`
250-
const transformOptions: TransformOptions = {
256+
const transformOptions: EsbuildTransformOptions = {
251257
target: 'esnext',
252258
charset: 'utf8',
253259
...esbuildTransformOptions,
@@ -303,7 +309,7 @@ export function esbuildPlugin(config: ResolvedConfig): Plugin {
303309

304310
const rollupToEsbuildFormatMap: Record<
305311
string,
306-
TransformOptions['format'] | undefined
312+
EsbuildTransformOptions['format'] | undefined
307313
> = {
308314
es: 'esm',
309315
cjs: 'cjs',
@@ -381,7 +387,7 @@ export const buildEsbuildPlugin = (): Plugin => {
381387
export function resolveEsbuildTranspileOptions(
382388
config: ResolvedConfig,
383389
format: InternalModuleFormat,
384-
): TransformOptions | null {
390+
): EsbuildTransformOptions | null {
385391
const target = config.build.target
386392
const minify = config.build.minify === 'esbuild'
387393

@@ -395,7 +401,7 @@ export function resolveEsbuildTranspileOptions(
395401
const isEsLibBuild = config.build.lib && format === 'es'
396402
const esbuildOptions = config.esbuild || {}
397403

398-
const options: TransformOptions = {
404+
const options: EsbuildTransformOptions = {
399405
charset: 'utf8',
400406
...esbuildOptions,
401407
loader: 'js',
@@ -467,7 +473,7 @@ export function resolveEsbuildTranspileOptions(
467473
}
468474
}
469475

470-
function prettifyMessage(m: Message, code: string): string {
476+
function prettifyMessage(m: EsbuildMessage, code: string): string {
471477
let res = colors.yellow(m.text)
472478
if (m.location) {
473479
res += `\n` + generateCodeFrame(code, m.location)

packages/vite/src/node/publicUtils.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ export {
1111
DEFAULT_SERVER_MAIN_FIELDS as defaultServerMainFields,
1212
defaultAllowedOrigins,
1313
} from './constants'
14-
export { version as esbuildVersion } from 'esbuild'
14+
// NOTE: export for backward compat
15+
export const esbuildVersion = '0.25.0'
1516
export {
1617
splitVendorChunkPlugin,
1718
splitVendorChunk,
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/* eslint-disable @typescript-eslint/ban-ts-comment */
2+
3+
// @ts-ignore `esbuild` may not be installed
4+
import type esbuild from 'esbuild'
5+
6+
/* eslint-enable @typescript-eslint/ban-ts-comment */
7+
8+
export type EsbuildTarget = string | string[]
9+
10+
export type EsbuildLoader = esbuild.Loader
11+
export type EsbuildTransformOptions = esbuild.TransformOptions
12+
export type EsbuildTransformResult = esbuild.TransformResult
13+
14+
export type EsbuildMessage = esbuild.Message
15+
16+
export type DepsOptimizerEsbuildOptions = Omit<
17+
esbuild.BuildOptions,
18+
| 'bundle'
19+
| 'entryPoints'
20+
| 'external'
21+
| 'write'
22+
| 'watch'
23+
| 'outdir'
24+
| 'outfile'
25+
| 'outbase'
26+
| 'outExtension'
27+
| 'metafile'
28+
>

0 commit comments

Comments
 (0)