自 ES2015 开始,Javascript 终于有了像样的模块机制,来应对大型应用。
- 模块的一个作用就是隔离作用域,之前的作法会污染全局变量 (Global Space)。
- 另一作用是更好的重用。
## Back & forward
CommonJS Module
1 | const fs = require('fs') |
ES Modules (ESM)
看起来简单、清爽、好用。
1 | import fs from 'fs' |
## export 用法
首先,先看下常见的两种 export 用法:
Named exports
1 | # export 一个类 |
这些类,方法,属性,在 import 时,方式如下:
1 | # import 单个 |
Default exports (one per module)
1 | # export 一个类 |
这些类,方法,属性,在 import 时,方式如下:
1 | # Default 的 export 可以直接引用 |
Mix exports
Default 只能有一个。Named export 可以有多个,但二都可以同时使用。
1 | # 以 React.js 为例(这里 export 不是 ES2015 的写法): |
然后使用时,就可以这样 import 会很方便。
1 | import React, { Component } from 'react'; |
## Namespace imports
模块对象
有时候,一个模块中有太多这样的小的方法,属性,一个个写的话比较繁琐,好在 ES2015 Modules 提供了一种优雅的方案:
1 | import React, * as ReactUtils from 'react'; |
import *
时,导入的其实是一个模块命名空间对象,模块将它的所有属性都导出了。
然后就可以这样调用函数了: ReactUtils. Component
。
## Static module structure
聚合模块
这是个人认为较好的一种实践,程序包中主模块的代码比较多,为了简化使用者更方便 import。可以用一种统一的方式将其它模块中的内容聚合 (Mix exports) 在一起导出。
一般会在根目录下建立一个 index.js 文件,然后在其中,整理好对应的 export。
可以参见 AntDesign
1 | # 总 component 的 export 写法 |
## Practice
如果模块默认输出一个函数,函数名的首字母应该小写。
1 | function makeStyleGuide() { |
如果模块默认输出一个对象,对象名的首字母应该大写。
1 | const StyleGuide = { |
如果模块只有一个输出值,就使用export default,如果模块有多个输出值,就不使用export default,不要export default与普通的export同时使用。
## ESM with Node (node.mjs)
Node 的官方讨论,如何在 node 中支持 ES2015 Modules。目前有三种方案:
- ‘use module’
- myModuleName.mjs
- Automatic Detection (is import/export exist)
- Info in package.json
看 ESP 规范,最后的方案是判断文本中是否含有 import
或 export
,备选方案是 .mjs
后缀。
## Path Finder
查找路径有三种方式,
- 相对路径
import Menu from ./menu
- 绝对路径
import Menu from /menu
- npm_module
import Menu from menu
## import 所有语法
作为备注,这里记下 import 所有的用法:
1 | import defaultMember from "module-name"; |
## REF::