这是我参与「第四届青训营 」笔记创作活动的第5天
为什需要webpack
1. 在浏览器引入js脚本的方式有:
<!-- 引入外部的 JavaScript 文件 -->
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<!-- 引入我自己的 JavaScript 文件 -->
<script src="./scripts/common.js"></script>
复制代码
此解决方案很难扩展,因为加载太多脚本会导致网络瓶颈。同时如果你不小心更改了JavaScript文件的 加载顺序 ,这个项目可能要崩溃;一般在页面内有多个js文件且顺序颠倒可能导致bug,特别是最上面还有有引入 jquery / lodash / bootstrap 之类的外部库及框架文件时 存在依赖 。
自己引入一个js文件内嵌多个文件的引入会导致:
-
作用域问题
- 库文件在window下绑定全局变量如 $ _ 之类,本身用户文件也会绑定全局变量,会导致污染
-
文件太大
- 需要一段时间加载,会导致短暂的白屏;(拆开会随文件解析慢慢加载出一个一个部分)
-
可读性差
-
可维护性弱
2. 解决作用域问题:
在早期使用Grunt和Gulp两个工具来管理我们项目的资源
- 任务执行器 :将所有的项目文件拼接在一起(利用了js的立即调用函数表达式(IIFE) - Immediately invoked function expressions)解决了大型项目的作用域问题;当脚本文件被封装在 IIFE 内部时,你可以安全地拼接或安全地组合所有文件,而不必担心作用域冲突。基本操作原理如下:
; (function () { // 开头多加个;避免压缩后出现问题
var myName = "千锋大前端"
})()
// 当数变成立即执行的函数表达式时,表达式中的变量不能从外部访问。
// 不会污染window环境,解决了作用域问题
// *闭包
// 将其赋给一个变量=>储存执行返回的结果
var result = (function () {
var myName = "千锋大前端"
return myName
// 通过return来暴漏需要的数据=>多的可以用对象传递
})()
console.log(result) //输出暴漏的数据
复制代码
- Grunt , Gulp 解决了作用域问题。但是,修改一个文件意味着必须重新构建整个文件。拼接可以做到很容易地跨文件重用脚本,却使构建结果的优化变得更加困难。如何判断代码是否实际被使用?
- 即使你只用到 lodash 中的某个函数,也必须在构建结果中加入整个库,然后将它们压缩在一起。大规模地实现延迟加载代码块及无用代码的去除,需要开发人员手动地进行大量工作。
3. 如何解决代码拆分问题
-
Node.js 是一个 JavaScript 运行时,可以在浏览器环境之外的计算机和服务器中使用。webpack 运行在 Node.js 中。
-
当 Node.js 发布时,一个新的时代开始了,它带来了新的挑战。既然不是在浏览器中运行 JavaScript,现在已经没有了可以添加到浏览器中的 html 文件和 script 标签。那么 Node.js 应用程序要如何加载新的代码文件呢?
- CommonJS 问世并引入了 require 机制,它允许你在当前文件中加载和使用某个模块。导入需要的每个模块,这一开箱即用的功能,帮助我们解决了代码拆分的问题。
- Node.js 已经成为一种语言、一个平台和一种快速开发和创建快速应用程序的方式,接管了整个 JavaScript 世界。
- 但 CommonJS 没有浏览器支持。没有 live binding(实时绑定)。循环引用存在问题。同步执行的模块解析加载器速度很慢。虽然 CommonJS 是 Node.js 项目的绝佳解决方案,但浏览器不支持模块化
4. 如何让浏览器支持模块
- 在早期,我们应用 Browserify 和 RequireJS 等打包工具编写能够在浏览器中运行的commonJS模块 【具体操作原理参考require.js提供的require( )方法】
- 目前,我们还有一个选择,就是来自 Web 项目的好消息是,模块正在成为ECMAScript 标准的官方功能。然而,浏览器支持不完整,版本迭代速度也不够快,还是推荐上面两个早期模块实现。早期的任务构建工具基于 Google 的 Closure 编译器,要求我们手动在顶部声明所有的依赖,开发体验不好
5. 利用webpack来实现这一切
- webpack不仅可以让我们编写模块,而且还支持任何模块格式(至少在我们到达 ESM 之前),并且可以同时处理 resource 和 assets ;
- 可以打包你的 JavaScript 应用程序(支持 ESM和 CommonJS),可以扩展为支持许多不同的静态资源,例如:images , fonts 和 stylesheets ;
- webpack 关心性能和加载时间;它始终在改进或添加新功能,例如:异步地加载和预先加载代码文件,以便为你的项目和用户提供最佳体验