diff --git a/packages/vite/index.cjs b/packages/vite/index.cjs index 55cff43d29e4b7..70515aa90c7a8d 100644 --- a/packages/vite/index.cjs +++ b/packages/vite/index.cjs @@ -1,3 +1,6 @@ +const description = + ' See https://vite.dev/guide/troubleshooting.html#vite-cjs-node-api-deprecated for more details.' + warnCjsUsage() // type utils @@ -17,12 +20,43 @@ const asyncFunctions = [ 'formatPostcssSourceMap', 'loadConfigFromFile', 'preprocessCSS', + 'createBuilder', ] asyncFunctions.forEach((name) => { module.exports[name] = (...args) => import('./dist/node/index.js').then((i) => i[name](...args)) }) +// variables and sync functions that cannot be used from cjs build +const disallowedVariables = [ + // was not exposed in cjs from the beginning + 'parseAst', + 'parseAstAsync', + 'buildErrorMessage', + 'sortUserPlugins', + // Environment API related variables that are too big to include in the cjs build + 'DevEnvironment', + 'BuildEnvironment', + 'createIdResolver', + 'createRunnableDevEnvironment', + // can be redirected from ESM, but doesn't make sense as it's Environment API related + 'fetchModule', + 'moduleRunnerTransform', + // can be exposed, but doesn't make sense as it's Environment API related + 'createServerHotChannel', + 'createServerModuleRunner', + 'isRunnableDevEnvironment', +] +disallowedVariables.forEach((name) => { + Object.defineProperty(module.exports, name, { + get() { + throw new Error( + `${name} is not available in the CJS build of Vite.` + description, + ) + }, + }) +}) + function warnCjsUsage() { if (process.env.VITE_CJS_IGNORE_WARNING) return const logLevelIndex = process.argv.findIndex((arg) => @@ -39,9 +73,7 @@ function warnCjsUsage() { } const yellow = (str) => `\u001b[33m${str}\u001b[39m` console.warn( - yellow( - `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.`, - ), + yellow("The CJS build of Vite's Node API is deprecated." + description), ) if (process.env.VITE_CJS_TRACE) { const e = {} diff --git a/packages/vite/rollup.config.ts b/packages/vite/rollup.config.ts index 59d569bfc8f4d0..a2670e5871e3e7 100644 --- a/packages/vite/rollup.config.ts +++ b/packages/vite/rollup.config.ts @@ -201,7 +201,11 @@ const cjsConfig = defineConfig({ format: 'cjs', }, external: Object.keys(pkg.dependencies), - plugins: [...createSharedNodePlugins({}), bundleSizeLimit(175)], + plugins: [ + ...createSharedNodePlugins({}), + bundleSizeLimit(175), + exportCheck(), + ], }) export default defineConfig([ @@ -342,4 +346,29 @@ function bundleSizeLimit(limit: number): Plugin { } } +function exportCheck(): Plugin { + return { + name: 'export-check', + async writeBundle() { + // escape import so that it's not bundled while config load + const dynImport = (id: string) => import(id) + + const esmNamespace = await dynImport('./dist/node/index.js') + const cjsModuleExports = (await dynImport('./index.cjs')).default + const cjsModuleExportsKeys = new Set( + Object.getOwnPropertyNames(cjsModuleExports), + ) + const lackingExports = Object.keys(esmNamespace).filter( + (key) => !cjsModuleExportsKeys.has(key), + ) + if (lackingExports.length > 0) { + this.error( + `Exports missing from cjs build: ${lackingExports.join(', ')}.` + + ` Please update index.cjs or src/publicUtils.ts.`, + ) + } + }, + } +} + // #endregion