模块化
模块化是指把一个复杂的系统分解到多个模块以方便编码。
CommonJS
核心思想是通过 require 方法来同步地加载依赖的其他模块,通过 module.exports 导出需要暴露的接口
// 导入
const moduleA = require('./moduleA');
// 导出
module.exports = moduleA.someFunc;
优缺点:
- 优点:代码可复用于 Node.js 环境下并运行,例如做同构应用;通过 NPM 发布的很多第三方模块都采用了 CommonJS 规范。
- 缺点:这样的代码无法直接运行在浏览器环境下,必须通过工具转换成标准的 ES5。
AMD
采用异步的方式去加载依赖的模块。
AMD 规范主要是为了解决针对浏览器环境的模块化问题,最具代表性的实现是 requirejs
// 定义一个模块
define('module', ['dep'], function(dep) {
return exports;
});
// 导入和使用
require(['module'], function(module) {
});
优缺点:
- 可在不转换代码的情况下直接在浏览器中运行;
- 可异步加载依赖;
- 可并行加载多个依赖;
- 代码可运行在浏览器环境和 Node.js 环境下。
- 缺点在于JavaScript 运行环境没有原生支持 AMD,需要先导入实现了 AMD 的库后才能正常使用。
ES6 模块化
是欧洲计算机制造联合会 ECMA 提出的 JavaScript 模块化规范,将逐渐取代 CommonJS 和 AMD 规范,成为浏览器和服务器通用的模块解决方案
缺点在于目前无法直接运行在大部分 JavaScript 运行环境下,必须通过工具转换成标准的 ES5 后才能正常运行
// 导入
import { readFile } from 'fs';
import React from 'react';
// 导出
export function hello() {};
export default {
// ...
};
常见的构建工具及对比
构建就是,把源代码转换成发布到线上的可执行 JavaScrip、CSS、HTML 代码,包括如下内容。
- 代码转换:TypeScript 编译成 JavaScript、SCSS 编译成 CSS 等。
- 文件优化:压缩 JavaScript、CSS、HTML 代码,压缩合并图片等。
- 代码分割:提取多个页面的公共代码、提取首屏不需要执行部分的代码让其异步加载。
- 模块合并:在采用模块化的项目里会有很多个模块和文件,需要构建功能把模块分类合并成一个文件。
- 自动刷新:监听本地源代码的变化,自动重新构建、刷新浏览器。
- 代码校验:在代码被提交到仓库前需要校验代码是否符合规范,以及单元测试是否通过。
- 自动发布:更新完代码后,自动构建出线上发布代码并传输给发布系统。
Npm Script
Grunt
Gulp
- 基于流的自动化构建工具。 除了可以管理和执行任务,还支持监听文件、读写文件
- 通过 gulp.task 注册一个任务;
- 通过 gulp.run 执行任务;
- 通过 gulp.watch 监听文件变化;
- 通过 gulp.src 读取文件;
- 通过 gulp.dest 写文件。
Fis3
Webpack
- Entry:入口,Webpack 执行构建的第一步将从 Entry 开始,可抽象成输入。
- Module:模块,在 Webpack 里一切皆模块,一个模块对应着一个文件。Webpack 会从配置的 Entry 开始递归找出所有依赖的模块。
- Chunk:代码块,一个 Chunk 由多个模块组合而成,用于代码合并与分割。
- Loader:模块转换器,用于把模块原内容按照需求转换成新内容。
- Plugin:扩展插件,在 Webpack 构建流程中的特定时机注入扩展逻辑来改变构建结果或做你想要的事情。
- Output:输出结果,在 Webpack 经过一系列处理并得出最终想要的代码后输出结果。
Rollup