vue 运行时报错: Cannot assign to read only property 'exports' of object 'Object'

背景

用 vue-cli 搭建的 vue 项目,引用了第三方插件,npm run dev 之后一直报错 error:Cannot assign to read only property ‘exports’ of object ‘#< object>’ ,查了好多资料好像是export和import共用了导致不兼容引起的,然后还是不起作用,最后参考了天地一扁舟的博客,完美解决。

解决方法

npm install babel-plugin-transform-es2015-modules-commonjs

然后在 babelrc中配置

{ “plugins”: [“transform-es2015-modules-commonjs”] }

即可解决

<think>好的,我现在需要帮助用户解决他们遇到的TypeError: Cannot assign to read only property 'hospitalCode'的错误。首先,我要理解这个错误的本质。根据用户提供的引用内容,这个错误通常发生在尝试修改一个只读属性。用户提到的引用[2]和[3]都指出,这可能是因为模块导出方式的问题,或者在JavaScript中试图修改一个被设置为只读的属性。 首先,用户的问题具体是尝试修改对象中的'hospitalCode'属性出错。我需要考虑几种可能的情况: 1. **对象属性被设置为只读**:可能是该属性在定义使用了`Object.defineProperty`或类似方法,设置了`writable: false`,导致无法修改。用户可能在某个地方定义了这个属性,或者在框架/库中被设置为只读。 2. **模块导出问题**:引用[1]、[3]、[5]提到,当使用CommonJS的`exports`,如果错误地尝试修改`exports`对象,可能会引发类似错误。用户可能在模块导出错误地修改了`exports`,但根据用户的问题,错误是关于'hospitalCode'而不是'exports',所以这可能不直接相关,但需要确认用户是否在模块导出中有相关操作。 3. **使用框架或库的限制**:比如在React中,状态对象可能是不可变的,直接修改状态可能导致此类错误。引用[4]中的例子显示,在React中尝试直接修改状态对象的属性会导致错误,解决方案是创建一个新对象。 接下来,我需要分析用户的具体情况。用户提到错误发生在'hospitalCode'属性上,这可能是在他们自己的代码中,或者是在处理某个库返回的对象。可能的解决步骤包括: - **检查对象是否被冻结或密封**:使用`Object.isFrozen`或`Object.isSealed`来确认对象是否被设置为不可修改。如果是,可能需要复制对象或重新创建。 - **使用不可变更新模式**:如在React中,状态不应直接修改,而是通过创建新对象来更新。例如,使用扩展运算符或`Object.assign`来创建新对象。 - **检查模块系统混合使用**:如果项目中同使用了ES6的`import/export`和CommonJS的`require/module.exports`,可能会导致问题。需要统一模块语法,如引用[5]提到的,使用`export`代替`exports`。 此外,用户之前的问题关于React的useCallback,可能他们在使用React遇到状态管理的错误。需要确认他们是否在尝试直接修改状态对象的属性,比如: ```javascript // 错误示例 const [state, setState] = useState({ hospitalCode: '123' }); state.hospitalCode = '456'; // 直接修改会导致错误 setState(state); ``` 正确的做法应该是: ```javascript setState(prev => ({ ...prev, hospitalCode: '456' })); ``` 或者使用扩展运算符创建新对象: ```javascript const newState = { ...state, hospitalCode: '456' }; setState(newState); ``` 另外,用户可能在使用第三方库返回的对象,这些对象可能是只读的。例如,Vue中的响应式对象或使用Object.freeze处理过的对象,这需要深拷贝对象来修改属性。 还需要考虑是否在严格模式下,某些操作被禁止。不过,错误信息明确提到是只读属性,所以更可能是对象属性本身被设置为不可写。 总结解决方案步骤: 1. **确认对象是否可写**:检查对象属性描述符,确认是否可写。 2. **避免直接修改状态**:使用不可变更新,创建新对象。 3. **检查模块导出语法**:确保使用正确的ES6导出方式。 4. **深拷贝对象**:当处理不可变对象,先复制再修改。 需要将这些步骤以清晰的方式呈现给用户,并提供代码示例,帮助他们理解和解决问题。同,要提醒常见的错误场景,如直接修改状态、混合模块系统等,确保用户能针对性地检查自己的代码。</think>#### 解决方案:`TypeError: Cannot assign to read only property 'hospitalCode'` 该错误表示你正在尝试修改一个被设置为**只读属性(read-only property)**的对象字段`hospitalCode`。以下是分步解决方案: --- ### 一、核心原因定位 1. **属性被显式设置为只读** - 通过`Object.defineProperty(obj, 'hospitalCode', { writable: false })`定义 - 对象被`Object.freeze()`或`Object.seal()`处理过 2. **框架的不可变数据限制** - React/Vue等框架的响应式数据要求不可变更新 3. **模块导出冲突** - CommonJS与ES6模块混用错误修改`exports`(虽与`hospitalCode`无直接关联,但需排查) --- ### 二、具体修复方法 #### 方法1:创建新对象(推荐) **适用场景**:React状态更新、Vue响应式数据等需要不可变更新的场景 ```javascript // 错误:直接修改原对象 ❌ obj.hospitalCode = 'newValue'; // 正确:创建新对象 ✅ const newObj = { ...obj, hospitalCode: 'newValue' }; // 扩展运算符 // 或 const newObj = Object.assign({}, obj, { hospitalCode: 'newValue' }); ``` #### 方法2:深拷贝对象 **适用场景**:处理第三方库返回的冻结对象 ```javascript // 使用JSON方式(注意会丢失函数/日期等特殊类型) const clonedObj = JSON.parse(JSON.stringify(obj)); clonedObj.hospitalCode = 'newValue'; // 使用lodash深拷贝 import { cloneDeep } from 'lodash'; const clonedObj = cloneDeep(obj); clonedObj.hospitalCode = 'newValue'; ``` #### 方法3:解除只读限制(慎用) **适用场景**:明确需要修改自有对象 ```javascript // 检查属性是否可写 const descriptor = Object.getOwnPropertyDescriptor(obj, 'hospitalCode'); console.log(descriptor.writable); // 输出是否为true // 解除只读限制 Object.defineProperty(obj, 'hospitalCode', { writable: true }); obj.hospitalCode = 'newValue'; // 现在可以修改 ``` #### 方法4:检查模块规范(Webpack项目) 若错误涉及模块导出,需统一规范: ```javascript // 错误:CommonJS语法 ❌ exports.hospitalCode = 'value'; // 正确:ES6语法 ✅ export const hospitalCode = 'value'; ``` --- ### 三、React/Vue框架中的典型场景 #### React示例 ```jsx // 错误:直接修改state ❌ const [hospitalInfo, setHospitalInfo] = useState({ hospitalCode: '001' }); hospitalInfo.hospitalCode = '002'; setHospitalInfo(hospitalInfo); // 触发错误 // 正确:不可变更新 ✅ setHospitalInfo(prev => ({ ...prev, hospitalCode: '002' })); ``` #### Vue示例 ```javascript // 错误:直接修改props ❌ export default { props: ['hospitalCode'], methods: { updateCode() { this.hospitalCode = 'new'; // 触发只读错误 } } } // 正确:通过事件通知父组件修改 ✅ this.$emit('update:hospitalCode', 'newValue'); ``` --- ### 四、调试建议 1. **检查对象来源**: - 使用`console.log(Object.getOwnPropertyDescriptor(obj, 'hospitalCode'))`查看属性描述符 2. **追溯赋值操作**: - 在代码中搜索`hospitalCode`的所有修改位置 3. **框架调试工具**: - React DevTools检查Props/State是否被冻结 - Vue DevTools观察响应式数据变化 --- ### 典型错误场景排查表 | 场景 | 表现特征 | 解决方案 | |------|----------|----------| | 直接修改React状态 | 使用`useState`后直接赋值 | 改用扩展运算符创建新对象 | | Vue Props修改 | 在子组件中修改props字段 | 通过`emit`通知父组件修改 | | 第三方库返回对象 | 对象属性无法修改 | 深拷贝后操作新对象 | | Webpack模块混用 | 同存在`import`和`module.exports` | 统一使用ES6模块语法 | --- 通过以上方法,90%以上的"read only property"错误可被解决。若问题依然存在,建议提供具体代码片段进一步分析[^2][^3][^5]。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值