模块化概述
模块化是当下前端最重要的开发范式之一。
把复杂的代码进行模块化提高开发效率。
模块化演变过程
早期前端没有预料到到现在能发展成这种规模,遗留了很多问题。
最开始是把数据分成模块
阶段一
调用
缺点:
阶段二
包裹成一个对象的方式
使用
阶段三
使用立即执行函数 提供模块的私有空间
阶段四
开始实现依赖关系
模块化规范的出现
node提供的标准
但是commonjs在浏览器中使用会有些问题。因为每次页面加载都会同步大量请求。
AMD
专门为浏览器设计的一种规范,而且还推出了一个叫require.js的库
加载模块
缺点
来看看淘宝的 sea.js + CMD
模块化标准规范
正题
上面介绍的演变过程都有些问题和缺点,如今的模块化标准基本统一。
最开始的ES modules没有被现代浏览器支持,随着webpack的出现才慢慢解决。
相比社区提出来的AMD,ESmodule更强大。
ES Modules 特性
使用
4.延迟演示
只有脚本执行完成(渲染完后)才开始加载
点击后
上面和defer属性效果一样
ES Modules 导出
这里使用 broswer sync测试
1.多个导出
2.批量导出
3.别名导出,导入时必须用别名
注意 name as default的话 会作为这个模块默认导出,导入时就必须这样
导入也可以起别名
4.默认导出
导入的时候 名字就可以随便取了
ES Modules 导入导出的注意事项
不带default是导出变量
导出的是一个内存空间,不是复制了一份,这是和node commonjs中是不同的2.而且暴露出去的是只读的,只能在内部修改
2不能外部修改,导入的模块默认为常量
ES Modules 导入用法
1.必须要完整命,这和commonjs不同
2必须完整路径
后期用打包工具是可以省略这些扩展名的。
3.必须./开头 还可以换其他俩种导入方法
4.如果导入为{} 那么不会提取任何对象,会执行(加载这个模块但不提取)
简写
4 提取所以导出的属性,把导出的属性以as的方式变为一个对象
5 动态获取import 路径
6 导出默认的同时 导出其他成员
方式2
ES Modules 导出导入成员
需要把较多的模块统一导出时候用会很方便
注意:(如果子模块导出的是default,那么导入的时候必须使用as 重命名)
ES Modules 浏览器环境 Polyfil
因为ESM是14年提出的,早期的浏览器不可能会支持,可以用下面的js文件解决,此文件支持绝大多数特性
这是个npm模块,那么我们可以通过 unpkg.com 这个网站提供的cdn服务获取
域名+文件名 回车
删除dist后面的 回车 (记得要带/不然走默认文档说明
点进去
拷贝链接
其实这个原理就是先用babel读出来然后将不识别的ESM转换,使得特性可以正常工作。
打开ie发现还不行,报promise为实现的error
解决:继续下载一个promise的polyfill,继续去cdn拿
正常打印,也就是ESM可以正常工作了
这又有个问题,如果在支持ES6的浏览器中,会被执行俩次(因为本身ESM会执行一次,然后ESMloader的polyfill又会执行一次
解决:利用script的新属性解决,添加后只会在不支持esm的浏览器中工作 (生产环境千万别用,因为是动态分析会特别慢
只有ie弹出了alert
ES Modules in Node.js - 支持情况
esm作为JS标准,会逐渐统一JS应用标准,node8.5后都支持esm了
修改扩展名msj,这个时候会提示是否修改路径,选no
运行,加上参数表示启用esm的实验特性
尝试提取系统内部模块的成员
这个是可以的
ES Modules in Node.js - 与 CommonJS 交互
如何在ESM中载入COMJS模块
也可以用exports.foo这种别名导出
注意,COMJS默认导出的是默认成员,所以导入的时候注意
ESM导出COMJS导入
node环境不支持,但是webpack打包环境中是可以的
总结
ES Modules in Node.js - 与 CommonJS 的差异
require exports module可以用esm中的 import export代替
对于_filename _dirname这俩个变量 可以通过
ES Modules in Node.js - 新版本进一步支持
也就是说不用将扩展名改为mjs了
将COMJS的文件改名为cjs扩展名,这样就可以用了
ES Modules in Node.js - Babel 兼容方案
处理早期node版本兼容,使用babel去兼容
node低版本中使用esm
原因
babel是基于插件转换的,babel本身不转换
解决:命令中后面跟个preset参数就可以了
觉得跟参数麻烦的可以
转换的是插件不是preset preset是一个集合
实验
移除preset
具体使用单个插件试试转换
运行成功!