Part2.5 模块化开发

什么是模块化开发

  • 将一个项目按照功能划分,理论上一个功能一个模块,互不影响,在需要的时候载入,尽量遵循高内聚低耦合

模块化演变过程

  • 文件引用
    • 简单的将所有的js文件统统放在一起。但是这些文件的顺序还不能出错,比如jquery需要先引入,才能引入jquery插件,才能在其他的文件中使用jquery。
    • 污染全局作用域,会导致全局变量命名冲突,依赖关系不明显,后期维护成本较高
  • 包裹全局对象
    • 设置模块成员的命名空间,只解决了命名冲突
  • IIFE (立即执行函数)
    • 闭包实现了私有成员,外部无法访问,清楚依赖关系

模块化的意义

  • 解决命名冲突
  • 管理依赖
  • 提高代码的可复用性

模块化规范

CommonJS 规范 (同步模式加载模块)
  • nodejs中提出的标准,一个文件就是一个模块,每个模块都有独立的作用域,通过module.exports导出成员,通过require函数载入模块.
  • 问题:
    • 在浏览器端使用的话,启动时加载模块,每次页面加载都会有大量同步模式请求出现,效率低下
AMD
  • AMD 使用起来相对复杂,模块JS文件请求频繁. Require.js实现了AMD规范

  • define 函数 定义模块

    • 图中 第一个参数是模块的名字,

    • 第二个参数是数组 依赖项,

    • 第三个参数是函数跟依赖项一一对应,这个函数的作用是为了给当前模块提供私有的空间,向外部导出成员的方式 return 即可

  • require 函数 加载模块

CMD规范 Sea.js实现了CMD规范

现阶段的规范统一

ES Modules
  • 目前多数的浏览器已经支持了ES Modules 可以直接通过Script去加载 设置type=module

  • 有以下特点:

    • 每个module都运行在单独的私有作用域

    • 默认是严格模式无法使用this,严格模式下是undefined

    • 通过CORS 方式请求外部js模块

    • 自动延迟执行脚本等同于script标签的defer属性一样

  • ES Modules 核心功能

    • import export 导入导出

      • 导入的成员变量是引用导出的成员存放的内存地址.

      • 导入的成员的是只读的

      • 导入可以省略 index.js,会自动加载目录下的index.js

      • 必须是./开头 或者 /开头 根目录查找,字母开头会以为是第三方模块

      • 导出的成员不是字面量对象,花括号只是语法

      • export default xxx

      • import 默认成员,{ 特定成员} from './xxx.js'

      • as xxx 导出/导入成员重命名

      • import xxx.js/import {} from './xxx.js' 直接执行模块

      • import * as a from './xxx.js' 可以拿到全部成员

  • ES Modules 在node中的使用

  • 默认commonjs规范下运行ESModule,修改文件扩展名.mjs
    node --experimenal-modules xxx.mjs

    • package.json 增加 type:module,可以直接执行
      node --experimenal-modules xxx.js
    • .cjs 告知是commonjs规范
      node --experimenal-modules xxx.cjs

兼容性支持

polyfill
  • 添加polyfill让浏览器支持最新语法,动态编译脚本,生产阶段不使用,浪费资源

babel

  • babel 是以插件形式实现的,不会转换代码.需要插件转换特性,一个插件转换一个特性
  • 安装babel yarn add @babel/node @babel/core @babel/preser-env --dev
  • 使用 yarn babel-node xxx.js --presets@babel/preset-env
  • presets 是一个插件集合,可以在.babelrc文件中配置,也可以在命令行中输入命令参数

posted @ 2020-08-16 18:48  tony_zhu  阅读(165)  评论(0编辑  收藏  举报