5月27日 01:16
module.exports 和 exports 的区别是什么?export 和 export default 的区别是什么?
两对概念,一个在 CommonJS,一个在 ESModule。
module.exports vs exports(CommonJS):
module.exports是真正的导出对象。exports只是module.exports的引用(const exports = module.exports)- 给
exports赋新值会断开引用,导出失败;module.exports赋新值可以 - 安全做法:只添加属性用
exports.foo = bar,需要替换整个导出用module.exports = foo
javascript// 正确 module.exports = { a: 1 }; exports.b = 2; // 错误 — exports 被重新赋值,断开引用 exports = { a: 1 }; // module.exports 还是 {}
export vs export default(ESModule):
export是命名导出,可以有多个。导入时用{ name }且名字必须匹配export default是默认导出,每个模块只有一个。导入时可以取任意名字- 一个模块可以同时有命名导出和默认导出
javascript// 导入区别 import { foo } from './a'; // 命名导出 import foo from './a'; // 默认导出 import foo, { bar } from './a'; // 两者都有
追问
为什么 export default 导入可以随意命名?
因为默认导出本质上导出的是 { default: value } 这个特殊 key。import x from 就是取 default key 的值。因此也叫 default import。
项目中应该优先用命名导出还是默认导出?
命名导出更好——IDE 自动补全、refactor 改名时更安全、Tree-Shaking 友好。默认导出适合"这个模块只有一个主要导出"(如一个组件、一个工具函数)。但争议是社区级的,没有绝对的优劣。