使用ParcelJS生产构建时遭遇Class未定义的ReferenceError问题
ParcelJS生产构建后类定义无法访问的问题
生产构建后出现以下错误:
app.js:5 Uncaught ReferenceError: Class1 is not defined at new <anonymous> (app.js:5:24) at app.js:9:1
开发环境运行正常,仅生产构建后触发该问题,可通过以下代码复现:
复现代码
/src/index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script src="./js/class_1.js"></script> <script src="./js/app.js"></script> </body> </html>
/src/js/class_1.js
class Class1 { constructor() { console.log("Class1 constructor()"); } }
/src/js/app.js
class App { constructor() { this.class_1 = new Class1(); } } new App();
/package.json
{ "name": "parcel-test", "source": "src/index.html", "scripts": { "start": "parcel --public-url ./", "build": "parcel build --public-url ./", "deploy": "push-dir --dir=dist --branch=gh-pages --cleanup --verbose" }, "devDependencies": { "parcel": "^2.10.0", "push-dir": "^0.4.1" } }
执行yarn build后,在dist目录启动服务器即可触发报错。
问题原因
Parcel在生产构建阶段会对脚本进行模块封装优化,默认不会将类、变量等暴露到全局window对象上;而开发环境下Parcel的封装策略相对宽松,变量会被挂载到全局,因此开发时能正常访问Class1。
解决方案
方案1:使用ES模块规范(推荐)
这是现代前端开发的标准做法,通过export和import明确模块依赖关系:
- 修改
class_1.js,导出Class1:
// /src/js/class_1.js export class Class1 { constructor() { console.log("Class1 constructor()"); } }
- 修改
app.js,导入Class1:
// /src/js/app.js import { Class1 } from './class_1.js'; class App { constructor() { this.class_1 = new Class1(); } } new App();
- 修改
index.html中的脚本标签,添加type="module"并移除单独引入class_1.js的标签:
<script type="module" src="./js/app.js"></script>
方案2:手动挂载到全局作用域
如果需要保持原有脚本引入方式,可将Class1手动挂载到window对象:
// /src/js/class_1.js class Class1 { constructor() { console.log("Class1 constructor()"); } } window.Class1 = Class1; // 挂载到全局作用域
这样生产构建后,Class1会被保留在全局作用域中,app.js就能正常访问。
内容的提问来源于stack exchange,提问作者fguillen
相关产品推荐
相关产品推荐

