TS/JS打包后報(bào)Uncaught?ReferenceError:?require?is?not?defined問(wèn)題解決辦法
前言
TS/JS項(xiàng)目開(kāi)發(fā)環(huán)境運(yùn)行正常,打包部署到瀏覽器后控制臺(tái)拋出Uncaught ReferenceError: require is not defined,是前端跨環(huán)境開(kāi)發(fā)中最典型的模塊規(guī)范兼容錯(cuò)誤。核心原因是代碼中殘留了Node.js專(zhuān)屬的CommonJS模塊語(yǔ)法(require/module.exports),而瀏覽器原生環(huán)境并不支持該語(yǔ)法,打包工具未完成CommonJS到瀏覽器可識(shí)別的ES模塊/全局變量的轉(zhuǎn)換,導(dǎo)致執(zhí)行時(shí)無(wú)法找到require方法。
本文從錯(cuò)誤本質(zhì)、模塊規(guī)范差異出發(fā),梳理該錯(cuò)誤的6個(gè)高頻場(chǎng)景(按出現(xiàn)概率排序),覆蓋原生代碼、TS配置、Webpack/Vite/Rollup打包配置、第三方依賴(lài)等所有誘因,提供分工具的可落地配置方案和通用排查流程,同時(shí)給出TS/JS+主流打包工具的兼容配置模板,徹底解決瀏覽器端require is not defined問(wèn)題。

一、核心認(rèn)知:為什么會(huì)報(bào)require is not defined?
排查前先明確模塊規(guī)范差異和錯(cuò)誤本質(zhì),這是解決問(wèn)題的關(guān)鍵——require并非JS原生語(yǔ)法,而是Node.js為實(shí)現(xiàn)CommonJS模塊規(guī)范新增的方法,瀏覽器無(wú)此內(nèi)置API,代碼中出現(xiàn)未被轉(zhuǎn)換的require就會(huì)直接報(bào)錯(cuò)。
1.1 兩大核心模塊規(guī)范的環(huán)境差異
前端開(kāi)發(fā)中主要用到**CommonJS(CJS)和ES模塊(ESM)**兩種規(guī)范,二者的運(yùn)行環(huán)境、語(yǔ)法完全不同,這是錯(cuò)誤產(chǎn)生的底層原因:
| 模塊規(guī)范 | 核心語(yǔ)法 | 運(yùn)行環(huán)境 | 瀏覽器原生支持 | 打包工具處理方式 |
|---|---|---|---|---|
| CommonJS | 導(dǎo)入require('xxx')、導(dǎo)出module.exports/exports | Node.js端(默認(rèn)) | ? 完全不支持 | 需轉(zhuǎn)換為ESM/瀏覽器全局變量 |
| ES模塊 | 導(dǎo)入import xxx from 'xxx'、導(dǎo)出export default/export | Node.js(需配置)+ 瀏覽器 | ? 現(xiàn)代瀏覽器原生支持 | 可直接使用,或打包為兼容語(yǔ)法 |
1.2 錯(cuò)誤的3個(gè)核心根源
所有require is not defined錯(cuò)誤,本質(zhì)都是代碼中存在未被打包工具轉(zhuǎn)換的CommonJS語(yǔ)法,誘因分為三類(lèi),無(wú)其他例外:
- 手寫(xiě)代碼混用CommonJS語(yǔ)法:在TS/JS中直接寫(xiě)
require/module.exports,打包工具未配置轉(zhuǎn)換規(guī)則; - 編譯/打包配置錯(cuò)誤:TS編譯后生成CommonJS代碼、打包工具未開(kāi)啟CommonJS轉(zhuǎn)ES模塊功能;
- 第三方依賴(lài)/打包產(chǎn)物殘留CJS語(yǔ)法:老版本依賴(lài)內(nèi)部用CommonJS編寫(xiě)、打包工具未處理第三方依賴(lài)的CJS語(yǔ)法,或直接運(yùn)行未打包的Node端代碼到瀏覽器。
1.3 快速判斷錯(cuò)誤類(lèi)型(按排查優(yōu)先級(jí))
根據(jù)報(bào)錯(cuò)位置和代碼場(chǎng)景,可快速定位排查方向,避免盲目修改:
- 報(bào)錯(cuò)指向自己的代碼:手寫(xiě)了
require/TS配置錯(cuò)誤導(dǎo)致編譯出require; - 報(bào)錯(cuò)指向打包后的vendor.js/第三方依賴(lài):第三方依賴(lài)為CJS語(yǔ)法,打包工具未處理;
- 直接運(yùn)行TS/JS文件報(bào)錯(cuò):未經(jīng)過(guò)打包工具處理,直接將Node端代碼放到瀏覽器運(yùn)行;
- 僅生產(chǎn)打包報(bào)錯(cuò)/開(kāi)發(fā)正常:打包工具的開(kāi)發(fā)/生產(chǎn)配置不一致,生產(chǎn)環(huán)境未開(kāi)啟CJS轉(zhuǎn)換。
二、最高頻6大場(chǎng)景:原因+錯(cuò)誤示例+可落地解決方案
以下按實(shí)際開(kāi)發(fā)中出現(xiàn)概率從高到低排序,覆蓋所有require is not defined的觸發(fā)場(chǎng)景,每個(gè)場(chǎng)景均提供錯(cuò)誤表現(xiàn)、錯(cuò)誤示例、核心原因、針對(duì)性解決方案,適配Webpack/Vite/Rollup/純TS編譯等所有項(xiàng)目類(lèi)型。
場(chǎng)景1:代碼中直接使用require/module.exports(最高頻,占比40%)
錯(cuò)誤表現(xiàn)
報(bào)錯(cuò)指向自己的業(yè)務(wù)代碼,如Uncaught ReferenceError: require is not defined at index.js:10,對(duì)應(yīng)行是手寫(xiě)的require。
錯(cuò)誤示例
// JS/TS中直接使用CommonJS語(yǔ)法(瀏覽器不支持)
// 錯(cuò)誤1:導(dǎo)入用require
const axios = require('axios')
const utils = require('./utils')
// 錯(cuò)誤2:導(dǎo)出用module.exports/exports
module.exports = { add: (a,b) => a+b }
exports.get = (id) => ({ id: id })
// 錯(cuò)誤3:TS中混用require和import(編譯后殘留require)
import Vue from 'vue'
const Router = require('vue-router')核心原因
開(kāi)發(fā)者習(xí)慣了Node.js的CommonJS語(yǔ)法,在瀏覽器端代碼中直接手寫(xiě)require/module.exports,打包工具默認(rèn)未對(duì)業(yè)務(wù)代碼的CJS語(yǔ)法做全量轉(zhuǎn)換,導(dǎo)致打包后殘留該語(yǔ)法。
解決方案
徹底替換為瀏覽器原生支持的ES模塊語(yǔ)法,這是最根本的解決方法,TS/JS通用,示例:
// 正確1:導(dǎo)入用import
import axios from 'axios'
import utils from './utils'
// 按需導(dǎo)入
import { getToken } from './utils/token'
// 正確2:導(dǎo)出用export default/export
// 默認(rèn)導(dǎo)出
export default { add: (a,b) => a+b }
// 按需導(dǎo)出
export const get = (id) => ({ id: id })
// 正確3:TS中統(tǒng)一使用ES模塊,不混用
import Vue from 'vue'
import Router from 'vue-router'注意:若需動(dòng)態(tài)導(dǎo)入模塊,使用ES模塊的import()函數(shù)(瀏覽器/打包工具均支持),替代Node.js的動(dòng)態(tài)require:
// 正確:ES模塊動(dòng)態(tài)導(dǎo)入
const loadModule = async () => {
const utils = await import('./utils')
utils.getToken()
}
// 錯(cuò)誤:Node.js動(dòng)態(tài)require(瀏覽器不支持)
// const utils = require(`./utils/${name}`)場(chǎng)景2:TS配置錯(cuò)誤,編譯后生成CommonJS的require(TS項(xiàng)目專(zhuān)屬,占比25%)
錯(cuò)誤表現(xiàn)
TS項(xiàng)目中未手寫(xiě)任何require,但打包/運(yùn)行后仍報(bào)require is not defined,報(bào)錯(cuò)代碼是TS編譯后的JS文件,包含require/module.exports。
核心原因
TS的編譯配置文件tsconfig.json中,module字段默認(rèn)值為CommonJS,TS編譯器(tsc)會(huì)將ES模塊的import/export編譯為Node.js的require/module.exports,生成的JS文件直接在瀏覽器運(yùn)行就會(huì)報(bào)錯(cuò)。
解決方案
修改tsconfig.json的模塊編譯配置,讓TS編譯后生成瀏覽器/打包工具可識(shí)別的ES模塊語(yǔ)法,核心修改module和moduleResolution字段,完整關(guān)鍵配置:
// tsconfig.json
{
"compilerOptions": {
"target": "ESNext", // 編譯為最新ES語(yǔ)法,可根據(jù)項(xiàng)目需求改為ES6/ES2020
"module": "ESNext", // 核心:編譯為ES模塊,避免生成require
"moduleResolution": "Bundler", // 模塊解析策略,適配Webpack/Vite/Rollup
// "moduleResolution": "NodeNext", // 兼容老版本打包工具,二選一
"esModuleInterop": true, // 兼容CommonJS模塊的ES模塊導(dǎo)入
"outDir": "./dist", // 編譯輸出目錄
"rootDir": "./src", // 源碼根目錄
"strict": true // 嚴(yán)格模式(可選,根據(jù)項(xiàng)目需求)
},
"include": ["./src/**/*"], // 要編譯的文件
"exclude": ["node_modules", "dist"] // 排除的文件
}關(guān)鍵說(shuō)明:
module: "ESNext":讓TS編譯后保留import/export,不轉(zhuǎn)換為require;moduleResolution: "Bundler":是TS 5.0+的新特性,專(zhuān)門(mén)適配前端打包工具,解析規(guī)則更友好;- 若使用低版本TS,將
moduleResolution改為NodeNext,效果一致。
場(chǎng)景3:Vite項(xiàng)目未配置CommonJS依賴(lài)轉(zhuǎn)換(Vite專(zhuān)屬,高頻)
錯(cuò)誤表現(xiàn)
Vite項(xiàng)目開(kāi)發(fā)正常,打包后報(bào)require is not defined,報(bào)錯(cuò)指向node_modules中的第三方依賴(lài)(如老版本的echarts、jquery)。
核心原因
Vite天生基于ES模塊開(kāi)發(fā),對(duì)CommonJS語(yǔ)法的第三方依賴(lài)支持不佳,開(kāi)發(fā)環(huán)境中Vite會(huì)自動(dòng)對(duì)CJS依賴(lài)做臨時(shí)轉(zhuǎn)換,但生產(chǎn)打包時(shí)若未顯式配置,會(huì)殘留require語(yǔ)法,導(dǎo)致瀏覽器報(bào)錯(cuò)。
解決方案
在vite.config.js/ts中配置CommonJS依賴(lài)轉(zhuǎn)換規(guī)則,通過(guò)build.commonjsOptions強(qiáng)制Vite處理CJS語(yǔ)法的依賴(lài),同時(shí)配置optimizeDeps預(yù)構(gòu)建CJS依賴(lài),完整配置:
// vite.config.js/ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue' // Vue項(xiàng)目可選,根據(jù)項(xiàng)目調(diào)整
import path from 'path'
export default defineConfig({
plugins: [vue()],
resolve: { alias: { '@': path.resolve(__dirname, 'src') } },
// 核心1:預(yù)構(gòu)建CommonJS依賴(lài),轉(zhuǎn)換為ES模塊
optimizeDeps: {
include: ['echarts', 'jquery'], // 填入你的CJS語(yǔ)法第三方依賴(lài)包名
esbuildOptions: {
format: 'esm' // 預(yù)構(gòu)建為ES模塊
}
},
// 核心2:生產(chǎn)打包時(shí)強(qiáng)制轉(zhuǎn)換CommonJS語(yǔ)法
build: {
commonjsOptions: {
transformMixedEsModules: true, // 處理混合了ES和CJS語(yǔ)法的依賴(lài)
include: /node_modules/ // 處理所有node_modules中的CJS依賴(lài)
}
}
})兜底方案:若個(gè)別依賴(lài)仍轉(zhuǎn)換失敗,使用vite-plugin-commonjs插件增強(qiáng)轉(zhuǎn)換能力:
# 安裝插件 npm install vite-plugin-commonjs --save-dev
// vite.config.js/ts
import { defineConfig } from 'vite'
import commonjs from 'vite-plugin-commonjs'
export default defineConfig({
plugins: [
commonjs(), // 注冊(cè)插件,自動(dòng)轉(zhuǎn)換CJS語(yǔ)法
vue()
]
})場(chǎng)景4:Webpack/Rollup配置缺失,未處理CommonJS語(yǔ)法(打包工具專(zhuān)屬)
錯(cuò)誤表現(xiàn)
Webpack/Rollup項(xiàng)目中,代碼用了ES模塊,但第三方依賴(lài)為CJS語(yǔ)法,打包后報(bào)require is not defined,報(bào)錯(cuò)指向依賴(lài)代碼。
核心原因
- Webpack:低版本W(wǎng)ebpack(<4)需手動(dòng)安裝插件處理CJS,高版本W(wǎng)ebpack默認(rèn)處理,但若配置了
externals排除了依賴(lài),會(huì)導(dǎo)致未轉(zhuǎn)換; - Rollup:天生基于ES模塊,對(duì)CJS語(yǔ)法支持差,必須手動(dòng)安裝插件才能處理CJS依賴(lài),否則直接殘留
require。
解決方案
分Webpack和Rollup給出針對(duì)性配置,均為開(kāi)箱即用:
方案1:Webpack項(xiàng)目(高版本/低版本通用)
確保Webpack處理所有CJS依賴(lài),避免externals錯(cuò)誤排除,核心配置:
// webpack.config.js
const path = require('path')
module.exports = {
entry: './src/index.ts',
output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist') },
resolve: { extensions: ['.ts', '.js', '.json'] },
module: { rules: [{ test: /\.ts$/, loader: 'ts-loader' }] },
// 關(guān)鍵:若需配置externals,僅排除CDN引入的依賴(lài),不要排除本地安裝的CJS依賴(lài)
externals: {
// 示例:CDN引入的Vue,排除后不參與打包,瀏覽器通過(guò)全局變量Vue獲取
vue: 'Vue'
},
mode: 'production'
}注意:Webpack5/4默認(rèn)會(huì)將CJS語(yǔ)法轉(zhuǎn)換為瀏覽器可執(zhí)行的代碼,無(wú)需額外插件,避免隨意配置externals排除本地依賴(lài)是關(guān)鍵。
方案2:Rollup項(xiàng)目(必須安裝插件)
安裝Rollup的CJS轉(zhuǎn)換插件,處理自身代碼和第三方依賴(lài)的CJS語(yǔ)法,步驟:
- 安裝所需插件:
npm install @rollup/plugin-commonjs @rollup/plugin-node-resolve --save-dev
- Rollup配置文件(rollup.config.js):
// rollup.config.js
import commonjs from '@rollup/plugin-commonjs'
import nodeResolve from '@rollup/plugin-node-resolve'
import typescript from '@rollup/plugin-typescript' // TS項(xiàng)目可選
export default {
input: './src/index.ts',
output: [{ file: 'dist/bundle.js', format: 'esm' }], // 輸出為ES模塊
plugins: [
nodeResolve(), // 解析node_modules中的依賴(lài)
commonjs(), // 核心:將CommonJS轉(zhuǎn)換為ES模塊
typescript() // TS編譯(可選)
]
}場(chǎng)景5:直接運(yùn)行未打包的TS/JS文件,未經(jīng)過(guò)編譯轉(zhuǎn)換(新手高頻)
錯(cuò)誤表現(xiàn)
將TS/JS文件直接通過(guò)script標(biāo)簽引入瀏覽器(如<script src="./src/index.ts"></script>),未使用任何打包工具,直接報(bào)require is not defined。
核心原因
- 瀏覽器無(wú)法直接運(yùn)行TS文件,也無(wú)法識(shí)別TS/JS中的
require和ES模塊語(yǔ)法; - 未通過(guò)打包工具(Webpack/Vite/Rollup)或編譯器(tsc/babel)將代碼轉(zhuǎn)換為瀏覽器可識(shí)別的純JS語(yǔ)法。
解決方案
必須通過(guò)工具處理后再引入瀏覽器,分兩種簡(jiǎn)單方案,新手友好:
方案1:使用打包工具(推薦,適配所有項(xiàng)目)
執(zhí)行項(xiàng)目的打包命令,將TS/JS打包為單個(gè)瀏覽器可運(yùn)行的JS文件,再引入:
# Vite項(xiàng)目 npm run build # Webpack項(xiàng)目 npm run build # Rollup項(xiàng)目 npx rollup -c
引入打包后的文件(通常在dist目錄下):
<!-- 正確:引入打包后的純JS文件 --> <script src="./dist/bundle.js"></script> <!-- 錯(cuò)誤:直接引入未打包的TS/JS源文件 --> <!-- <script src="./src/index.ts"></script> -->
方案2:純TS項(xiàng)目快速編譯(無(wú)打包工具)
通過(guò)tsc將TS編譯為ES模塊的JS文件,再通過(guò)script標(biāo)簽的type="module"引入:
- 按場(chǎng)景2修改
tsconfig.json,確保編譯為ES模塊; - 執(zhí)行TS編譯命令:
npx tsc
- 引入編譯后的JS文件,添加
type="module":
<script src="./dist/index.js" type="module"></script>
注意:type="module"是瀏覽器識(shí)別ES模塊的關(guān)鍵,添加后才能支持import/export。
場(chǎng)景6:第三方依賴(lài)通過(guò)CDN引入,全局變量缺失導(dǎo)致間接報(bào)require錯(cuò)誤
錯(cuò)誤表現(xiàn)
將第三方依賴(lài)通過(guò)CDN引入(如<script src="https://cdn.bootcdn.net/ajax/libs/echarts/5.4.3/echarts.common.js"></script>),業(yè)務(wù)代碼中用import/require引入該依賴(lài),打包后報(bào)require is not defined。
核心原因
- CDN引入的依賴(lài)會(huì)暴露全局變量(如echarts暴露
window.echarts),無(wú)需再通過(guò)import/require引入; - 若業(yè)務(wù)代碼中仍用
import/require引入,打包工具會(huì)嘗試解析該依賴(lài),若配置了externals則會(huì)殘留require,未配置則會(huì)打包失敗。
解決方案
兩步操作:排除依賴(lài)打包 + 業(yè)務(wù)代碼使用全局變量,以echarts為例:
- 打包工具中配置externals,排除該依賴(lài)(不參與打包):
- Vite/Webpack/Rollup配置方式一致,以Vite為例:
// vite.config.js export default defineConfig({ build: { rollupOptions: { externals: { echarts: 'echarts' } } } }) - 業(yè)務(wù)代碼中直接使用全局變量,不再導(dǎo)入:
// 正確:直接使用CDN暴露的全局變量 const myChart = echarts.init(document.getElementById('chart')) // 錯(cuò)誤:繼續(xù)導(dǎo)入,導(dǎo)致打包殘留require // import * as echarts from 'echarts' // const echarts = require('echarts')
三、主流工具通用配置模板(開(kāi)箱即用,避免99%的require錯(cuò)誤)
結(jié)合以上所有解決方案,提供TS+Webpack5、TS+Vite、純JS+Rollup三大主流項(xiàng)目的完整配置模板,直接復(fù)制到項(xiàng)目中即可,從根源上避免require is not defined錯(cuò)誤。
模板1:TS+Webpack5項(xiàng)目(通用企業(yè)級(jí)配置)
包含TS編譯、CJS轉(zhuǎn)換、ES模塊兼容所有核心配置,直接使用:
// webpack.config.js
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: './src/index.ts',
output: {
filename: 'assets/js/[name].[hash:8].js',
path: path.resolve(__dirname, 'dist'),
clean: true
},
resolve: {
extensions: ['.ts', '.tsx', '.js', '.json'],
alias: { '@': path.resolve(__dirname, 'src') }
},
module: {
rules: [
{ test: /\.tsx?$/, loader: 'ts-loader', exclude: /node_modules/ }
]
},
plugins: [
new HtmlWebpackPlugin({ template: './public/index.html' })
],
// 僅排除CDN引入的依賴(lài),本地CJS依賴(lài)由Webpack自動(dòng)轉(zhuǎn)換
externals: {
// vue: 'Vue', // 示例:CDN引入Vue時(shí)開(kāi)啟
// echarts: 'echarts'
},
mode: 'production'
}// tsconfig.json
{
"compilerOptions": {
"target": "ES6",
"module": "ESNext",
"moduleResolution": "Bundler",
"esModuleInterop": true,
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"allowJs": true
},
"include": ["./src/**/*"],
"exclude": ["node_modules", "dist"]
}模板2:TS+Vite項(xiàng)目(前端主流配置)
專(zhuān)為Vite優(yōu)化,強(qiáng)制轉(zhuǎn)換CJS依賴(lài),適配Vue/React/純TS項(xiàng)目:
// vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
import commonjs from 'vite-plugin-commonjs'
export default defineConfig({
plugins: [vue(), commonjs()],
resolve: { alias: { '@': path.resolve(__dirname, 'src') } },
optimizeDeps: {
include: ['echarts', 'jquery'], // 預(yù)構(gòu)建CJS依賴(lài)
esbuildOptions: { format: 'esm' }
},
build: {
commonjsOptions: {
transformMixedEsModules: true,
include: /node_modules/
},
rollupOptions: {
externals: { /* echarts: 'echarts' */ }
}
}
})// tsconfig.json
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "Bundler",
"esModuleInterop": true,
"strict": true,
"jsx": "preserve",
"baseUrl": ".",
"paths": { "@/*": ["src/*"] }
},
"include": ["src/**/*", "vite.config.ts"],
"exclude": ["node_modules"]
}模板3:純JS+Rollup項(xiàng)目(輕量庫(kù)開(kāi)發(fā)配置)
輕量無(wú)冗余,專(zhuān)門(mén)處理CJS語(yǔ)法,適配前端庫(kù)開(kāi)發(fā):
// rollup.config.js
import commonjs from '@rollup/plugin-commonjs'
import nodeResolve from '@rollup/plugin-node-resolve'
import { babel } from '@rollup/plugin-babel'
export default {
input: './src/index.js',
output: [
{ file: 'dist/bundle.esm.js', format: 'esm' }, // 輸出ES模塊
{ file: 'dist/bundle.umd.js', format: 'umd', name: 'MyLib' } // 輸出UMD(兼容瀏覽器/Node)
],
plugins: [
nodeResolve(),
commonjs(), // 核心轉(zhuǎn)換CJS
babel({ babelHelpers: 'bundled', exclude: /node_modules/ })
],
externals: { /* jquery: '$' */ }
}四、通用排查流程:三步定位所有require is not defined錯(cuò)誤(1分鐘搞定)
遇到TS/JS打包后報(bào)require is not defined,無(wú)需盲目修改配置,按以下三步排查流程執(zhí)行,1分鐘內(nèi)可定位所有問(wèn)題根源,適用于所有項(xiàng)目類(lèi)型:
步驟1:檢查代碼是否手寫(xiě)了require/module.exports(排除基礎(chǔ)問(wèn)題)
- 全局搜索項(xiàng)目代碼中的
require、module.exports、exports.,若有則全部替換為ES模塊的import/export; - 檢查是否有動(dòng)態(tài)
require,替換為ES模塊的import()異步函數(shù)。
步驟2:檢查編譯/打包配置(核心排查)
- TS項(xiàng)目:打開(kāi)
tsconfig.json,確認(rèn)module為ESNext/ES6,moduleResolution為Bundler/NodeNext,避免編譯出require; - Vite項(xiàng)目:確認(rèn)配置了
build.commonjsOptions和optimizeDeps,或安裝了vite-plugin-commonjs; - Rollup項(xiàng)目:確認(rèn)安裝并注冊(cè)了
@rollup/plugin-commonjs和@rollup/plugin-node-resolve; - Webpack項(xiàng)目:確認(rèn)未隨意配置
externals排除本地CJS依賴(lài),高版本W(wǎng)ebpack無(wú)需額外插件。
步驟3:檢查代碼運(yùn)行/引入方式(排除環(huán)境問(wèn)題)
- 確認(rèn)是否直接運(yùn)行未打包/未編譯的TS/JS文件,若是則通過(guò)打包工具處理后再引入;
- 確認(rèn)CDN引入的依賴(lài)是否被重復(fù)導(dǎo)入,若是則配置
externals并使用全局變量; - 生產(chǎn)環(huán)境報(bào)錯(cuò)的話(huà),對(duì)比開(kāi)發(fā)/生產(chǎn)的打包配置,確保生產(chǎn)環(huán)境開(kāi)啟了CJS轉(zhuǎn)換。
驗(yàn)證方法:每修改一步,重新打包并在瀏覽器中運(yùn)行,打開(kāi)F12→Sources面板,查看打包后的JS文件是否還有require,無(wú)則問(wèn)題解決。
五、高頻避坑點(diǎn)(企業(yè)開(kāi)發(fā)規(guī)范,避免重復(fù)踩坑)
- 瀏覽器端代碼徹底拋棄CommonJS:永遠(yuǎn)使用
import/export,不手寫(xiě)require/module.exports,從根源避免問(wèn)題; - TS配置必改module:新建TS項(xiàng)目后,第一時(shí)間將
tsconfig.json的module改為ESNext,避免編譯出require; - Vite項(xiàng)目必配CJS轉(zhuǎn)換:使用Vite開(kāi)發(fā)時(shí),只要引入了老版本CJS依賴(lài),就必須配置
build.commonjsOptions或vite-plugin-commonjs; - Rollup項(xiàng)目必裝commonjs插件:Rollup天生不支持CJS,未安裝
@rollup/plugin-commonjs必報(bào)require錯(cuò)誤; - 避免直接引入未處理的TS/JS:瀏覽器無(wú)法運(yùn)行TS,也無(wú)法識(shí)別模塊語(yǔ)法,必須通過(guò)打包/編譯工具處理;
- CDN依賴(lài)不重復(fù)導(dǎo)入:CDN引入的依賴(lài)通過(guò)全局變量使用,不要在代碼中
import/require,并配置externals排除打包; - 開(kāi)發(fā)/生產(chǎn)配置保持一致:不要在開(kāi)發(fā)環(huán)境配置CJS轉(zhuǎn)換,生產(chǎn)環(huán)境卻刪除,導(dǎo)致開(kāi)發(fā)正常生產(chǎn)報(bào)錯(cuò)。
六、總結(jié)
TS/JS打包后報(bào)Uncaught ReferenceError: require is not defined的問(wèn)題,本質(zhì)是「環(huán)境不兼容」導(dǎo)致的模塊語(yǔ)法殘留——require是Node.js的CommonJS專(zhuān)屬語(yǔ)法,瀏覽器無(wú)此API,打包后代碼中只要?dú)埩粑崔D(zhuǎn)換的require,就會(huì)觸發(fā)該錯(cuò)誤。
核心解決思路可總結(jié)為3個(gè)核心動(dòng)作,三者結(jié)合可解決100%的該類(lèi)錯(cuò)誤:
- 代碼層:徹底替換為ES模塊語(yǔ)法(
import/export),不手寫(xiě)任何require/module.exports; - 編譯層:TS項(xiàng)目修改
tsconfig.json,確保編譯后生成ES模塊,不產(chǎn)生require; - 打包層:配置打包工具(Vite/Webpack/Rollup)處理第三方依賴(lài)的CJS語(yǔ)法,強(qiáng)制轉(zhuǎn)換為瀏覽器可識(shí)別的代碼。
遵循本文的6大高頻場(chǎng)景解決方案和三步通用排查流程,可快速定位并解決所有require is not defined錯(cuò)誤;直接使用主流工具通用配置模板,可從根源上避免99%的該類(lèi)錯(cuò)誤,讓TS/JS項(xiàng)目在瀏覽器端的運(yùn)行更穩(wěn)定。
到此這篇關(guān)于TS/JS打包后報(bào)Uncaught ReferenceError: require is not defined問(wèn)題解決辦法的文章就介紹到這了,更多相關(guān)Uncaught ReferenceError: require is not defined內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
uniapp小程序?qū)崿F(xiàn)瀑布流布局的思路與代碼
這篇文章主要給大家介紹了關(guān)于uniapp小程序?qū)崿F(xiàn)瀑布流布局的思路與代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04
Extjs表單輸入框異步校驗(yàn)的插件實(shí)現(xiàn)方法
這篇文章主要介紹了Extjs表單輸入框異步校驗(yàn)的插件實(shí)現(xiàn)方法,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-03-03
一個(gè)XML格式數(shù)據(jù)轉(zhuǎn)換為圖表的例子
這個(gè)例子使用的是轉(zhuǎn)換為VML的語(yǔ)法,換成其他如SVG的語(yǔ)法,就可以轉(zhuǎn)換成為SVG圖形,單元數(shù)量可以任意加。2010-02-02
Node+OCR實(shí)現(xiàn)圖像文字識(shí)別功能
這篇文章主要為大家詳細(xì)介紹了Node+OCR實(shí)現(xiàn)圖像文字識(shí)別功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-11-11
如何在JavaScript中運(yùn)行.NET?Core代碼詳情
這篇文章主要介紹了在JavaScript中運(yùn)行.NET?Core代碼詳情,DotNetJS可以將C#項(xiàng)目編譯為與任何環(huán)境兼容的單文件JavaScript庫(kù),變可以在JavaScript中運(yùn)行.NET?Core代碼,相關(guān)操作分享詳情,需要的小伙伴可以參考一下2022-04-04
javascript中函數(shù)作為參數(shù)調(diào)用的方法
這篇文章主要介紹了javascript中函數(shù)作為參數(shù)調(diào)用的方法,實(shí)例分析了函數(shù)作為操作調(diào)用的原理與相關(guān)技巧,需要的朋友可以參考下2015-02-02
js 失去焦點(diǎn)時(shí)關(guān)閉層實(shí)現(xiàn)代碼
失去焦點(diǎn)時(shí)關(guān)閉層實(shí)現(xiàn)代碼。大家可以參考下。2009-05-05

