前端模块化演进
函数封装 =》对象 =》立即执行函数 =》 CommonJS AMD
CMD
=》ES6 module & webpack
函数封装
缺点:
- 污染了全局变量
- 变量名重名
- 模块成员之间没什么关系
对象
缺点:
- 外部可以随意修改内部成员,安全问题
立即执行函数
优点:
- 模块外部无法修改没有暴露出来的变量、函数
CommonJS
CommonJS规范是由NodeJS发扬光大,模块化规范
- 定义模块
一个单独的文件就是一个模块。每一个模块都是一个单独的作用域,该模块内部定义的变量,无法被其他模块读取,除非定义为global对象
的属性。 - 模块输出
module.exports = foo;
- 加载模块
require('./foo');
服务器和浏览器差别:服务器端可同步读取、编译、执行模块,浏览器呢?
script
标签 ×
服务器端组件,对模块代码作静态分析
×
AMD
Asynchronous Module Definition
异步模块定义
AMD 是 RequireJS 在推广过程中对模块定义的规范化的产出
用到对应的库函数: requireJS
requireJS
解决两个问题:
- 多个js文件可能有依赖关系,被依赖的文件需要早于依赖它的文件加载到浏览器
- js加载的时候浏览器会停止页面渲染,加载文件越多,页面失去响应时间越长
// 模块定义
define(id?, dependencies?, factory() {
return object;
});
define(id?, dependencies?, object);
// 异步加载+回调函数
require([dependencies], function(mod){});
加载执行
: 并行预加载,预先知道依赖哪些模块,哪个先下载下来,哪个先执行。- 优点:1. 可以预先利用一些空闲时间解析模块。2. 用户体验好,依赖模块提前执行了,没有延迟
- 缺点:1. 依赖模块的执行顺序和书写顺序不一定一致。
CMD
Common Module Definitiohn
CMD 是 SeaJS 在推广过程中对模块定义的规范化产出。
SeaJS
define(id?, deps?, factory) // id(一般文件名),deps一般省略
// 定义模块 myModule.js 相当于按顺序一次下载模块,不执行
define(factory(require, exports, module) {
var $ = require('jquery');
module.exports = {$};
})
// 加载模块, 开始执行,遇到require就执行
seajs.use(['myModule.js'], function (my) {});
加载执行
:并行预加载,字符串解析一遍才知道依赖哪些模块,按顺序遇到require时再执行。- 优点:1. 执行顺序在代码中是有体现的,是可控的
- 缺点:1. 性能好,因为只有用户需要的时候才执行的原因
AMD和CMD最大的区别是对依赖模块的执行时机处理不同,注意不是加载的时机或者方式不同
layUI
layui.define([mods], function (exports) {
// ...do something (related with mods)
exports('mod', function () {
//... 输出接口
});
})
layui.use(['laypage', 'layedit'], function(laypage, layedit) {
// 使用模块
});
ES6 module webapck
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
// import CleanWebpackPlugin from './node_modules/clean-webpack-plugin';
module.exports = {
mode: 'development', // 模式配置,默认production会压缩
devtool: '', // sourceMap
entry: '', // 入口文件
output: {}, // 出口文件
module: {}, // 处理对应模块
plugins: [], // 对应的插件,在webpack运行到某个时刻的时候,帮你做一些事情
devServer: {}, // 开发服务器配置
resolve: {}, // 配置别名和省略后缀名
optimization: {}, // tree shaking, 生产环境默认有
performance: true // 性能上的一些问题警告,如代码包大小
}
// export default {}