一文讲清ESModel和CommonJS中的导入导出
前序
模块化的出现是前端发展的必然结果,从早期的单独一个html网页到现在的spa单页面应用,前端要承担的处理越来越大,为解决文件分工分类的原因出现模块化概念,在前端用两套标准,一个是CommonJS模块,诞生于node环境中主要的关键字为exports,module.exports,require,另一个是ESModel规范,主要应用于vue中,服务于浏览器环境,vue中的模块打包器webpack支持两种规范的打包,主要关键字为export,export default,import。
ESModel的模块化
export和import
a.js导出文件
// 可以使用多次
export const name = '七月'
export function far(){
return '小明'
}
const sex = '男'
const age = 11
// 可以申明为对象导出多个变量
export {
sex,
age
}
b.js导入文件
// 导入方式1
import {name, far, age, sex} from './a.js'
// 导入方式2,通过别命的方式重新命名
import * as user from './a.js'
console.log(name)
console.log(far())
console.log(sex)
console.log(age)
//别命的导入使用
console.log(user.age)
1、export (ES6)
注意事项:导出时(export)
命名导出:使用export关键字导出变量、函数、类或值时,需要为它们指定名称。这些名称将在其他模块中用于导入。
默认导出与命名导出:export default用于导出模块的默认值,而命名导出使用export关键字后跟变量名或函数名。一个模块只能有一个默认导出,但可以有多个命名导出。
导出表达式:你可以直接导出变量、函数或类的值,或者导出它们的计算结果(如表达式)。
重新导出:你可以使用export { name1, name2, ... } from 'module-name'语法来重新导出另一个模块的命名导出。\
引入时(import)
命名匹配:当使用命名导入时,必须确保导入的名称与导出模块中定义的名称完全匹配。
默认导入与命名导入:使用import关键字时,可以指定一个名称来接收默认导出(import name from 'module-name'),或者使用花括号来接收命名导出(import { name1, name2 } from 'module-name')。
静态分析:与默认导出一样,import语句也是静态的,需要在编译时确定模块的路径。
路径正确性:确保在import语句中指定的模块路径是正确的。相对路径或绝对路径都可以,但如果是相对路径,需要注意当前文件与目标模块文件之间的相对位置。
模块加载:import语句会在运行时加载模块,如果模块不存在或发生错误,程序将抛出异常。
export default和import
注意: 一个js文件有且仅有一个export default导出 a.js导出
const name = '七月'
const sex = '男'
const age = 11
function far(){
return '跑'
}
export default {
name,
sex,
age,
far
}
b.js导入
// 这里起任何名字都行
import user from './a.js'
console.log(user.far())
注意事项
1、export (ES6)
注意事项:
导出时(export)
命名导出:使用export关键字导出变量、函数、类或值时,需要为它们指定名称。这些名称将在其他模块中用于导入。
默认导出与命名导出:export default用于导出模块的默认值,而命名导出使用export关键字后跟变量名或函数名。一个模块只能有一个默认导出,但可以有多个命名导出。
导出表达式:你可以直接导出变量、函数或类的值,或者导出它们的计算结果(如表达式)。
重新导出:你可以使用export { name1, name2, ... } from 'module-name'语法来重新导出另一个模块的命名导出。
引入时(import)
命名匹配:当使用命名导入时,必须确保导入的名称与导出模块中定义的名称完全匹配。
默认导入与命名导入:使用import关键字时,可以指定一个名称来接收默认导出(import name from 'module-name'),或者使用花括号来接收命名导出(import { name1, name2 } from 'module-name')。
静态分析:与默认导出一样,import语句也是静态的,需要在编译时确定模块的路径。
路径正确性:确保在import语句中指定的模块路径是正确的。相对路径或绝对路径都可以,但如果是相对路径,需要注意当前文件与目标模块文件之间的相对位置。
模块加载:import语句会在运行时加载模块,如果模块不存在或发生错误,程序将抛出异常。
CommonJS导入导出
a.js
const name = 'alias'
const age = () => { return 18 }
// 导出方式1
exports.name = name
exports.age = age
// 导出方式2
module.exports = { name, age, }
b.js
const user = require('./utils/user')
3、exports (CommonJS)
注意事项:
导出时(exports)
exports 和 module.exports:exports 是 module.exports 的一个引用。当你为 exports 分配一个新值时,它不再引用 module.exports。因此,通常推荐直接使用 module.exports,以避免混淆。
导出类型:你可以导出函数、对象、值等。如果导出一个单一的值,通常使用 module.exports = value;。如果导出多个值,则使用 exports.name = value; 或 module.exports = { name: value };。
不要混用:在同一个模块中,不要混用 exports 和 module.exports 来导出不同的内容,因为这会导致混淆和不可预期的行为。
导出函数或类:当你导出函数或类时,可以直接将函数或类赋值给 module.exports。
引入时(require)
路径:使用 require 引入模块时,需要提供正确的文件路径。可以是相对路径(如 ./myModule)或绝对路径(如 /path/to/myModule)。此外,Node.js 还会查找 node_modules 目录中的模块。
赋值:require 语句会将引入的模块内容赋值给一个变量。你可以为这个变量指定任何名称。
缓存:Node.js 会缓存已加载的模块,这意味着多次 require 同一个模块会返回相同的对象(除非使用 require.cache 手动清除缓存)。
循环依赖:虽然Node.js可以处理一定程度的循环依赖,但过度使用或不当使用循环依赖可能导致不可预测的行为或错误。因此,应尽量避免不必要的循环依赖。
4、module.exports
注意事项:
导出时(module.exports)
导出内容:module.exports 可以导出任何 JavaScript 数据类型,包括函数、对象、数组、字符串、数字等。一旦你为 module.exports 分配了一个值,它将替代默认的导出对象。
不要重复赋值:一旦你为 module.exports 分配了一个值,之后的任何对 module.exports 的赋值操作都将覆盖之前的值。因此,通常建议在文件的顶部进行 module.exports 的赋值。
导出函数:如果你导出的是一个函数,确保该函数在调用时可以访问到它需要的所有外部变量和上下文。
模块缓存:Node.js 会缓存已加载的模块,这意味着如果你多次 require 同一个模块,它将只执行一次,并返回第一次执行的结果。确保你的模块在导出时处于正确的状态。
避免循环依赖:虽然 Node.js 可以处理一定程度的循环依赖,但过度使用或不当使用循环依赖可能导致未定义的行为或错误。
引入时(require)
路径:使用 require 引入模块时,需要提供正确的文件路径。可以是相对路径(如 ./myModule)或绝对路径(如 /path/to/myModule)。如果省略路径,Node.js 将查找 node_modules 目录中的模块。
命名:你可以为引入的模块指定任何变量名,这通常是模块导出的主要功能的名称。
错误处理:如果 require 无法找到指定的模块,它将抛出一个错误。确保你的代码可以妥善处理这些错误,特别是在动态引入模块时。
缓存:由于 Node.js 缓存已加载的模块,所以 require 的结果将始终是第一次加载时的结果,除非你清除 require.cache。
转载自:https://juejin.cn/post/7375928754148032539