本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图**(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。
webpack 可以通过 loader 和 plugin 来扩展打包能力
- 例如 css-loader 来支持打包 css 文件…
- TerserPlugin 来做打包体积优化
逻辑多、文件多,项目的复杂度提高了
他还能解释高级特性、语言(typescript / ES6 语法),这些代码直接在浏览器里写,可能浏览器无法识别,这时 webpack 就充当了翻译官的角色
提供了一些小插件
webpack 不仅强大,而且灵活(可插拔设计,需要的时候用,不需要的时候也可以移除掉,并没有绑定死)
入门的误区规避
作用域
命名空间
模块化
作用域
保护对象的属性,不暴露出来,防止被随意篡改(模块作用域)
var SusanModule = (function() {
var name = "Susan"
var sex = "女孩"
return {
tell: function() {
console.log("我的名字是", name)
console.log("我的性别是", sex)
}
}
})()
较早期的模块实现方式(挂载到了 window 全局(浏览器的 window 对象是全局作用域))
(function(window) {
var name = "Susan"
var sex = "女孩"
function tell() {
console.log("我的名字是", name)
console.log("我的性别是", sex)
}
window.SusanModule = { tell }
})(window)
作用域封装
重用性
解除耦合(提升系统的可维护性,降低维护成本)
// 求和模块的定义
define("getSum", ["math"], function (math) {
return function (a, b) {
console.log("sum:" + math.cum(a, b));
}
});
// 通过 require 函数来引入
const math = require("./math");
// 通过 exports 将其导出
exports.getSum = function (a, b) {
return a + b;
}
(上述两个方案的共同特性是规定模块的依赖必须显示引入,方便维护不同模块时,不必去操心引入顺序的问题)
// import 导入
import math from "./math";
// export 导出
export function sum(a, b) {
return a + b;
}
Gulp、GRUNT:帮助我们实现模块化构建的工具(比较老的工具库了)
webpack 与立即执行函数之间的关系
webpack 打包的核心逻辑
观察打包出来的结果,是一个立即执行函数
打包出来文件的大致结构:
(function(module) {
var installedModules = {};
function __webpack_require__(moduleId){
// SOME CODE
}
// 。。。
return __webpack_require__(0); // entry file
})([ /* modules array */])
上述结构中的核心方法
function __webpack_require__(moduleId){
// check if module is in cache
if(installedModules[moduleId]){
return installedModules[moduleId].exports;
}
// create a new module (and put into cache)
var module = installedModules[moduleId] = {
i: moduleId,
l: false,
exports: {}
};
// exe the module func
modules[moduleId].call{
module.exports,
module,
module.exports,
__webpack_require__
};
// flag the module as loaded
module.l = true;
// return the exxports of the module
return module.exports;
}
理解包管理器
熟悉 npm 核心特性
理解 npm 仓库
与 依赖
的概念
理解 npm 语义化版本
掌握使用 npm 自定义工程脚本的方法
推荐将 npm 的仓库源设为国内的 淘宝源
- 在工作中发现很多文章博客都提出,不要使用 cnpm 工具,如果为了下载更快,推荐使用 淘宝源,而不是 cnpm
- 设置为 淘宝源 …
仓库名名称(npm install 名称、若要上传 npm,就要保证唯一)
语义化版本(npm install 的时候会自动选版本)
^version: 中版本和小版本
^1.0.1->1.x.x
~version: 小版本
~1.0.1->1.0.x
version: 特定版本
1.0.1->1.0.1
可以定义一些命令(如启动服务、语法检查、webpack 打包等)
"dev": "webpack-dev-server"
"build": "eslint .... && webpack"
定义好的命令常见用法
删掉重装有时解决不了问题,是这里面写的版本有问题(而不是依赖顺带安装的)
npm install echarts -s
npm install echarts -d
npm install webpack-cli -g
全局安装,这样我们就可以直接在命令行里运行 webpack 命令了(一般在项目根目录执行 webpack 进行打包)
// webpack.config.js
const path = require("path")
module.exports = {
entry: "./app.js",
output: {
path: path.join(__dirname, "dist"),
filename: "bundle.js"
}
}
webpack-dev-server
(命令行命令(需要安装全局 webpack-dev-server),不安装也可以,直接执行 ./node_modules/.bin/webpack-dev-server
)
(有 webpack 的项目中,可以在 js 文件里引入 图片、css、less、scss 等,webpack 会去处理这些依赖 => 需要引入对应的 loader ,并且没有意义)
npm install css-loader style-loader --save-dev
并在 webpack 中配置 loader
做资源的处理、压缩(去除代码中不必要的内容,注释、换行…)
npm install uglifyjs-webpack-plugin -save-dev
并在 webpack 中配置 plugin(uglifyjs 是用来压缩代码体积的插件)并没有记全
新建项目文件,在根目录下 npm init
初始化一个项目(npm init -y
≈ 使用 npm 默认配置项,不需要一路回车设置项目名等)
npm install react react-dom
npm install webpack webpack-cli -g
创建 src/App.jsx
…
并不是所有的浏览器都支持 ES6 语法的,必须是版本比较高一些,比较新一些的浏览器才支持这个语法
npm install @babel/core @babel/cli -g
(在全局)npm install @babel/preset-env
这个包,可以把 高版本的 JS 语法转换成低版本的
"babel": { "presets": ["@babel/preset-env"] }
babel test.js --presets=@babel/preset-env
webpack 本身只处理ES5版本及以下的JS,ES6语法直接放在 webpack 下打包,肯定会报错的
html 在 webpack 中怎么处理
npm install babel-loader
babel 的 loader
npm install @babel/preset-env @babel/preset-react
语法解析规则
安装完后在 webpack 中配置使用
npm install html-webpack-plugin -d
并在 webpack 中配置
webpack 打包
(可以加 --config 指定配置文件,–open 直接使用浏览器打开…)
(webpack 5.x 和 html-webpack-plugin 不太兼容,有问题,所以按视频的操作跑不起来,需要指定版本)
webpack --mode production
打包会自动给我们做代码压缩等操作,优化打包结果,当然我们也可以定制打包结果(压缩插件 uglifyjs => uglify-es => terser…)
webpack-bundle-analyzer 插件可以用来让我们可视化的看我们的打包结果,根据可视化可以看出哪些文件的体积最大/过大,然后做一个针对性的优化,有没有改动的余地
npm install webpack-bundle-analyzer
并在 webpack 中做配置
加快构建速度
node 和 webpack 都是单进程的,所以一般优化都是在 线程的程度上
前端技术的蓬勃发展
我们想在 js 里面更方便地实现 html ,社区就有了 jsx
我们觉得原生的 css 不够好用,社区就给了我们 sass 和 less
针对前端模块化开发越来越强的需求,社区有了 AMD、COMMONJS、ES2015等等的方案
但这些方案大多并不被浏览器直接的支持,所以说往往伴随着这些新技术而生的还有另外一些让这些新技术应用于浏览器的方案
前端工程化的过程,真的是让我们开发者大费精力,人们也是纷纷在寻找前端模块化的过程中才知晓了 webpack,webpack 的流行确实是得益于野性发展的前端,但它的本质是一个前端模块化打包的一个解决方案,更重要的是它又是一个可以融合运用各种前端新技术的平台
学习的参考视频:【2020新课程】Webpack从原理到实战完整版-深入浅出,简单易学,前端工程师必学经典内容!
别人写的笔记:webpack学习笔记:发展背景、工作机制、核心配置、性能优化
关于webpack项目中报错:Error: Cannot find module ‘webpack/lib/node/NodeTemplatePlugin’ 的解决办法
Webpack 5: The ‘compilation’ argument must be an instance of Compilation #1451
【webpack】HtmlWebpackPlugin插件报错,The ‘compilation‘ argument must be an instance of Compilation
webpack超详细配置, 使用教程(图文)(2017-05-06 的博客,有点老了,不知道价值怎么样)