模块化演变
CommonJS 标准
- 一个文件就是一个模块
- 每个模块都有独自的作用域
- 通过 module.exports 导出成员
- 通过 require 函数载入模块
- 同步模式加载模块
因为同步模式加载模块,不实用浏览器,于是呈现了
AMD(Asynchronous Module Definition 异步模块定义标准)并呈现了 Require.js,实现了 AMD 标准, 用define
定义。然而应用起来绝对简单,模块 JS 文件申请频繁
EsModule
个性
1,通过给 script 增加 type = module
的属性,就能够以 ES Module 的规范执行其中的 JS 代码了
<script type="module">
console.log('this is es module')
</script>
2,ESM 主动采纳严格模式,疏忽 'use strict'
<script type="module">
console.log(this) // 会打印 undefined
</script>
3, 每个 ES Module 都是运行在独自的公有作用域中
<script type="module">
var foo = 100
console.log(foo)
</script>
<script type="module">
console.log(foo) // undefined
</script>
4,ESM 是通过 CORS 的形式申请内部 JS 模块的
5,ESM 的 script 标签会提早执行脚本
导出
导出的只是一个援用,导出的是寄存值得地址
export {name,age}
导入
导入中的 from
不能省略掉 .js
文件名, 须要填写残缺文件路径名。也能够应用残缺 URL 来加载文件.import
不能放在相似 if
这种嵌套语法中,须要放在文件顶层。如果须要动静加载,应用 import()
函数,返回一个promise
。
import('./module.js').then(function(module){console.log(module) // 返回对象在 module 中
})
如果导出内容很多,有多个对象,还有一个 default
。导入的时候其余对象能够失常导入,如果想导入import
成员,须要重命名
export {a,b}
export default "c";
//---------------------
import {a,b default as c} from "module.js"
// 或者如下,tilte 能够随便命名
import title,{a,b} from "module.js"
导出导入成员
我的项目中常常会呈现一些专用模块,比方 component
,business
,page
等相似的公众区域,
应用的时候挨个导入会很麻烦,能够新建一个 index.js
文件,对立导出
import {comA} from "./comA.js
import {comB} from "./comB.js"
export {comA,comB}
ESM 兼容性问题
因为市面上存在一些浏览器不兼容 ESM,除了 webpack 打包编译转换为 ES5 等形式外,有一个浏览器环境 polyfill。间接引入 unpkg
网站的两个 cdn
链接,IE 不反对 promise,还须要引入 promise 的 polyfill
<script nomodule src="https://unpkg.com/promise-polyfill@8.1.3/dist/polyfill.min.js"></script>
<script nomodule src="https://unpkg.com/browser-es-module-loader@0.4.1/dist/babel-browser-build.js"></script>
<script nomodule src="https://unpkg.com/browser-es-module-loader@0.4.1/dist/browser-es-module-loader.js"></script>
如果在 script
标签中退出 module
属性,只会在不兼容 ESM 标准的浏览器中运行
<script type="module">
Es Module 和 Node.js 交互
Node.js 8.5 版本之后,开始实验性应用 ESM。
论断:
- ES Module 中能够导入 CommonJS 模块
- CommonJS 模块始终只会导出一个默认成员
- ESM 中不能间接提取 CMS 成员,留神 import 不是解构导出对象
- 不能在 CommonJS 模块中通过 require 载入 ES Module
ESM in Node.js 与 CMS 模块差别
- ESM 中没有 CommonJS 中那些模块全局成员(require, module, exports,__filename,__dirname)
- require, module, exports 能够通过 import 和 export 代替
-
__filename 和 __dirname 在 ESM 中能够通过 import 对象的 meta 属性获取
// 通过 url 模块的 fileURLToPath 办法转换为门路 import {fileURLToPath} from 'url' import {dirname} from 'path' const __filename = fileURLToPath(import.meta.url) const __dirname = dirname(__filename) console.log(__filename) console.log(__dirname)
注意事项
如果须要在type=module
的状况下持续应用 CommonJS,
须要将文件扩展名批改为.cjs