前言
- webpack打包理念是?流程是如何进行的?
- 常用 Loader 有哪些?如何配置?
- 常用插件(Plugin)有哪些?如何的配置?
- Babel 的如何配置?
为了回答上述问题,特此记录。 github 地址
历史与缘由
打包工具出现前,前端正面临着许多问题:
- 前端资源变得越来越多,难以手动管理;
- 必须严格按照依赖顺序书写代码;
- 开发环境与生产环境一致,新语言特性难以引入;
- css预处理器难以接入
- js,file,css资源管理模型不一致(?)
webpack本身也是一种资源打包工具,它的功能包含且不止以下:
- 多份资源文件打包成一个文件
- 支持babel,eslint,typescript,less,sass等
- 支持模块化处理css,图片等资源文件
- 支持HMR+开发服务器
- 支持代码分离
- 支持Tree-shaking
- 支持Sourcemap
- ...
那么我们如何使用它呢?一般来说,现在新建前端项目都是用框架了,比如 React 和 Vue 都有自带的 cli 工具和初始化 Demo,但是为了使用别人的工具的时候也不迷茫,所以我们要明白现在的前端项目在打包时,主要做的事和怎么去做这两个问题。于是就有了这篇学习笔记。
配置
webpack官网明显说出自身有一些核心概念:
- 入口(entry)
- 输出(output)
- loader
- 插件(plugin)
- 模式(mode)
- 浏览器兼容性(browser compatibility)
- 环境(environment)
这里不再赘述,本文着重于配置一个与前端框架无关的现代前端开发环境。
安装依赖
npm install webpack webpack-cli -D
注意:本文的 webpack 版本为 ^5.69.1,webpack-cli 版本为 ^4.9.2.
工作模式
自从 webpack 升级到4.x版本,可以无配置打包(需要使用与默认路径相同的文件目录) 但是一般都需要一个 webpack.config.js 配置文件来应对各种状况,如下是一个基本配置:
const path = require('path')
module.exports = {
entry: './src/index', //入口文件
output: {
fileName: 'bundle.js',
path: path.join(__dirname,'dist'),
},
mode: 'development',
}
配置 babel
没有 babel 的项目不能说是现代前端项目。
安装依赖
npm install @babel/core babel-loader @babel/preset-env -D
// webpack.config.js
module.exports = {
...
module: {
rules: [
{
test: /\.jsx?$/,
use: ['babel-loader'],
exclude: /node_modules/ //排除 node_modules 目录
},
...
]
}
}
# .babelrc
{
"presets": ["@babel/preset-env"]
}
mode
● none(默认): 不使用优化选项(=production) ● development : 打包快速,省了代码优化步骤 ● production : 打包比较慢,会开启 tree-shaking 和 压缩代码
处理 CSS
webpack 核心不能识别非 JavaScript 和非 JSON 文件,为了能够识别其他类型的文件,使用 loader 来做源码转换。 ● 识别 CSS,此配置能识别 less 预处理器并能自动根据浏览器添加前缀
...//前文配置
module: {
rules: [
{
test: /\.(le|c)ss$/,
use: ['style-loader', 'css-loader', 'postcss-loader', 'less-loader'],
exclude: /node_modules/
}
]
}
}
上面的配置需要安装如下依赖:
npm install css-loader less less-loader postcss-loader postcss-preset-env -D
并在项目根目录增加一个 postcss.config.js 的配置文件,方可生效
module.exports = {
plugins: [
[
'postcss-preset-env',
{
// 其他选项
},
],
],
};
样式分离
style-loader 是通过 head 标签加载 CSS,通过 mini-css-extract-plugin 插件可以进行样式分离,将 CSS 通过文件的方式引入。 让我们来安装它
npm install mini-css-extract-plugin -D
修改 webpack.config.js 配置
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
...
plugins: [
new HtmlWbpackPlugin({
template: './public/index.html',
filename: 'index.html',
}),
...
]
图片和字体文件
webpack5 已经内置file-loader和url-loader了,但是很多都在用v4版本,所以也记一下
图片常用三个 loader,file-loader , url-loader , img-loader
url-loader 当图片小于 limit 值的时候,会将图片转为 base64 编码,大于 limit 值的时候依然是使用 file-loader 进行拷贝,img-loader 用来压缩图片
{
test: /\.(jpe?g|png|gif)$/i,
use:[
{
loader: 'url-loader',
options: {
name: '[name][hash:8].[ext]',
// 文件小于 50k 会转换为 base64,大于则拷贝文件
limit: 50 * 1024
}
}
]
},
}
字体
- 项目中,新建 ./src/fonts 文件夹来存放字体文件
- 引入到入口文件
- 在文件中使用
- 增加字体文件的配置
// 2. 引入字体图标文件 eg:index.js
import './fonts/iconfont.css'
// 3. 在文件中使用
<!-- 使用字体图标文件 -->
<i class="iconfont iconClassName"></i>
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
}
在浏览器打开前端项目 & 热更新
● 如何在浏览器看到项目
主要用到 HtmlWbpackPlugin 这个插件,安装它
npm install html-webpack-plugin -D
然后修改 webpack.config.js 文件
//首先引入插件
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
//...
plugins: [
//数组 放着所有的webpack插件
new HtmlWebpackPlugin({
template: './public/index.html',
filename: 'index.html', //打包后的文件名
minify: {
removeAttributeQuotes: false, //是否删除属性的双引号
collapseWhitespace: false, //是否折叠空白
},
// hash: true //是否加上hash,默认是 false
})
]
}
在根目录新建一个 public 目录,新建一个 index.html 文件,内容快捷生成即可。 此时运行 npx webpack 就可以在 dist 文件夹下看到生成的 html 文件了,并且引入了打包好的 JavaScript 文件。
● 热更新 主要用到 webpack-dev-server 这个工具,乘此机会也把命令改改。
- 安装依赖
npm install cross-env webpack-dev-server
cross-env 是用来兼顾 mac 和 windows 两个系统
- 修改 package.json
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "cross-env NODE_ENV=development webpack",
"build": "cross-env NODE_ENV=production webpack",
"server": "cross-env NODE_ENV=development webpack-dev-server"
},
- 修改 webpack.config.js 文件
module.exports = {
//...
plugins: [
//数组 放着所有的webpack插件
new HtmlWebpackPlugin({
template: './public/index.html',
filename: 'index.html', //打包后的文件名
minify: {
removeAttributeQuotes: false, //是否删除属性的双引号
collapseWhitespace: false, //是否折叠空白
},
// hash: true //是否加上hash,默认是 false
})
],
devServer: {
port: '3000', //默认是8080
compress: true //是否启用 gzip 压缩
}
}
运行 npm run server 命令,打开 'http://localhost:3000' 即可看到 html 展示效果,并且能实时根据源文件变动而实时构建。 源码调试 devtool 中的一些设置,可以帮助我们将编译后的代码映射回原始源代码。不同的值会明显影响到构建和重新构建的速度。 开发环境配置:eval-cheap-source-map ,生产环境选择:none(默认)或者 source-map ;因为开发阶段要调试代码,需要错误发生的详细地址(行与列),而生产环境则需要一点混淆。