没有webpack的缺点:
代码量大时,可读性不好
函数间依赖严重,维护性不好
协作开发,容易变量命名冲突
我们引入js标签的问题:
如果一个script不好维护
- 当script标签很多会有性能问题: 同步加载会阻塞,异步加载浏览器网络请求只能加载6个js文件
2. 作用域问题: 可能会导致全局变量污染
// add.js文件
function add(a, b) {
console.log( a + b )
}
function display(val) {
console.log(val)
}
// 该函数只想在add.js文件内部使用 但是引入到html文档中,会被污染
模块化第一步:
改进:使用立即执行函数,并暴露需要的方法
(function() {
function add(a, b) {
console.log( a + b )
}
function display(val) {
console.log(val)
}
window.add = add;
// 暴露方法
})()
问题: 引入依赖的问题
方法执行之前要引入模块
<script>
add(1, 2) // 方法还没引入就执行,报错
math(1, 2) // 方法还没引入就执行,报错
</script>
<script src="./add.js"></script>
<script src="./math.js"></script>
在模块中包含其他模块: 必须要先引入其他模块,不然会报错
// math.js文件
(function(){
add(1, 3) // add模块 在html文档中,要比math模块提前引入
function math(a, b) {
console.log( a * b )
}
window.math = math;
})()
解决: gulp grunt等工具
解决方式: 在模块中告诉需要先引入其他模块
/**
* add.js
*/
// 在注释中告诉要引入该模块之前引入上面的模块(使用工具后自动添加)
(function(){
add(1, 3)
function math(a, b) {
console.log( a * b )
}
window.math = math;
})()
问题1: 我们修改了一个文件,可能就打破了依赖
问题2: Dead Code(只使用一个方法,但会引入整个库,占空间;对比在webpack中,没被引入的方法会自动删除)
模块化第二部:
Node commonJS: 只引入执行的方法,不会整个库引入
使用方法: 从模块文件导出,导入到入口文件
导出: add.js模块文件
// add.js模块文件
function add(a, b) {
console.log( a + b )
}
function display(val) {
console.log(val)
}
module.exports = add; // 导出方法
导入: 入口文件main.js
// 导入文件
var add = require('../add') // 后缀自动识别
var math = require('../math') // 后缀自动识别
add(1, 2) // 可以在node中直接执行
math(3, 4) // 可以在node中直接执行
问题: 没有浏览器的支持,直接引入会报错: require is not defined
解决: 打包工具 browerify (webpack之前的)
解决方式: 把./node/main.js文件作为入口文件,打包生成一个文件./dist/main.js(正常的js文件),browerify会自动处理里面变量冲突的问题,然后在html文件中引入该js文件即可。
问题: commonJS语法是静态的
描述: 有些功能用户仅需要按需加载,browerify会把所有js模块打包成一个大大的js文件,加载到html中的时候,会导致用户在第一次加载的时候很慢(webpack还可以把这里打包出来的文件再进行分割(软加载,自动处理))
模块化第三部:
异步加载js模块文件(以过渡)
AMD: Require.js
使用数组方式异步加载js模块,但是模块依赖太严重会自动打包成很大的js文件。
//my/shirt.js now has some dependencies, a cart and inventory
//module in the same directory as shirt.js
define(["./cart", "./inventory"], function(cart, inventory) {
//return an object to define the "my/shirt" module.
return {
color: "blue",
size: "large",
addToCart: function() {
inventory.decrement(this);
cart.add(this);
}
}
}
);
CMD: Sea.js(国内开发)
问题: 太动态 打包出来很膨胀
模块化第四部:
推出模块化标准:没出标准之前有人使用AMD,有人使用CMD,需要一个机制来配合,出标准后不再需要处理这些。
问题: 2015年才推出,以前的浏览器不支持。
解决方案: 需要在script type='module'
解决方案: 推出了Webpack:
任意模块化的语法都支持
按需加载 异步打包
工具的集合