解决Webpack 打包报错:TypeError: Cannot assign to read only property 'exports' ?

前言:

做前端项目打包时,你是否遇到过这样的窘境:本地 npm run dev 运行一切正常,可执行 npm run build 打包后,生产环境控制台直接抛出 TypeError: Cannot assign to read only property 'exports' of object '#<Object>' 错误?

一、背景介绍

最近有个以前的老项目(Vue2+webpack)在正式环境出现了问题,这个项目中途一直没改动,突然有个页面打不开了。在控制台的报错信息如下图所示:

需要说明的一点,这是打包后的报错,在本地运行的时候,是没有问题的。 我把这段报错信息复制下来,如果有需要的话可以复制去研究一下。

js 复制代码
vendor.0d88a535e3e863312d89.js:44 TypeError: Cannot assign to read only property 'exports' of object '#<Object>
    at Object.<anonymous> (0.d97ee341e9f7c8f3e805.js:1:14033)
    at 16Wf (0.d97ee341e9f7c8f3e805.js:1:16662)
    at n (manifest.83cbbf59a618d5d725c4.js:1:101)
    at Object.exjW (0.d97ee341e9f7c8f3e805.js:10:119646)
    at n (manifest.83cbbf59a618d5d725c4.js:1:101)
    at Object.OpaP (0.d97ee341e9f7c8f3e805.js:10:22333)
    at n (manifest.83cbbf59a618d5d725c4.js:1:101)
    at 7AuU (0.d97ee341e9f7c8f3e805.js:1:52095)
    at n (manifest.83cbbf59a618d5d725c4.js:1:101)
    at Object.sGS9 (0.d97ee341e9f7c8f3e805.js:10:181323)

二、解决方法

快速修复建议

  1. 首先尝试 方案一方案二 ,检查并修正 babelwebpack 配置。(推荐)
  2. 如果你知道具体哪个文件导致问题,直接修改该文件的模块语法。

下面将具体展开描述解决步骤:

  1. 我将这个问题的报错信息直接抛给了通义千问,让它帮我分析问题原因,并给出解决方案。

代码如下:

js 复制代码
{
  "presets": [
    ["env", {
      "modules": false,
      "targets": {
        "browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
      }
    }],
    "stage-2"
  ],
  "plugins": ["transform-runtime"]
}
  1. 对照着我自己的代码检查之后,确保项目根目录下的.babelrcbabel.config.js文件包含正确的配置,没有问题,(我项目中是.babelrc文件)。

    如果没有 .babelrc 文件,创建一个并添加上述内容。

  2. 然后继续看下一个方案:

代码如下:

js 复制代码
  module: {
    rules: [
      // 添加 JavaScript 文件处理规则来解决模块系统冲突问题
      {
        test: /\.js$/,
        loader: 'babel-loader',
        exclude: /(node_modules|bower_components)/,
        options: {
          presets: [
            ['env', {
              modules: false // 确保设置为 false
            }]
          ]
        }
      }
    ]
  },

根据 方案二 ,找到项目中对应的 build/webpack.prod.conf.js文件,看是否有上面的这段代码。

下图是我的项目中的代码,很尴尬,没有这部分代码......

  1. 接着就可以将这部分代码加进去:

代码如下,可直接复制:

js 复制代码
  module: {
    rules: [
      // 添加 JavaScript 文件处理规则来解决模块系统冲突问题
      {
        test: /\.js$/,
        loader: 'babel-loader',
        exclude: /(node_modules|bower_components)/,
        options: {
          presets: [
            ['env', {
              modules: false
            }]
          ]
        }
      },
      // 保留原有的样式处理规则
      ...utils.styleLoaders({
        sourceMap: config.build.productionSourceMap,
        extract: true
      })
    ]
  },

关键点是设置 "modules": false,这告诉 Babel 不要转换 ES6 的 import/export 语法,让 webpack 来处理模块系统,避免 ES6 模块语法和 CommonJS 语法冲突的问题。

完成这些修改后,重新运行 npm run build 应该就能解决你遇到的错误了。

推荐这个方案的原因是,这样可以确保开发环境和生产环境使用相同的 babel 配置。这个修改就是我成功解决问题的方法。

  1. AI 还给我建议说,"检查具体出错的文件",可是根据错误堆栈,问题出现的文件名称是被编译过的,找的话就需要查找源代码中混用了 importmodule.exports 的地方,找到之后统一使用一种模块语法即可。 由于我的出错文件是在第三方库中,所以这个方案有点麻烦,我果断放弃。

三、问题原因

核心原因正如分析所示:在同一模块中同时混用了 ES6 的 import/export 语法与 CommonJS 的 module.exports 语法,导致 webpack 处理模块时出现冲突。这是 webpack 打包后,生产环境中较为常见的问题。

如果是自己写的代码,可以在代码中查找并修改,统一项目中的模块语法规范即可。如果是第三方库出现的问题,就可以用本文中的方法解决,先尝试检查 babel 配置并确保 modules: false 设置正确,这通常能解决大部分此类问题。

四、总结

前端打包报错往往 "现象复杂,根源简单",遇到类似问题时,优先排查模块语法、依赖兼容性、Webpack 配置这三大方向,通常能快速找到突破口。

以上,希望对大家有帮助!

相关推荐
敲敲了个代码1 小时前
从硬编码到 Schema 推断:前端表单开发的工程化转型
前端·javascript·vue.js·学习·面试·职场和发展·前端框架
张雨zy3 小时前
Pinia 与 TypeScript 完美搭配:Vue 应用状态管理新选择
vue.js·ubuntu·typescript
dly_blog3 小时前
Vue 响应式陷阱与解决方案(第19节)
前端·javascript·vue.js
消失的旧时光-19433 小时前
401 自动刷新 Token 的完整架构设计(Dio 实战版)
开发语言·前端·javascript
console.log('npc')3 小时前
Table,vue3在父组件调用子组件columns列的方法展示弹窗文件预览效果
前端·javascript·vue.js
我命由我123454 小时前
SVG - SVG 引入(SVG 概述、SVG 基本使用、SVG 使用 CSS、SVG 使用 JavaScript、SVG 实例实操)
开发语言·前端·javascript·css·学习·ecmascript·学习方法
C_心欲无痕4 小时前
vue3 - markRaw标记为非响应式对象
前端·javascript·vue.js
qingyun9895 小时前
深度优先遍历:JavaScript递归查找树形数据结构中的节点标签
前端·javascript·数据结构
胡楚昊5 小时前
NSSCTF动调题包通关
开发语言·javascript·算法
熬夜敲代码的小N5 小时前
Vue (Official)重磅更新!Vue Language Tools 3.2功能一览!
前端·javascript·vue.js