Skip to content

Commit 76fdc27

Browse files
authoredMay 21, 2022
feat!: migrate to ESM (#8178)
1 parent f4d6262 commit 76fdc27

39 files changed

+597
-311
lines changed
 

Diff for: ‎.eslintrc.cjs

+6
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,12 @@ module.exports = defineConfig({
148148
rules: {
149149
'@typescript-eslint/triple-slash-reference': 'off'
150150
}
151+
},
152+
{
153+
files: 'packages/vite/**/*.*',
154+
rules: {
155+
'no-restricted-globals': ['error', 'require', '__dirname', '__filename']
156+
}
151157
}
152158
]
153159
})

Diff for: ‎package.json

+1
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
"prompts": "^2.4.2",
7878
"rimraf": "^3.0.2",
7979
"rollup": "^2.72.1",
80+
"rollup-plugin-esbuild": "^4.9.1",
8081
"semver": "^7.3.7",
8182
"simple-git-hooks": "^2.7.0",
8283
"sirv": "^2.0.2",

Diff for: ‎packages/plugin-vue-jsx/src/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { createHash } from 'crypto'
22
import path from 'path'
33
import type { types } from '@babel/core'
4-
import babel from '@babel/core'
4+
import * as babel from '@babel/core'
55
import jsx from '@vue/babel-plugin-jsx'
66
// @ts-expect-error missing type
77
import importMeta from '@babel/plugin-syntax-import-meta'

Diff for: ‎packages/plugin-vue/src/style.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export async function transformStyle(
5151
}
5252

5353
const map = result.map
54-
? formatPostcssSourceMap(
54+
? await formatPostcssSourceMap(
5555
// version property of result.map is declared as string
5656
// but actually it is a number
5757
result.map as Omit<RawSourceMap, 'version'> as ExistingRawSourceMap,

Diff for: ‎packages/vite/LICENSE.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1648,7 +1648,7 @@ Repository: gulpjs/glob-parent
16481648

16491649
## http-proxy
16501650
License: MIT
1651-
By: Charlie Robbins
1651+
By: Charlie Robbins, jcrugzz <jcrugzz@gmail.com>
16521652
Repository: https://github.com/http-party/node-http-proxy.git
16531653

16541654
> node-http-proxy

Diff for: ‎packages/vite/bin/vite.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
#!/usr/bin/env node
2-
const { performance } = require('perf_hooks')
2+
import { performance } from 'perf_hooks'
33

4-
if (!__dirname.includes('node_modules')) {
4+
if (!import.meta.url.includes('node_modules')) {
55
try {
66
// only available as dev dependency
7-
require('source-map-support').install()
7+
await import('source-map-support').then((r) => r.default.install())
88
} catch (e) {}
99
}
1010

@@ -41,7 +41,7 @@ if (debugIndex > 0) {
4141
}
4242

4343
function start() {
44-
require('../dist/node/cli')
44+
return import('../dist/node/cli.js')
4545
}
4646

4747
if (profileIndex > 0) {
@@ -50,7 +50,7 @@ if (profileIndex > 0) {
5050
if (next && !next.startsWith('-')) {
5151
process.argv.splice(profileIndex, 1)
5252
}
53-
const inspector = require('inspector')
53+
const inspector = await import('inspector').then((r) => r.default)
5454
const session = (global.__vite_profile_session = new inspector.Session())
5555
session.connect()
5656
session.post('Profiler.enable', () => {

Diff for: ‎packages/vite/index.cjs

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/* eslint-disable no-restricted-globals */
2+
3+
// type utils
4+
module.exports.defineConfig = (config) => config
5+
6+
// proxy cjs utils (sync functions)
7+
Object.assign(module.exports, require('./dist/node-cjs/publicUtils.cjs'))
8+
9+
// async functions, can be redirect from ESM build
10+
const asyncFunctions = [
11+
'build',
12+
'createServer',
13+
'preview',
14+
'transformWithEsbuild',
15+
'resolveConfig',
16+
'optimizeDeps',
17+
'formatPostcssSourceMap',
18+
'loadConfigFromFile'
19+
]
20+
asyncFunctions.forEach((name) => {
21+
module.exports[name] = (...args) =>
22+
import('./dist/node/index.js').then((i) => i[name](...args))
23+
})
24+
25+
// some sync functions are marked not supported due to their complexity and uncommon usage
26+
const unsupportedCJS = ['resolvePackageEntry', 'resolvePackageData']
27+
unsupportedCJS.forEach((name) => {
28+
module.exports[name] = () => {
29+
throw new Error(
30+
`"${name}" is not supported in CJS build of Vite 3.\nPlease use ESM or dynamic imports \`const { ${name} } = await import('vite')\`.`
31+
)
32+
}
33+
})

Diff for: ‎packages/vite/package.json

+22-5
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,34 @@
11
{
22
"name": "vite",
33
"version": "3.0.0-alpha.1",
4+
"type": "module",
45
"license": "MIT",
56
"author": "Evan You",
67
"description": "Native-ESM powered web dev build tool",
78
"bin": {
89
"vite": "bin/vite.js"
910
},
10-
"main": "dist/node/index.js",
11-
"types": "dist/node/index.d.ts",
11+
"main": "./dist/node/index.js",
12+
"module": "./dist/node/index.js",
13+
"types": "./dist/node/index.d.ts",
14+
"exports": {
15+
".": {
16+
"types": "./dist/node/index.d.ts",
17+
"import": "./dist/node/index.js",
18+
"require": "./index.cjs"
19+
},
20+
"./client": {
21+
"types": "./client.d.ts"
22+
},
23+
"./terser": {
24+
"require": "./dist/node-cjs/terser.cjs"
25+
}
26+
},
1227
"files": [
1328
"bin",
1429
"dist",
1530
"client.d.ts",
31+
"index.cjs",
1632
"src/client",
1733
"types"
1834
],
@@ -29,12 +45,12 @@
2945
},
3046
"homepage": "https://github.com/vitejs/vite/tree/main/#readme",
3147
"scripts": {
32-
"dev": "rimraf dist && rollup -c -w",
48+
"dev": "rimraf dist && pnpm run build-bundle -w",
3349
"build": "rimraf dist && run-s build-bundle build-types",
34-
"build-bundle": "rollup -c",
50+
"build-bundle": "rollup --config rollup.config.ts --configPlugin esbuild",
3551
"build-types": "run-s build-temp-types patch-types roll-types",
3652
"build-temp-types": "tsc --emitDeclarationOnly --outDir temp/node -p src/node",
37-
"patch-types": "ts-node scripts/patchTypes.ts",
53+
"patch-types": "esno scripts/patchTypes.ts",
3854
"roll-types": "api-extractor run && rimraf temp",
3955
"lint": "eslint --ext .ts src/**",
4056
"format": "prettier --write --parser typescript \"src/**/*.ts\"",
@@ -75,6 +91,7 @@
7591
"dotenv": "^14.3.2",
7692
"dotenv-expand": "^5.1.0",
7793
"es-module-lexer": "^0.10.5",
94+
"esno": "^0.16.3",
7895
"estree-walker": "^2.0.2",
7996
"etag": "^1.8.1",
8097
"fast-glob": "^3.2.11",

Diff for: ‎packages/vite/rollup.config.js renamed to ‎packages/vite/rollup.config.ts

+220-130
Large diffs are not rendered by default.

Diff for: ‎packages/vite/scripts/patchTypes.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1+
import { readFileSync, readdirSync, statSync, writeFileSync } from 'fs'
2+
import { dirname, relative, resolve } from 'path'
3+
import { fileURLToPath } from 'url'
14
import type { ParseResult } from '@babel/parser'
25
import { parse } from '@babel/parser'
36
import type { File } from '@babel/types'
47
import colors from 'picocolors'
5-
import { readdirSync, readFileSync, statSync, writeFileSync } from 'fs'
68
import MagicString from 'magic-string'
7-
import { dirname, relative, resolve } from 'path'
9+
10+
// @ts-ignore
11+
const __dirname = resolve(fileURLToPath(import.meta.url), '..')
812

913
const tempDir = resolve(__dirname, '../temp/node')
1014
const typesDir = resolve(__dirname, '../types')

Diff for: ‎packages/vite/scripts/tsconfig.json

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"extends": "../tsconfig.base.json",
3+
"compilerOptions": {
4+
"module": "esnext"
5+
}
6+
}

Diff for: ‎packages/vite/src/node/__tests__/build.spec.ts

+3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import { resolve } from 'path'
2+
import { fileURLToPath } from 'url'
23
import { describe, expect, test } from 'vitest'
34
import type { LibraryFormats, LibraryOptions } from '../build'
45
import { resolveLibFilename } from '../build'
56

7+
const __dirname = resolve(fileURLToPath(import.meta.url), '..')
8+
69
type FormatsToFileNames = [LibraryFormats, string][]
710
const baseLibOptions: LibraryOptions = {
811
fileName: 'my-lib',

Diff for: ‎packages/vite/src/node/__tests__/config.spec.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { describe, expect, test } from 'vitest'
22
import type { InlineConfig } from '..'
33
import type { UserConfig, UserConfigExport } from '../config'
4-
import { mergeConfig, resolveConfig, resolveEnvPrefix } from '../config'
4+
import { resolveConfig, resolveEnvPrefix } from '../config'
5+
import { mergeConfig } from '../publicUtils'
56

67
describe('mergeConfig', () => {
78
test('handles configs with different alias schemas', () => {

Diff for: ‎packages/vite/src/node/__tests__/plugins/dynamicImportVar/parse.test.ts

+7-5
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
import { resolve } from 'path'
2+
import { fileURLToPath } from 'url'
23
import { describe, expect, it } from 'vitest'
34
import { transformDynamicImport } from '../../../plugins/dynamicImportVars'
45

6+
const __dirname = resolve(fileURLToPath(import.meta.url), '..')
7+
58
async function run(input: string) {
6-
const { glob, rawPattern } = await transformDynamicImport(
7-
input,
8-
resolve(__dirname, 'index.js'),
9-
(id) => id.replace('@', resolve(__dirname, './mods/'))
10-
)
9+
const { glob, rawPattern } =
10+
(await transformDynamicImport(input, resolve(__dirname, 'index.js'), (id) =>
11+
id.replace('@', resolve(__dirname, './mods/'))
12+
)) || {}
1113
return `__variableDynamicImportRuntimeHelper(${glob}, \`${rawPattern}\`)`
1214
}
1315

Diff for: ‎packages/vite/src/node/__tests__/plugins/importGlob/fixture.test.ts

+3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
import { resolve } from 'path'
22
import { promises as fs } from 'fs'
3+
import { fileURLToPath } from 'url'
34
import { describe, expect, it } from 'vitest'
45
import { transformGlobImport } from '../../../plugins/importMetaGlob'
56
import { transformWithEsbuild } from '../../../plugins/esbuild'
67

8+
const __dirname = resolve(fileURLToPath(import.meta.url), '..')
9+
710
describe('fixture', async () => {
811
const resolveId = (id: string) => id
912
const root = resolve(__dirname, '..')

Diff for: ‎packages/vite/src/node/build.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import { loadFallbackPlugin } from './plugins/loadFallback'
4040
import type { PackageData } from './packages'
4141
import { watchPackageDataPlugin } from './packages'
4242
import { ensureWatchPlugin } from './plugins/ensureWatch'
43+
import { VERSION } from './constants'
4344

4445
export interface BuildOptions {
4546
/**
@@ -339,7 +340,7 @@ async function doBuild(
339340

340341
config.logger.info(
341342
colors.cyan(
342-
`vite v${require('vite/package.json').version} ${colors.green(
343+
`vite v${VERSION} ${colors.green(
343344
`building ${ssr ? `SSR bundle ` : ``}for ${config.mode}...`
344345
)}`
345346
)

Diff for: ‎packages/vite/src/node/cli.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import type { BuildOptions } from './build'
55
import type { ServerOptions } from './server'
66
import type { LogLevel } from './logger'
77
import { createLogger } from './logger'
8+
import { VERSION } from './constants'
89
import { resolveConfig } from '.'
910

1011
const cli = cac('vite')
@@ -97,7 +98,7 @@ cli
9798
const info = server.config.logger.info
9899

99100
info(
100-
colors.cyan(`\n vite v${require('vite/package.json').version}`) +
101+
colors.cyan(`\n vite v${VERSION}`) +
101102
colors.green(` dev server running at:\n`),
102103
{
103104
clear: !server.config.logger.hasWarned
@@ -257,6 +258,6 @@ cli
257258
)
258259

259260
cli.help()
260-
cli.version(require('../../package.json').version)
261+
cli.version(VERSION)
261262

262263
cli.parse()

Diff for: ‎packages/vite/src/node/config.ts

+10-117
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import fs from 'fs'
22
import path from 'path'
33
import { parse as parseUrl, pathToFileURL } from 'url'
44
import { performance } from 'perf_hooks'
5+
import { createRequire } from 'module'
56
import colors from 'picocolors'
67
import dotenv from 'dotenv'
78
import dotenvExpand from 'dotenv-expand'
@@ -25,6 +26,9 @@ import {
2526
isExternalUrl,
2627
isObject,
2728
lookupFile,
29+
mergeAlias,
30+
mergeConfig,
31+
normalizeAlias,
2832
normalizePath
2933
} from './utils'
3034
import { resolvePlugins } from './plugins'
@@ -616,118 +620,6 @@ function resolveBaseUrl(
616620
return base
617621
}
618622

619-
function mergeConfigRecursively(
620-
defaults: Record<string, any>,
621-
overrides: Record<string, any>,
622-
rootPath: string
623-
) {
624-
const merged: Record<string, any> = { ...defaults }
625-
for (const key in overrides) {
626-
const value = overrides[key]
627-
if (value == null) {
628-
continue
629-
}
630-
631-
const existing = merged[key]
632-
633-
if (existing == null) {
634-
merged[key] = value
635-
continue
636-
}
637-
638-
// fields that require special handling
639-
if (key === 'alias' && (rootPath === 'resolve' || rootPath === '')) {
640-
merged[key] = mergeAlias(existing, value)
641-
continue
642-
} else if (key === 'assetsInclude' && rootPath === '') {
643-
merged[key] = [].concat(existing, value)
644-
continue
645-
} else if (
646-
key === 'noExternal' &&
647-
rootPath === 'ssr' &&
648-
(existing === true || value === true)
649-
) {
650-
merged[key] = true
651-
continue
652-
}
653-
654-
if (Array.isArray(existing) || Array.isArray(value)) {
655-
merged[key] = [...arraify(existing ?? []), ...arraify(value ?? [])]
656-
continue
657-
}
658-
if (isObject(existing) && isObject(value)) {
659-
merged[key] = mergeConfigRecursively(
660-
existing,
661-
value,
662-
rootPath ? `${rootPath}.${key}` : key
663-
)
664-
continue
665-
}
666-
667-
merged[key] = value
668-
}
669-
return merged
670-
}
671-
672-
export function mergeConfig(
673-
defaults: Record<string, any>,
674-
overrides: Record<string, any>,
675-
isRoot = true
676-
): Record<string, any> {
677-
return mergeConfigRecursively(defaults, overrides, isRoot ? '' : '.')
678-
}
679-
680-
function mergeAlias(
681-
a?: AliasOptions,
682-
b?: AliasOptions
683-
): AliasOptions | undefined {
684-
if (!a) return b
685-
if (!b) return a
686-
if (isObject(a) && isObject(b)) {
687-
return { ...a, ...b }
688-
}
689-
// the order is flipped because the alias is resolved from top-down,
690-
// where the later should have higher priority
691-
return [...normalizeAlias(b), ...normalizeAlias(a)]
692-
}
693-
694-
function normalizeAlias(o: AliasOptions = []): Alias[] {
695-
return Array.isArray(o)
696-
? o.map(normalizeSingleAlias)
697-
: Object.keys(o).map((find) =>
698-
normalizeSingleAlias({
699-
find,
700-
replacement: (o as any)[find]
701-
})
702-
)
703-
}
704-
705-
// https://github.com/vitejs/vite/issues/1363
706-
// work around https://github.com/rollup/plugins/issues/759
707-
function normalizeSingleAlias({
708-
find,
709-
replacement,
710-
customResolver
711-
}: Alias): Alias {
712-
if (
713-
typeof find === 'string' &&
714-
find.endsWith('/') &&
715-
replacement.endsWith('/')
716-
) {
717-
find = find.slice(0, find.length - 1)
718-
replacement = replacement.slice(0, replacement.length - 1)
719-
}
720-
721-
const alias: Alias = {
722-
find,
723-
replacement
724-
}
725-
if (customResolver) {
726-
alias.customResolver = customResolver
727-
}
728-
return alias
729-
}
730-
731623
export function sortUserPlugins(
732624
plugins: (Plugin | Plugin[])[] | undefined
733625
): [Plugin[], Plugin[], Plugin[]] {
@@ -934,25 +826,26 @@ interface NodeModuleWithCompile extends NodeModule {
934826
_compile(code: string, filename: string): any
935827
}
936828

829+
const _require = createRequire(import.meta.url)
937830
async function loadConfigFromBundledFile(
938831
fileName: string,
939832
bundledCode: string
940833
): Promise<UserConfig> {
941834
const extension = path.extname(fileName)
942835
const realFileName = fs.realpathSync(fileName)
943-
const defaultLoader = require.extensions[extension]!
944-
require.extensions[extension] = (module: NodeModule, filename: string) => {
836+
const defaultLoader = _require.extensions[extension]!
837+
_require.extensions[extension] = (module: NodeModule, filename: string) => {
945838
if (filename === realFileName) {
946839
;(module as NodeModuleWithCompile)._compile(bundledCode, filename)
947840
} else {
948841
defaultLoader(module, filename)
949842
}
950843
}
951844
// clear cache in case of server restart
952-
delete require.cache[require.resolve(fileName)]
953-
const raw = require(fileName)
845+
delete _require.cache[_require.resolve(fileName)]
846+
const raw = _require(fileName)
954847
const config = raw.__esModule ? raw.default : raw
955-
require.extensions[extension] = defaultLoader
848+
_require.extensions[extension] = defaultLoader
956849
return config
957850
}
958851

Diff for: ‎packages/vite/src/node/constants.ts

+13-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
import path from 'path'
1+
import path, { resolve } from 'path'
2+
import { fileURLToPath } from 'url'
3+
// @ts-expect-error
4+
import { version } from '../../package.json'
5+
6+
export const VERSION = version as string
27

38
export const DEFAULT_MAIN_FIELDS = [
49
'module',
@@ -46,10 +51,13 @@ export const NULL_BYTE_PLACEHOLDER = `__x00__`
4651

4752
export const CLIENT_PUBLIC_PATH = `/@vite/client`
4853
export const ENV_PUBLIC_PATH = `/@vite/env`
49-
// eslint-disable-next-line node/no-missing-require
50-
export const CLIENT_ENTRY = require.resolve('vite/dist/client/client.mjs')
51-
// eslint-disable-next-line node/no-missing-require
52-
export const ENV_ENTRY = require.resolve('vite/dist/client/env.mjs')
54+
export const VITE_PACKAGE_DIR = resolve(
55+
fileURLToPath(import.meta.url),
56+
'../../..'
57+
)
58+
59+
export const CLIENT_ENTRY = resolve(VITE_PACKAGE_DIR, 'dist/client/client.mjs')
60+
export const ENV_ENTRY = resolve(VITE_PACKAGE_DIR, 'dist/client/env.mjs')
5361
export const CLIENT_DIR = path.dirname(CLIENT_ENTRY)
5462

5563
// ** READ THIS ** before editing `KNOWN_ASSET_TYPES`.

Diff for: ‎packages/vite/src/node/index.ts

+2-8
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,13 @@
11
export * from './config'
2-
export { createServer, searchForWorkspaceRoot } from './server'
2+
export { createServer } from './server'
33
export { preview } from './preview'
44
export { build } from './build'
55
export { optimizeDeps } from './optimizer'
6-
export { send } from './server/send'
7-
export { createLogger } from './logger'
86
export { formatPostcssSourceMap } from './plugins/css'
97
export { transformWithEsbuild } from './plugins/esbuild'
108
export { resolvePackageEntry } from './plugins/resolve'
11-
export {
12-
splitVendorChunkPlugin,
13-
splitVendorChunk
14-
} from './plugins/splitVendorChunk'
159
export { resolvePackageData } from './packages'
16-
export { normalizePath } from './utils'
10+
export * from './publicUtils'
1711

1812
// additional types
1913
export type { CorsOptions, CorsOrigin, CommonServerOptions } from './http'

Diff for: ‎packages/vite/src/node/plugins/css.ts

+10-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import fs from 'fs'
22
import path from 'path'
3+
import { createRequire } from 'module'
34
import glob from 'fast-glob'
45
import postcssrc from 'postcss-load-config'
56
import type {
@@ -888,7 +889,7 @@ async function compileCSS(
888889

889890
const rawPostcssMap = postcssResult.map.toJSON()
890891

891-
const postcssMap = formatPostcssSourceMap(
892+
const postcssMap = await formatPostcssSourceMap(
892893
// version property of rawPostcssMap is declared as string
893894
// but actually it is a number
894895
rawPostcssMap as Omit<RawSourceMap, 'version'> as ExistingRawSourceMap,
@@ -904,10 +905,10 @@ async function compileCSS(
904905
}
905906
}
906907

907-
export function formatPostcssSourceMap(
908+
export async function formatPostcssSourceMap(
908909
rawMap: ExistingRawSourceMap,
909910
file: string
910-
): ExistingRawSourceMap {
911+
): Promise<ExistingRawSourceMap> {
911912
const inputFileDir = path.dirname(file)
912913

913914
const sources = rawMap.sources.map((source) => {
@@ -1278,6 +1279,9 @@ export interface StylePreprocessorResults {
12781279

12791280
const loadedPreprocessors: Partial<Record<PreprocessLang, any>> = {}
12801281

1282+
// TODO: use dynamic import
1283+
const _require = createRequire(import.meta.url)
1284+
12811285
function loadPreprocessor(lang: PreprocessLang.scss, root: string): typeof Sass
12821286
function loadPreprocessor(lang: PreprocessLang.sass, root: string): typeof Sass
12831287
function loadPreprocessor(lang: PreprocessLang.less, root: string): typeof Less
@@ -1292,9 +1296,9 @@ function loadPreprocessor(lang: PreprocessLang, root: string): any {
12921296
try {
12931297
// Search for the preprocessor in the root directory first, and fall back
12941298
// to the default require paths.
1295-
const fallbackPaths = require.resolve.paths?.(lang) || []
1296-
const resolved = require.resolve(lang, { paths: [root, ...fallbackPaths] })
1297-
return (loadedPreprocessors[lang] = require(resolved))
1299+
const fallbackPaths = _require.resolve.paths?.(lang) || []
1300+
const resolved = _require.resolve(lang, { paths: [root, ...fallbackPaths] })
1301+
return (loadedPreprocessors[lang] = _require(resolved))
12981302
} catch (e) {
12991303
if (e.code === 'MODULE_NOT_FOUND') {
13001304
throw new Error(

Diff for: ‎packages/vite/src/node/plugins/importMetaGlob.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { isAbsolute, posix } from 'path'
2-
import { isMatch, scan } from 'micromatch'
2+
import micromatch from 'micromatch'
33
import { stripLiteral } from 'strip-literal'
44
import type {
55
ArrayExpression,
@@ -20,6 +20,8 @@ import type { ResolvedConfig } from '../config'
2020
import { normalizePath, slash } from '../utils'
2121
import { isCSSRequest } from './css'
2222

23+
const { isMatch, scan } = micromatch
24+
2325
export interface ParsedImportGlob {
2426
match: RegExpMatchArray
2527
index: number

Diff for: ‎packages/vite/src/node/plugins/splitVendorChunk.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,12 @@ import type {
66
} from 'rollup'
77
import type { UserConfig } from '../../node'
88
import type { Plugin } from '../plugin'
9-
import { isCSSRequest } from './css'
9+
10+
// This file will be built for both ESM and CJS. Avoid relying on other modules as possible.
11+
const cssLangs = `\\.(css|less|sass|scss|styl|stylus|pcss|postcss)($|\\?)`
12+
const cssLangRE = new RegExp(cssLangs)
13+
export const isCSSRequest = (request: string): boolean =>
14+
cssLangRE.test(request)
1015

1116
// Use splitVendorChunkPlugin() to get the same manualChunks strategy as Vite 2.7
1217
// We don't recommend using this strategy as a general solution moving forward

Diff for: ‎packages/vite/src/node/plugins/ssrRequireHook.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { createRequire } from 'module'
12
import MagicString from 'magic-string'
23
import type { ResolvedConfig } from '..'
34
import type { Plugin } from '../plugin'
@@ -49,6 +50,7 @@ type NodeResolveFilename = (
4950

5051
/** Respect the `resolve.dedupe` option in production SSR. */
5152
function dedupeRequire(dedupe: string[]) {
53+
// eslint-disable-next-line no-restricted-globals
5254
const Module = require('module') as { _resolveFilename: NodeResolveFilename }
5355
const resolveFilename = Module._resolveFilename
5456
Module._resolveFilename = function (request, parent, isMain, options) {
@@ -64,10 +66,11 @@ function dedupeRequire(dedupe: string[]) {
6466
}
6567
}
6668

69+
const _require = createRequire(import.meta.url)
6770
export function hookNodeResolve(
6871
getResolver: (resolveFilename: NodeResolveFilename) => NodeResolveFilename
6972
): () => void {
70-
const Module = require('module') as { _resolveFilename: NodeResolveFilename }
73+
const Module = _require('module') as { _resolveFilename: NodeResolveFilename }
7174
const prevResolver = Module._resolveFilename
7275
Module._resolveFilename = getResolver(prevResolver)
7376
return () => {

Diff for: ‎packages/vite/src/node/plugins/terser.ts

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,25 @@
1+
import { dirname } from 'path'
2+
import { fileURLToPath } from 'url'
13
import { Worker } from 'okie'
24
import type { Terser } from 'types/terser'
35
import type { Plugin } from '../plugin'
46
import type { ResolvedConfig } from '..'
57

8+
// TODO: use import()
9+
const _dirname = dirname(fileURLToPath(import.meta.url))
10+
611
export function terserPlugin(config: ResolvedConfig): Plugin {
712
const makeWorker = () =>
813
new Worker(
914
async (basedir: string, code: string, options: Terser.MinifyOptions) => {
1015
// when vite is linked, the worker thread won't share the same resolve
1116
// root with vite itself, so we have to pass in the basedir and resolve
1217
// terser first.
13-
// eslint-disable-next-line node/no-restricted-require
18+
// eslint-disable-next-line node/no-restricted-require, no-restricted-globals
1419
const terserPath = require.resolve('terser', {
1520
paths: [basedir]
1621
})
22+
// eslint-disable-next-line no-restricted-globals
1723
return require(terserPath).minify(code, options) as Terser.MinifyOutput
1824
}
1925
)
@@ -44,7 +50,7 @@ export function terserPlugin(config: ResolvedConfig): Plugin {
4450
// Lazy load worker.
4551
worker ||= makeWorker()
4652

47-
const res = await worker.run(__dirname, code, {
53+
const res = await worker.run(_dirname, code, {
4854
safari10: true,
4955
...config.build.terserOptions,
5056
sourceMap: !!outputOptions.sourcemap,

Diff for: ‎packages/vite/src/node/publicUtils.ts

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/**
2+
* Exported sync utils should go here.
3+
* This file will be bundled to ESM and CJS and redirected by ../index.cjs
4+
* Please control the side-effects by checking the ./dist/node-cjs/publicUtils.cjs bundle
5+
*/
6+
export {
7+
splitVendorChunkPlugin,
8+
splitVendorChunk
9+
} from './plugins/splitVendorChunk'
10+
export { normalizePath, mergeConfig, mergeAlias } from './utils'
11+
export { send } from './server/send'
12+
export { createLogger } from './logger'
13+
export { searchForWorkspaceRoot } from './server/searchRoot'

Diff for: ‎packages/vite/src/node/server/__tests__/search-root.spec.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
import { resolve } from 'path'
1+
import { dirname, resolve } from 'path'
2+
import { fileURLToPath } from 'url'
23
import { describe, expect, test } from 'vitest'
34
import { searchForWorkspaceRoot } from '../searchRoot'
45

6+
const __dirname = dirname(fileURLToPath(import.meta.url))
7+
58
describe('searchForWorkspaceRoot', () => {
69
test('lerna', () => {
710
const resolved = searchForWorkspaceRoot(

Diff for: ‎packages/vite/src/node/server/index.ts

+7-2
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,13 @@ import type { SourceMap } from 'rollup'
1414
import type { CommonServerOptions } from '../http'
1515
import { httpServerStart, resolveHttpServer, resolveHttpsConfig } from '../http'
1616
import type { InlineConfig, ResolvedConfig } from '../config'
17-
import { mergeConfig, resolveConfig } from '../config'
18-
import { isParentDirectory, normalizePath, resolveHostname } from '../utils'
17+
import { resolveConfig } from '../config'
18+
import {
19+
isParentDirectory,
20+
mergeConfig,
21+
normalizePath,
22+
resolveHostname
23+
} from '../utils'
1924
import { ssrLoadModule } from '../ssr/ssrModuleLoader'
2025
import { resolveSSRExternal } from '../ssr/ssrExternal'
2126
import {

Diff for: ‎packages/vite/src/node/server/middlewares/static.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import type { ServerResponse } from 'http'
33
import type { Options } from 'sirv'
44
import sirv from 'sirv'
55
import type { Connect } from 'types/connect'
6-
import { isMatch } from 'micromatch'
6+
import micromatch from 'micromatch'
77
import type { ViteDevServer } from '../..'
88
import { FS_PREFIX } from '../../constants'
99
import {
@@ -18,6 +18,8 @@ import {
1818
slash
1919
} from '../../utils'
2020

21+
const { isMatch } = micromatch
22+
2123
const sirvOptions: Options = {
2224
dev: true,
2325
etag: true,

Diff for: ‎packages/vite/src/node/server/openBrowser.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@
88
*
99
*/
1010

11-
import path from 'path'
11+
import { join } from 'path'
1212
import { execSync } from 'child_process'
1313
import open from 'open'
1414
import spawn from 'cross-spawn'
1515
import colors from 'picocolors'
1616
import type { Logger } from '../logger'
17+
import { VITE_PACKAGE_DIR } from '../constants'
1718

1819
// https://github.com/sindresorhus/open#app
1920
const OSX_CHROME = 'google chrome'
@@ -72,7 +73,7 @@ function startBrowserProcess(browser: string | undefined, url: string) {
7273
// on OS X Google Chrome with AppleScript
7374
execSync('ps cax | grep "Google Chrome"')
7475
execSync('osascript openChrome.applescript "' + encodeURI(url) + '"', {
75-
cwd: path.dirname(require.resolve('vite/bin/openChrome.applescript')),
76+
cwd: join(VITE_PACKAGE_DIR, 'bin'),
7677
stdio: 'ignore'
7778
})
7879
return true

Diff for: ‎packages/vite/src/node/server/pluginContainer.ts

+8-1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ SOFTWARE.
3232
import fs from 'fs'
3333
import { join, resolve } from 'path'
3434
import { performance } from 'perf_hooks'
35+
import { createRequire } from 'module'
3536
import type {
3637
EmittedFile,
3738
InputOptions,
@@ -151,8 +152,14 @@ export async function createPluginContainer(
151152

152153
const watchFiles = new Set<string>()
153154

155+
// TODO: use import()
156+
const _require = createRequire(import.meta.url)
157+
154158
// get rollup version
155-
const rollupPkgPath = resolve(require.resolve('rollup'), '../../package.json')
159+
const rollupPkgPath = resolve(
160+
_require.resolve('rollup'),
161+
'../../package.json'
162+
)
156163
const minimalContext: MinimalPluginContext = {
157164
meta: {
158165
rollupVersion: JSON.parse(fs.readFileSync(rollupPkgPath, 'utf-8'))

Diff for: ‎packages/vite/src/node/ssr/__tests__/ssrModuleLoader.spec.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
import { resolve } from 'path'
2+
import { fileURLToPath } from 'url'
23
import { expect, test, vi } from 'vitest'
34
import { createServer } from '../../index'
45

5-
const badjs = resolve(__dirname, './fixtures/ssrModuleLoader-bad.js')
6+
const __filename = fileURLToPath(import.meta.url)
7+
const badjs = resolve(__filename, '../fixtures/ssrModuleLoader-bad.js')
68
const THROW_MESSAGE = 'it is an expected error'
79

810
test('always throw error when evaluating an wrong SSR module', async () => {
911
const viteServer = await createServer()
1012
const spy = vi.spyOn(console, 'error').mockImplementation(() => {})
1113
const expectedErrors = []
12-
for (const i of [0, 1]) {
14+
for (const _ of [0, 1]) {
1315
try {
1416
await viteServer.ssrLoadModule(badjs)
1517
} catch (e) {

Diff for: ‎packages/vite/src/node/ssr/ssrExternal.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import fs from 'fs'
22
import path from 'path'
3+
import { createRequire } from 'module'
34
import { createFilter } from '@rollup/pluginutils'
45
import type { InternalResolveOptions } from '../plugins/resolve'
56
import { tryNodeResolve } from '../plugins/resolve'
@@ -82,6 +83,9 @@ export function resolveSSRExternal(
8283
const CJS_CONTENT_RE =
8384
/\bmodule\.exports\b|\bexports[.\[]|\brequire\s*\(|\bObject\.(defineProperty|defineProperties|assign)\s*\(\s*exports\b/
8485

86+
// TODO: use import()
87+
const _require = createRequire(import.meta.url)
88+
8589
// do we need to do this ahead of time or could we do it lazily?
8690
function collectExternals(
8791
root: string,
@@ -116,6 +120,7 @@ function collectExternals(
116120

117121
let esmEntry: string | undefined
118122
let requireEntry: string
123+
119124
try {
120125
esmEntry = tryNodeResolve(
121126
id,
@@ -127,7 +132,7 @@ function collectExternals(
127132
)?.id
128133
// normalizePath required for windows. tryNodeResolve uses normalizePath
129134
// which returns with '/', require.resolve returns with '\\'
130-
requireEntry = normalizePath(require.resolve(id, { paths: [root] }))
135+
requireEntry = normalizePath(_require.resolve(id, { paths: [root] }))
131136
} catch (e) {
132137
try {
133138
// no main entry, but deep imports may be allowed

Diff for: ‎packages/vite/src/node/tsconfig.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"compilerOptions": {
66
"target": "ES2020",
77
"outDir": "../../dist/node",
8-
"module": "CommonJS",
8+
"module": "ESNext",
99
"lib": ["ESNext", "DOM"],
1010
"sourceMap": true
1111
}

Diff for: ‎packages/vite/src/node/utils.ts

+120-3
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,15 @@ import path from 'path'
44
import { createHash } from 'crypto'
55
import { promisify } from 'util'
66
import { URL, URLSearchParams, pathToFileURL } from 'url'
7-
import { builtinModules } from 'module'
7+
import { builtinModules, createRequire } from 'module'
88
import { performance } from 'perf_hooks'
99
import resolve from 'resolve'
1010
import type { FSWatcher } from 'chokidar'
1111
import remapping from '@ampproject/remapping'
1212
import type { DecodedSourceMap, RawSourceMap } from '@ampproject/remapping'
1313
import colors from 'picocolors'
1414
import debug from 'debug'
15+
import type { Alias, AliasOptions } from 'types/alias'
1516
import {
1617
CLIENT_ENTRY,
1718
CLIENT_PUBLIC_PATH,
@@ -70,8 +71,12 @@ export const bareImportRE = /^[\w@](?!.*:\/\/)/
7071
export const deepImportRE = /^([^@][^/]*)\/|^(@[^/]+\/[^/]+)\//
7172

7273
export let isRunningWithYarnPnp: boolean
74+
75+
// TODO: use import()
76+
const _require = createRequire(import.meta.url)
77+
7378
try {
74-
isRunningWithYarnPnp = Boolean(require('pnpapi'))
79+
isRunningWithYarnPnp = Boolean(_require('pnpapi'))
7580
} catch {}
7681

7782
const ssrExtensions = ['.js', '.cjs', '.json', '.node']
@@ -775,7 +780,7 @@ export const usingDynamicImport = typeof jest === 'undefined'
775780
*/
776781
export const dynamicImport = usingDynamicImport
777782
? new Function('file', 'return import(file)')
778-
: require
783+
: _require
779784

780785
export function parseRequest(id: string): Record<string, string> | null {
781786
const [_, search] = id.split(requestQuerySplitRE, 2)
@@ -832,3 +837,115 @@ function gracefulRename(
832837
export function emptyCssComments(raw: string) {
833838
return raw.replace(multilineCommentsRE, (s) => ' '.repeat(s.length))
834839
}
840+
841+
function mergeConfigRecursively(
842+
defaults: Record<string, any>,
843+
overrides: Record<string, any>,
844+
rootPath: string
845+
) {
846+
const merged: Record<string, any> = { ...defaults }
847+
for (const key in overrides) {
848+
const value = overrides[key]
849+
if (value == null) {
850+
continue
851+
}
852+
853+
const existing = merged[key]
854+
855+
if (existing == null) {
856+
merged[key] = value
857+
continue
858+
}
859+
860+
// fields that require special handling
861+
if (key === 'alias' && (rootPath === 'resolve' || rootPath === '')) {
862+
merged[key] = mergeAlias(existing, value)
863+
continue
864+
} else if (key === 'assetsInclude' && rootPath === '') {
865+
merged[key] = [].concat(existing, value)
866+
continue
867+
} else if (
868+
key === 'noExternal' &&
869+
rootPath === 'ssr' &&
870+
(existing === true || value === true)
871+
) {
872+
merged[key] = true
873+
continue
874+
}
875+
876+
if (Array.isArray(existing) || Array.isArray(value)) {
877+
merged[key] = [...arraify(existing ?? []), ...arraify(value ?? [])]
878+
continue
879+
}
880+
if (isObject(existing) && isObject(value)) {
881+
merged[key] = mergeConfigRecursively(
882+
existing,
883+
value,
884+
rootPath ? `${rootPath}.${key}` : key
885+
)
886+
continue
887+
}
888+
889+
merged[key] = value
890+
}
891+
return merged
892+
}
893+
894+
export function mergeConfig(
895+
defaults: Record<string, any>,
896+
overrides: Record<string, any>,
897+
isRoot = true
898+
): Record<string, any> {
899+
return mergeConfigRecursively(defaults, overrides, isRoot ? '' : '.')
900+
}
901+
902+
export function mergeAlias(
903+
a?: AliasOptions,
904+
b?: AliasOptions
905+
): AliasOptions | undefined {
906+
if (!a) return b
907+
if (!b) return a
908+
if (isObject(a) && isObject(b)) {
909+
return { ...a, ...b }
910+
}
911+
// the order is flipped because the alias is resolved from top-down,
912+
// where the later should have higher priority
913+
return [...normalizeAlias(b), ...normalizeAlias(a)]
914+
}
915+
916+
export function normalizeAlias(o: AliasOptions = []): Alias[] {
917+
return Array.isArray(o)
918+
? o.map(normalizeSingleAlias)
919+
: Object.keys(o).map((find) =>
920+
normalizeSingleAlias({
921+
find,
922+
replacement: (o as any)[find]
923+
})
924+
)
925+
}
926+
927+
// https://github.com/vitejs/vite/issues/1363
928+
// work around https://github.com/rollup/plugins/issues/759
929+
function normalizeSingleAlias({
930+
find,
931+
replacement,
932+
customResolver
933+
}: Alias): Alias {
934+
if (
935+
typeof find === 'string' &&
936+
find.endsWith('/') &&
937+
replacement.endsWith('/')
938+
) {
939+
find = find.slice(0, find.length - 1)
940+
replacement = replacement.slice(0, replacement.length - 1)
941+
}
942+
943+
const alias: Alias = {
944+
find,
945+
replacement
946+
}
947+
if (customResolver) {
948+
alias.customResolver = customResolver
949+
}
950+
return alias
951+
}

Diff for: ‎packages/vite/tsconfig.base.json

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{
22
"compilerOptions": {
33
"target": "ES2020",
4+
"module": "ESNext",
45
"moduleResolution": "node",
56
"strict": true,
67
"declaration": true,

Diff for: ‎playground/vitestSetup.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ export async function startDefaultServe() {
161161
let config: InlineConfig | undefined
162162
if (fs.existsSync(testCustomConfig)) {
163163
// test has custom server configuration.
164-
config = require(testCustomConfig)
164+
config = await import(testCustomConfig).then((r) => r.default)
165165
}
166166

167167
const options: InlineConfig = {

Diff for: ‎playground/vue-sourcemap/__tests__/serve.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ describe.runIf(isServe)('serve:vue-sourcemap', () => {
1515
return text
1616
}
1717
}
18-
throw new Error('Not found')
18+
throw new Error('Style not found: ' + content)
1919
}
2020

2121
test('js', async () => {

Diff for: ‎pnpm-lock.yaml

+47
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)
Please sign in to comment.