模块化演变

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.jsimport {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