• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
社会优先于个人
博客园    首页    新随笔    联系   管理    订阅  订阅
3.5 模块化开发

组件化和模块化

  • 模块可以理解为零件,比如轮胎上的螺丝钉
  • 组件可以理解为轮胎,具备完整功能的整体

模块化和工程化

  • 工程化类似于车间,模块化类似于零件

模块化开发的价值

避免命名冲突

  • js没有语言层面的命名空间,编写通用模块的普遍方式是将其暴露给全局作用域,但问题是无法阻止命名冲突
  • es6之前,业界通用方案是,在逻辑层面实现命名空间或者沙箱空间来弥补语言层面的缺陷
  • es6,新增的静态模块体系加入了沙箱特性,变量和函数的作用域仅限在沙箱,除非开发者故意暴露给全局作用域

便于依赖管理

  • 浏览器按照从上到下的顺序解析html文档,相邻的script标签,前一个执行完了才会解析下一个
  • 存在依赖关系的js模块,被依赖方必须在需求方之前加载
  • 前端工程化之前,就是手动控制script标签顺序来实现。缺点,项目复杂度增高维护难度增大,难以从代码中判断依赖关系。
  • 依赖管理是模块化规范的核心特征之一
  • 开发者遵循规范编写各模块之间源代码,构建工具按照规范进行解析,生成抽象语法树获取模块之间的依赖关系
  • html文件只要引入一个入口文件就行了

利于性能优化

  • 在浏览器环境下,前端模块化必须具备动态性
  • 按需加载是web性能优化的铁律之一
  • 虽然不使用模块也能实现按需加载,但模块化的依赖管理让按需加载更容易实现
  • 模块化构建工具将同步的散列的模块进行合并打包,减少http请求,提高web应用的解析速度,减少服务器并发压力
  • 细粒度的模块划分搭配动态加载令web应用的解析更加顺畅

提高可维护性

  • 命名冲突和依赖管理严重影响开发效率和维护效率,模块化解决这两个问题,必然会提高维护效率
  • 模块化的命名空间和沙箱机制,细粒度的模块划分,让单个模块更容易维护和迭代。从而提高了整个项目的维护效率

利于代码复用

  • 功能与业务弱耦合的模块可以在一定场景下复用
  • 代码复用的关键:模块本身的粒度,逻辑的设计。这些主要取决于开发者的抽象能力
  • 模块化规范对于代码复用的贡献在于提供了一系列机制和策略,便于可复用模块的实现

前端模块化发展史

  • es6之前,有commonjs,AMD,CMD
  • 这三个与ECMAScript规范并无关联
  • commonjs是面向浏览器之外的js规范,主要是nodejs开发
  • AMD,DMD是commonjs的变种,是针对浏览器的模块化开发,配合插件可以处理js意外以外的前端资源

commonjs

  • 最开始叫servejs,命名上就能看出不是定位给浏览器环境用的
  • 2009年改名为commonjs,随后被nodejs采纳为默认的模块化规范
  • commonjs是一种只适用于js的静态模块化规范,适合node.js,不适合浏览器,因为
  • 浏览器的前端资源不止js,还有css图片等,commonjs无法处理js之外的资源
  • commonjs所有模块都是同步阻塞式加载,无法实现按需异步加载

AMD/CMD

  • 在commonjs基础上,扩展了以下功能
  • 可以处理js以外的资源
  • 源码不需要编译就可以在浏览器环境下运行
  • 按需异步加载,并行加载
  • 插件系统

commonjs,AMD,CMD 三者的缺点

  • 应用场景单一,无法跨环境运行
  • 构建工具不同意
  • 不同规范的模块不能混用,模块复用性不高
  • 未来不可期

ES6 module规范

  • 推出后, commonjs,AMD,CMD开始退出舞台
  • es6 是一种静态模块体系
  • import 函数可以实现按需加载
  • es6 module是一个语言层面的规范,与应用场景无关,所以一个不涉及运行环境api的模块可以在任何场景下运行
  • 受限于浏览器的实现程序,目前针对浏览器的模块需要构建工具进行编译

webpack模块化构建

  • webpack支持commonjs,AMD,和es6 module,你可以选择任意一种进行源代码开发
  • webpack构建这三种是有细微差异的

规范差异性

  • commonjs不具备异步加载的功能,需要借助webpack的api实现异步加载
  • webpack构建AMD的异步加载模块不能定义输出的文件名称,导致文件缺乏语义化
  • es6 暂时不支持异步加载,webpack支持import函数变向实现了

异步模块构建差异性

  • AMD的异步文件名是由模块的id作为命名的一部分,没有语义,不好追踪
  • commonjs,webpack通过require.ensure api 提供定义异步文件的chunk name的参数
  • Es6,webpack不支持chunk name,但是提供了特殊的注释作为文件名
posted on 2022-03-22 13:12  社会优先于个人  阅读(53)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3