十分钟玩转模块化:ES Modules && ConmonJS 使用详解

node应用由模块组成,采用的commonjs模块规范。

一 ES Modules

1.1 重要特性(CommonJS对比)

  1. 会延迟执行脚本,不会阻塞页面。在导入详解-动态的导入路径中可以看到,ES模块的导入是异步行为,当ES的导入放到顶端时,会提前进行静态编译,而在使用import方法导入时,会返回promise对象。
    commonjs是运行时加载模块,ES6在编译期间会将所有import提升到顶部,在静态编译期间就确定模块的依赖。
    而common JS是同步的。不会提升require。直接使用即可。

  2. ES6导出的是引用关系,当模块内部的变量变化时,导出的值也会变化。
    commonjs导出的是一个值拷贝,会对加载结果进行缓存,一旦内部再修改这个值,则不会同步到外部。

  3. 导出的值是只读的常量。可以看作const类型。
    而commoonJS导出的是普通常量。

1.2 导出详解

export var name = 1
export function hello(){}
export class Person {}
// ---
import { name } from './module.js'

集体导出的方式更加简明。

var name = 1
function hello(){}
class Person {}

export { name, hello, Person }
//---重命名导出
export {
	name as fooName,
	hello as fooHello,
	Person as fooPerson
}
// 当使用名称default导出时可以直接导入
// default导出的两种方式
export {
	name as default,
}
export default function(){}
// default导入
import abc from './js'
import { default as abc } from './js'

下面的花括号是导出变量组的语法,而不是一个对象字面量。

export { name, hello, Person }

下面的导出都是错的:

export '' // 错的
export [] // 错的
export 123 // 错的

1.3 导入详解

1 不可省略的扩展名和index
import * as mod from './module/index.js' // true
import * as mod from './module' //ERROR
import * as mod from './module/index' //ERROR
2 ./ 不可省略 省略是包文件
import * as mod from './module.js' // true
import * as mod from 'module.js' // ERROR 会从node_modules中找
3 加载但不提取
import './module.js'
4 导出全部成员到对象
import * as mod from './module.js'
5 动态的模块路径

import后面无法使用变量,且只能出现在文件顶部。

使用全局方法import()来实现动态模块导入,它的返回值是promise。

import('./module.js').then((module)=>{})
6 将导入成员直接导出

常用于index文件,整合多个子文件集中导出。

export { name, age } from './module.js'

二 ESmodule 与 CommonJS

2.1 混合使用

Node js同时支持 ESmodule和CommonJS。

使用commonJS导出的模块也可以使用ESmodule方式导入。

// commonJS 始终只会导出一个默认成员
module.exports = {
  foo: '123'
}
// ---
exports.foo = 123
// commonJS
const mod = require('./commonjs.js')
// Es
import mod from './commonjs.js'
console.log(mod) // { foo: '123' }
// 下面是不对的 因为commonJS 始终只会导出一个默认成员
import { foo } from './commonjs.js' // ERROR

2.2 变量差异

commonJS提供的变量:

require module exports __filename __surname 都可以直接使用。

ESmodule对应变量:

import { fileURLToPath } from 'url'
import { dirname } from 'path'
const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)

2.3 node版本支持

新版的JS更好的支持了module,当package.json中的type为module时候js默认为module。

在旧版本commonJS后缀为js,ESmodule后缀为mjs。

在新版本commonJS后缀为cjs,ESmodule后缀为js。

2.4 Babel兼容

现在我们在webpack等工具中使用模块化,大部分使用babel做兼容。

安装preset-env。(plugin-transform-modules-commonjs)。

在babelrc中配置。

2.5 webpack

webpack本身已经对两种模块进行了兼容处理,我们可以在该环境中自由使用。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值