Webpack的作用:将相互依赖的.html、.css、.js、图片、字体等资源文件经过处理打包成静态的前端项目。
为什么使用Webpack:在nodejs下开发前端项目,支持模块化开发,以及使用vue、react的js框架进行组件化开发,这样会有许多分散的文件,需要一个工具来整合这些资源文件。
webpack可以将nodejs模块化代码转换为浏览器可执行代码,它提供import、export、es6模块化的语法支持,通过分析import、export,将需要的代码加载进来,webpack中任何文件都可以通过import导入,只需要有对应的loader即可。在打包过程中,可以通过插件plugins干预打包过程,从而剔除不必要的代码,形成体积更小的项目。
依赖下载
//安装webpack
yarn init -y
yarn add webpack webpack-cli --dev //安装到开发者依赖中
npm init -y
npm install webpack webpack-cli --global //全局安装webpack(不推荐)
npm install webpack webpack-cli --save--dev //本地安装webpack webpack-cli
//与webpack有关的依赖都需要安装在--dev开发者依赖中,因为在打包后就不需要这些依赖了
//加载css文件需要安装style-loader css-loader
yarn add --dev style-loader css-loader
//插件:自动生成html文件,避免在html中手写src路径出错
yarn add html-webpack-plugin
yarn add html-webpack-plugin --dev //也需要下载到开发环境中
//使用js新特性和es6需要使用babel工具转译,安装babel-loader
yarn add --dev babel-loader @babel/core @babel/preset-env
//插件:压缩打包后的js代码,减少打包后的文件体积
yarn add --dev terser-webpack-plugin
//打包后修改代码,会自动重新打包,并刷新页面
yarn add --dev webpack-dev-server
//插件:可视化的打包分析工具,分析打包后哪个文件体积比较大,以便做下一步优化
yarn add --dev webpack-bundle-analyzer
打包命令
npx webpack //打包命令
npm run build //vue的打包命令
//两者都会默认生成一个dist文件夹,但是包里面的内容不同
- npx webpack打包,默认输出的文件夹名为dist,文件名为main.js
webpack.config.js配置文件
// 使用nodejs的path库
const path = require('path')
// 插件html-webpack-plugin可以自动打包生成一个index.html,同时也是一个构造函数,需要new一下创建实例
const HtmlWebpackPlugin = require('html-webpack-plugin')
// 插件terser-webpack-plugin是一个压缩工具,也是一个构造函数
const TerserPlugin = require('terser-webpack-plugin')
// 插件webpack-bundle-analyzer是一个可视化的打包分析工具,是一个对象,需要使用其中同名的BuddleAnalyzerPlugin构造函数
const BuddleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
// 使用nodejs的模块化语法
module.exports = {
mode: 'development',//默认 production生产环境,可以手动设置为开发环境,两种环境打包生成的代码不一样
devtool: 'inline-source-map',//设置后重新打包,可在打包文件中查看到源码转译后的代码
entry: './src/index.js',//设置入口文件路径
output: { //设置打包后的文件名以及文件路径
filename: 'dist.js', //打包的文件名固定不变,浏览器会根据文件名进行缓存。(开发环境下可用)
// 图5 - 为了避免浏览器缓存,文件名可以写成如下格式:
// filename: '[name].[contenthash].js',//[name]默认显示main,也可以手动改成其他名字,如dist;[contenthash]根据文件内容进行hash计算生成一串不重复的字符
path: path.resolve(__dirname, 'dist'),//path.resolve接收多个参数,可以指定多级目录; __dirname指当前文件webpack.config.js所在的位置
},
resolve: {
alias: { //图6 - 给导入的路径设置别名
// 别名: 真实路径
images: path.resolve(__dirname, "src/assets/images")
}
},
optimization: { //图3 - 设置是否压缩以及压缩工具
minimize: true,//是否压缩
minimizer: [new TerserPlugin()],//使用什么工具压缩
},
devServer: { //图4 - 存在代码修改后,自动重新加载,需安装webpack-dev-server工具
static: './dist',//指定devServer从哪个静态资源目录加载代码
},
plugins: [ //插件
new HtmlWebpackPlugin({ //图2 - 会自动打包生成一个index.html,并允许传参自定义网页标题
title: '博客列表',
}),
new BuddleAnalyzerPlugin() //图7 - 会在运行npx webpack时自动打开
],
module: {
rules: [ //配置扩展名匹配的loader
{ //匹配.css文件需要style-loader css-loader,注意写的顺序,否则打包的时候报错
test: /\.css$/i,//使用正则表达式匹配文件扩展名,i是忽略大小写
use: ['style-loader', 'css-loader']
},
{ // 匹配.scss文件需要style-loader css-loader scss-loader,注意写的顺序
test: /\.scss$/i,
use: ['style-loader', 'css-loader', 'scss-loader']
},
{ //图1 - 匹配图片,图片不需要匹配loader
test: /\.(png|svg|jpg|jpeg|gif)$/i,
type: 'asset/resource'
},
{ //匹配.js文件
test: /\.js$/i,
exclude: /node_modules/,//不用转译node_modules下的js文件
use: { //需要给loader传递自定义配置,使用对象形式
loader: 'babel-loader',//匹配的loader
options: {
presets: ['@babel/preset-env'] //presets指定预设转码器,可转译js新特性和es6成浏览器识别的代码
}
}
}
]
},
}
-
图1 - 图片匹配:打包的图片名生成一串随机的字符串。
-
图2 - 插件:打包时,自动生成一个html文件。网页标题默认项目名。该构造函数允许传参设置title。
-
图3 - 压缩后的代码:去掉了空白,且变量都使用了简化形式。
-
图4 - 在package.json的scripts中配置如下,输入命令yarn start即可启动webpack的devServe并自动打开浏览器。 --open是自动打开浏览器的意思。
-
图5 - 避免浏览器缓存,通过修改打包后文件名的命名格式实现。
-
图6 - 给导入的路径设置别名
-
图7 - 执行npx webpack时自动打开了BubbleAnalyzerPlugin 可视化的打包分析工具
其他问题:
已经预设了转码器,但打包后的源码还是箭头函数,并没有转译成普通函数是为啥?我用的是Webpack5.79.0,网上说目前浏览器还不能识别es6,还是需要转译成es5。有小伙伴知道的话,麻烦告诉我一下,谢谢啦~