Skip to content

Commit 87c5502

Browse files
sapphi-redbluwy
andauthoredNov 13, 2024··
feat: show error when accessing variables not exposed in CJS build (#18649)
Co-authored-by: Bjorn Lu <bjornlu.dev@gmail.com>
1 parent a6f5f5b commit 87c5502

File tree

2 files changed

+65
-4
lines changed

2 files changed

+65
-4
lines changed
 

‎packages/vite/index.cjs

+35-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
const description =
2+
' See https://vite.dev/guide/troubleshooting.html#vite-cjs-node-api-deprecated for more details.'
3+
14
warnCjsUsage()
25

36
// type utils
@@ -17,12 +20,43 @@ const asyncFunctions = [
1720
'formatPostcssSourceMap',
1821
'loadConfigFromFile',
1922
'preprocessCSS',
23+
'createBuilder',
2024
]
2125
asyncFunctions.forEach((name) => {
2226
module.exports[name] = (...args) =>
2327
import('./dist/node/index.js').then((i) => i[name](...args))
2428
})
2529

30+
// variables and sync functions that cannot be used from cjs build
31+
const disallowedVariables = [
32+
// was not exposed in cjs from the beginning
33+
'parseAst',
34+
'parseAstAsync',
35+
'buildErrorMessage',
36+
'sortUserPlugins',
37+
// Environment API related variables that are too big to include in the cjs build
38+
'DevEnvironment',
39+
'BuildEnvironment',
40+
'createIdResolver',
41+
'createRunnableDevEnvironment',
42+
// can be redirected from ESM, but doesn't make sense as it's Environment API related
43+
'fetchModule',
44+
'moduleRunnerTransform',
45+
// can be exposed, but doesn't make sense as it's Environment API related
46+
'createServerHotChannel',
47+
'createServerModuleRunner',
48+
'isRunnableDevEnvironment',
49+
]
50+
disallowedVariables.forEach((name) => {
51+
Object.defineProperty(module.exports, name, {
52+
get() {
53+
throw new Error(
54+
`${name} is not available in the CJS build of Vite.` + description,
55+
)
56+
},
57+
})
58+
})
59+
2660
function warnCjsUsage() {
2761
if (process.env.VITE_CJS_IGNORE_WARNING) return
2862
const logLevelIndex = process.argv.findIndex((arg) =>
@@ -39,9 +73,7 @@ function warnCjsUsage() {
3973
}
4074
const yellow = (str) => `\u001b[33m${str}\u001b[39m`
4175
console.warn(
42-
yellow(
43-
`The CJS build of Vite's Node API is deprecated. See https://vite.dev/guide/troubleshooting.html#vite-cjs-node-api-deprecated for more details.`,
44-
),
76+
yellow("The CJS build of Vite's Node API is deprecated." + description),
4577
)
4678
if (process.env.VITE_CJS_TRACE) {
4779
const e = {}

‎packages/vite/rollup.config.ts

+30-1
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,11 @@ const cjsConfig = defineConfig({
201201
format: 'cjs',
202202
},
203203
external: Object.keys(pkg.dependencies),
204-
plugins: [...createSharedNodePlugins({}), bundleSizeLimit(175)],
204+
plugins: [
205+
...createSharedNodePlugins({}),
206+
bundleSizeLimit(175),
207+
exportCheck(),
208+
],
205209
})
206210

207211
export default defineConfig([
@@ -342,4 +346,29 @@ function bundleSizeLimit(limit: number): Plugin {
342346
}
343347
}
344348

349+
function exportCheck(): Plugin {
350+
return {
351+
name: 'export-check',
352+
async writeBundle() {
353+
// escape import so that it's not bundled while config load
354+
const dynImport = (id: string) => import(id)
355+
356+
const esmNamespace = await dynImport('./dist/node/index.js')
357+
const cjsModuleExports = (await dynImport('./index.cjs')).default
358+
const cjsModuleExportsKeys = new Set(
359+
Object.getOwnPropertyNames(cjsModuleExports),
360+
)
361+
const lackingExports = Object.keys(esmNamespace).filter(
362+
(key) => !cjsModuleExportsKeys.has(key),
363+
)
364+
if (lackingExports.length > 0) {
365+
this.error(
366+
`Exports missing from cjs build: ${lackingExports.join(', ')}.` +
367+
` Please update index.cjs or src/publicUtils.ts.`,
368+
)
369+
}
370+
},
371+
}
372+
}
373+
345374
// #endregion

0 commit comments

Comments
 (0)
Please sign in to comment.