文章目录
WebPack
1.什么是webpack?
官方解释:
本质上,webpack 是一个用于现代 JavaScript 应用程序的_静态模块打包工具_。当 webpack 处理应用程序时,它会在内部构建一个 依赖图(dependency graph),此依赖图对应映射到项目所需的每个模块,并生成一个或多个 bundle。
webpack是一套基于NodeJS的"模块打包工具",
在webpack刚推出的时候就是一个单纯的JS模块打包工具,可以将多个模块的JS文件合并打包到一个文件中
但是随着时间的推移、众多开发者的追捧和众多开发者的贡献
现在webpack不仅仅能够打包JS模块, 还可以打包CSS/LESS/SCSS/图片等其它文件
2.为什么要分模块?
如果将所有的JS代码都写到一个文件中, 十分不利于代码的维护和复用
所以我们可以将不同的功能写到不同的模块中, 这样就提升了代码的维护性和复用性
但是当将代码写到不同模块时新的问题又出现了,
例如: 导入资源变多了, 请求次数变多了, 网页性能也就差了
例如: 不同功能都放到了不同模块中了, 那么如何维护模块之间的关系也变成一个难题了
<script src="./content.js"></script>
<script src="./header.js"></script>
<script src="./footer.js"></script> // 如果index.js中用到了footer,就会报错
<script src="./index.js"></script>
3.如何解决上述问题
- 项目上线时将用到的所有模块都合并到一个文件
- 在index.html中只导入主文件, 再主文件中再导入依赖模块
4.如何通过webpack打包js模块
4.1安装webpack
cnpm init -y
cnpm install --save-dev webpack
cnpm install --save-dev webpack-cli
4.2在终端中输入打包的指令
npx webpack index.js
注意点:
index.js就是需要打包的文件
打包之后的文件会放到dist目录中, 名称叫做main.js
5.什么是webpack配置文件?
我们在打包JS文件的时候需要输入: npx webpack index.js
这句指令的含义是: 利用webpack将index.js和它依赖的模块打包到一个文件中
其实在webpack指令中除了可以通过命令行的方式告诉webpack需要打包哪个文件以外,
还可以通过配置文件的方式告诉webpack需要打包哪个文件
6.使用webpack配置文件
6.1打包模式(mode):
- 指定打包的模式, 模式有两种
- 一种是开发模式(development): 不会对打包的JS代码进行压缩
- 还有一种就是上线(生产)模式(production): 会对打包的JS代码进行压缩
6.2入口(entry)
- 打包的入口起点,或者理解为指定需要打包的文件
6.3输出(output)
- output 属性告诉 webpack 在哪里输出它所创建的 bundle,以及如何命名这些文件。
- 主要输出文件的默认值是
./dist/main.js
,其他生成文件默认放置在./dist
文件夹中。 - 由对象构成,有两个属性
filename
指定打包之后的JS文件的名称path
指定打包之后的文件存储到什么地方
6.4映射(sourcemap)
webpack打包后的文件会自动添加很多代码, 在开发过程中非常不利于我们去调试
因为如果运行webpack打包后的代码,错误提示的内容也是打包后文件的内容
所以为了降低调试的难度, 提高错误代码的阅读性, 我们就需要知道打包后代码和打包之前代码的映射关系
只要有了这个映射关系我们就能很好的显示错误提示的内容, 存储这个映射关系的文件我们就称之为sourcemap
devtool:此选项控制是否生成,以及如何生成 source map。
- 在webpack.config.js中添加
devtool: "xxx"
, - 配置说明:(指带有此英文的作用)
eval
:不会单独生成sourcemap文件, 会将映射关系存储到打包的文件中, 并且通过eval存储- 优势: 性能最好
- 缺点: 业务逻辑比较复杂时候提示信息可能不全面不正确
source-map
: 会单独生成sourcemap文件, 通过单独文件来存储映射关系- 优势: 提示信息全面,可以直接定位到错误代码的行和列
- 缺点: 打包速度慢
inline
:不会单独生成sourcemap文件, 会将映射关系存储到打包的文件中, 并且通过base64字符串形式存储cheap
:生成的映射信息只能定位到错误行不能定位到错误列module
:不仅希望存储我们代码的映射关系, 还希望存储第三方模块映射关系, 以便于第三方模块出错时也能更好的排错
- 推荐配置:
development-->cheap-module-eval-source-map
- 只需要行错误信息, 并且包含第三方模块错误信息, 并且不会生成单独sourcemap文件
production-->cheap-module-source-map
- 只需要行错误信息, 并且包含第三方模块错误信息, 并且会生成单独sourcemap文件
6.5loader
6.5.1什么是loader
webapck的本质是一个模块打包工具, 所以webpack默认只能处理JS文件,不能处理其他文件,
因为其他文件中没有模块的概念, 但是在企业开发中我们除了需要对JS进行打包以外,
还有可能需要对图片/CSS等进行打包, 所以为了能够让webpack能够对其它的文件类型进行打包,
在打包之前就必须将其它类型文件转换为webpack能够识别处理的模块,
用于将其它类型文件转换为webpack能够识别处理模块的工具我们就称之为loader
6.5.2如何使用loader
- 通过npm安装对应的loader
- 按照loader作者的要求在webpack进行相关配置
- 使用配置好的loader
6.6watch
6.6.1什么是watch
webpack 可以监听文件变化,当它们修改后会重新编译。
watch: true,
watchOptions: {
aggregateTimeout: 300, // 防抖, 和函数防抖一样, 改变过程中不重新打包, 只有改变完成指定时间后才打包
poll: 1000, // 每隔多少时间检查一次变动
ignored: /node_modules/ // 排除一些巨大的文件夹, 不需要监控的文件夹
},
6.7webpack-dev-server(推荐)
6.7.1什么是webpack-dev-server
webpack-dev-server和watch一样可以监听文件变化
webpack-dev-server可以将我们打包好的程序运行在一个服务器环境下
webpack-dev-server可以解决企业开发中"开发阶段"的跨域问题
6.7.2步骤
-
安装 文档地址
npm install webpack-dev-server --save-dev
-
配置
-
devServer: { contentBase: "./bundle", // 打包后的目录 open: true, // 是否自动在浏览器中打开 port: 9090 // 服务器端口号 },
-
-
在
package.json
中scripts
里面的"start": "npx webpack-dev-server --config webpack.config.js"
注意点
1.配置名称
- 如果你直接输入
npx webpack
进行打包,配置文件的名称必须叫做:webpack.config.js
,否则会出错 - 如果要使用其它名称, 那么在输入打包命令时候必须通过 --config 指定配置文件名称
npx webpack --config xxx
2.打包命令简化
- 在
package.json
中的"scripts"
设置打包命令- 格式:
"test": "npx webpack (--config xxx)"
- 终端命令:
npm run test
(test
可以自己设置)
- 格式:
7.插件(plugin)
7.1html-plugin
7.1.1 什么是html-plugin
简化了 HTML 文件的创建,以便为你的 webpack 包提供服务。
7.1.2步骤
-
安装
npm install --save-dev html-webpack-plugin
-
配置webpack
-
const HtmlWebpackPlugin = require('html-webpack-plugin'); const path = require('path'); module.exports = { entry: 'index.js', output: { path: path.resolve(__dirname, './dist'), filename: 'index_bundle.js' }, /* plugins: 告诉webpack需要新增一些什么样的功能 * */ plugins: [new HtmlWebpackPlugin({ // 指定打包的模板, 如果不指定会自动生成一个空的 template: "./index.html", minify: { // 告诉htmlplugin打包之后的html文件需要压缩 collapseWhitespace: true, } })] };
-
7.2clean-plugin
7.2.1什么是clean-webpack-plugin
webpack-clean-plugin会在打包之前将我们指定的文件夹清空
应用场景每次打包前将dist目录清空, 然后再存放新打包的内容, 避免新老混淆问题
7.2.2步骤
-
安装
*npm install --save-dev clean-webpack-plugin*
-
配置
-
const { CleanWebpackPlugin } = require('clean-webpack-plugin'); plugins: [new CleanWebpackPlugin()]
-
7.3copy-plugin
7.4 css-plugin
7.4.1 什么是css-plugin
mini-css-extract-plugin是一个专门用于将打包的CSS内容提取到单独文件的插件
配置文件:
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
new MiniCssExtractPlugin({
filename: './css/[name].css',
})
----------------------替换style-loader-------------
loader: MiniCssExtractPlugin.loader,
注意点: 如果相关文件资源无法显示, 需要根据打包后的结构手动设置公开路径
options: {
publicPath: "xxx"
}
7.5HMR
7.5.1什么是HMR(HotModuleReplacementPlugin)
是热更新插件,会在内容发生改变的时候时时的更新修改的内容但是不会重新刷新网站
7.5.2 使用hmr
HotModuleReplacementPlugin是一个内置插件, 所以不需要任何安装直接引入webpack模块即可使用
-
在devServer中开启热更新
-
hot: true, // 开启热更新
-
hotOnly: true // 即使热更新不生效,浏览器也不自动刷新
-
-
在webpack.config.js中创建热更新插件
new Webpack.HotModuleReplacementPlugin()
注意点:
- (重要)HMR 绝对不能被用在生产环境。
- 如果是通过
style-loader
来处理CSS, 那么经过前面两步就已经实现了热更新 - 如果是通过
MiniCssExtractPlugin.loader
来处理CSS, 那么还需要额外配置MiniCssExtractPlugin.loader
中options:{ hmr: true}
7.5.3js模块实现hmr
if(module.hot){ // 判断是否开启热更新
module.hot.accept("./test.js", function () { // 监听指定JS模块变化
//逻辑
});
}
8.图片处理(压缩和合并)
在企业开发中为了提升网页的访问速度, 我们除了会压缩HTML/CSS/JS以外
还会对网页上的图片进行压缩和合并, 压缩可以减少网页体积, 合并可以减少请求次数
8.1压缩图片
利用image-webpack-loader/img-loader压缩图片
配置文件:
{
loader: 'image-webpack-loader',
options: {
mozjpeg: {
progressive: true,
quality: 65
},
// optipng.enabled: false will disable optipng
optipng: {
enabled: false,
},
pngquant: {
quality: [0.65, 0.90],
speed: 4
},
gifsicle: {
interlaced: false,
},
// the webp option will enable WEBP
webp: {
quality: 75
}
}
},
8.2合并图片
过去为了减少网页请求的次数, 我们需要"UI设计师"给我们提供精灵图,
并且在使用时还需要手动的去设置每张图片的位置
但是有了webpack之后我们只需要让"UI设计师"给我们提供切割好的图片
我们可以自己合成精灵图, 并且还不用手动去设置图片的位置
利用postcss-sprites/webpack-spritesmith合并图片
出现图片路径问题
解决方案:
-
在开发阶段将publicPath设置为dev-server服务器地址
-
在上线阶段将publicPath设置为线上服务器地址