简介常用webpack配置
准备
知识储备
本文主要记录常用的配置,适对webpack有一些基础了解的同学,未了解webpack的可移步下方的官方文档的简介。
webpack四个核心概念
- 入口(entry): 指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始。
- 输出(output): 告诉 webpack 在哪里输出它所创建的 bundles,以及如何命名这些文件,默认值为 ./dist。
- loader: 让 webpack 能够去处理那些非 JavaScript 文件。
- 插件(plugins): webpack提供很多钩子可以让开发者进行二次开发插件,完成很多丰富的功能。
本文也主要围绕这四个概念,介绍webpack常用的插件等的配置。
loader和plugin的区别
- loader:由于webpack只能识别js,loader相当于翻译官的角色,帮助webpack对其他类型的资源进行转译的预处理工作。
- plugins:plugins扩展了webpack的功能,在webpack运行时会广播很多事件,plugin可以监听这些事件,然后通过webpack提供的API来改变输出结果。
配置示例
webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 通过 npm 安装
module.exports = {
entry: './path/to/my/entry/file.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'my-first-webpack.bundle.js'
},
module: {
rules: [
{ test: /\.txt$/, use: 'raw-loader' }
]
},
plugins: [
new HtmlWebpackPlugin({template: './src/index.html'})
]
};
一、开发工具
1. webpack-dev-server
webpack-dev-server会在本地开启一个服务,方便本地开发
安装依赖,配置好webpack.config.js后运行下面命令即可看到浏览器中打开的页面
webpack-dev-server --config webpack.config.js
- 安装依赖:
npm i -D webpack webpack-dev-server html-webpack-plugin
- 配置示例:
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
const webpack = require('webpack');
module.exports = {
mode: 'development',
devServer: {
port: 8080,
hot: true,// 局部更新
compress: true,//是否压缩
open: true,// 自动打开浏览器
contentBase: 'dist'
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
filename: 'index.html',
}),
new webpack.HotModuleReplacementPlugin(),
]
}
2. mock模拟数据
如果本地开发时想使用mock模拟数据来响应页面中的ajax请求,那么就需要特殊配置一下,详情请见我的另一篇文章。
二、常用loader
1. css、less、sass相关配置
- 安装依赖:
npm i -D style-loader css-loader less-loader
- 配置示例:
module.exports = {
module: {
rules: [
// 规则 css-loader主要解析我们样式中@import语法, 执行顺序是重右向左执行 - >重下到上
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
]
},
{
test: /\.less$/,
use: [
'style-loader',
'css-loader',
'less-loader'
]
}
]
}
};
2. 自动为css3样式加上-webkit等浏览器兼容前缀
使用 postcss,需要使用 postcss-loader 和 autoprefixer
- 安装依赖:
npm i -D postcss-loader autoprefixer
- 配置示例:
[{
test: /\.css$/,
use: [
'style-loader',
'css-loader',
'postcss-loader', // 给css3的样式加上-webkit等浏览器兼容前缀
]
},
{
test: /\.less$/,
use: [
'style-loader',
'css-loader',
'postcss-loader', // postcss-loader 放置在 css-loader 右边
'less-loader'
]
},
{
test: /\.scss/,
use: [
'style-loader',
'css-loader',
'postcss-loader',
'sass-loader'
]
}]
- 项目根目录下添加 postcss 的配置文件: postcss.config.js
module.exports = {
plugins: [
require('autoprefixer')({
browsers: [
// 加这个后可以出现额外的兼容性前缀
"> 0.01%"
]
})
]
}
3. 图片loader
file-loader和url-loader都是用来处理图片、字体图标等文件。
url-loader工作时分两种情况:
- 当文件大小小于limit参数,url-loader将文件转为base-64编码,用于减少http请求;
- 当文件大小大于limit参数时,调用file-loader进行处理;
因此我们优先使用url-loader,首先还是进行安装,安装url-loader之前还需要把file-loader先安装;
另外html上引用一个图片,为了使打包后的html不是引用了原目录下的图片,需要使用html-withimg-loader
- 安装依赖:
npm i -D file-loader url-loader html-withimg-loader
- 配置示例:
{
//省略其他配置
rules: [{
test: /\.(png|jpg|gif|jpeg|webp|svg|eot|ttf|woff|woff2)$/,
use: {
loader: 'url-loader',
options: {
//10k
limit: 10240,
//生成资源名称
name: '[name].[hash:8].[ext]',
//生成资源的路径
outputPath: 'imgs/',
esModule: false
},
exclude: /node_modules/,
}
},{
test: /\.(htm|html)$/,
use: {
loader: 'html-withimg-loader'
}
}]
}
4. vue-loader
使用 vue-loader,注意加入VueLoaderPlugin以及
- 参考:Vue Loader中文文档
- 安装依赖:
npm install -D vue-loader vue-template-compiler
- 配置示例:
// webpack.config.js
const VueLoaderPlugin = require('vue-loader/lib/plugin')
module.exports = {
mode: 'development',
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader'
},
// 它会应用到普通的 `.js` 文件
// 以及 `.vue` 文件中的 `<script>` 块
{
test: /\.js$/,
loader: 'babel-loader'
},
// 它会应用到普通的 `.css` 文件
// 以及 `.vue` 文件中的 `<style>` 块
{
test: /\.css$/,
use: [
'vue-style-loader',
'css-loader'
]
}
]
},
plugins: [
// 请确保引入这个插件来施展魔法
new VueLoaderPlugin()
]
}
5. svg-loader
使用svg有以下四种方式:
- 直接当作图片使用: 背景图片或img标签的src属性
- raw-loader: 解析svg为文本,当作dom节点使用
- svg-inline-loader: 压缩svg代码
- svg-sprite-loader: 和vue一起使用
直接使用
css
body {
background-image: url(./svgs/activity.svg);
}
html
<img src="./svgs/activity.svg"/>
raw-loader
raw-loader 可以把文本文件的内容读取出来,注入到 JavaScript 或 css 中去。
由于 raw-loader 会直接返回 svg 的文本内容,并且无法通过 css 去展示 svg 的文本内容,因此采用本方法后无法在css中导入svg。
也就是说在 css 中不可以出现 background-image: url(./svgs/activity.svg) 这样的代码,因为 background-image: url(<svg>...</svg>) 是不合法的。
配置
module.exports = {
module: {
rules: [
{
test: /\.svg$/,
use: ['raw-loader']
}
]
}
};
使用
import svgContent from './svgs/alert.svg';
window.document.getElementById('svg').innerHTML = svgContent;
svg-inline-loader
svg-inline-loader 和上面提到的 raw-loader 非常相似, 不同在于 svg-inline-loader 会分析 SVG 的内容,去除其中不必要的部分代码,以减少 SVG 的文件大小。
配置
module.exports = {
module: {
rules: [
{
test: /\.svg$/,
use: ['svg-inline-loader']
}
]
}
};
svg-sprite-loader + vue
好处:
- 推荐在vue脚手架中使用
- 页面代码清爽
- 可使用 ID 随处重复调用
- 每个 SVG 图标都可以更改大小颜色
使用
- 安装依赖:
npm i -D svg-sprite-loader
- 配置示例:
module.exports = {
module: {
rules: [
{
test: /\.svg$/,
loader: 'svg-sprite-loader',
include: [resolve('src/icons')],
options: {symbolId: 'icon-[name]'}
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: "url-loader",
// 排除字体图标文件
exclude: [path.resolve(__dirname, '../src/icons/svg')],
options: {
limit: 10000,
name: utils.assetsPath("img/[name].[hash:7].[ext]")
}
}
]
}
};
创建svg文件目录/src/icons/svg 里面呢放置所有svg文件,还有/src/icons/index.js.
/src/icons/index.js
import Vue from 'vue';
import VIcon from '@/components/VIcon'; // svg组件
Vue.component('v-icon', VIcon); // 全局注册
const requireAll = requireContext => requireContext.keys().map(requireContext);
const req = require.context('./svg', false, /\.svg$/);
requireAll(req);
新建VIcon.vue组件
<template>
<svg :class="svgClass" aria-hidden="true">
<use :xlink:href="iconName"></use>
</svg>
</template>
<script>
export default {
name: 'v-icon',
props: {
name: {
type: String,
required: true
},
className: {
type: String
}
},
computed: {
iconName() {
return `#icon-${this.name}`
},
svgClass() {
if (this.className) {
return 'svg-icon ' + this.className
} else {
return 'svg-icon'
}
}
}
}
</script>
<style scoped>
.svg-icon {
width: 1em;
height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
</style>
在main.js中引入
import './icons/index.js'
这样就能在vue中使用了 具体格式如下
<v-icon name="svg文件名"/>
三、常用插件(Plugin)
webpack提供很多钩子可以让开发者进行二次开发插件,完成很多丰富的功能。plugins扩展了webpack的功能,在webpack运行时会广播很多事件,plugin可以监听这些事件,然后通过webpack提供的API来改变输出结果。
1. html-webpack-plugin
详情见下面的文章
2. clean-webpack-plugin
clean-webpack-plugin用于在打包前清理上一次项目生成的bundle文件,它会根据output.path自动清理文件夹;这个插件在生产环境用的频率非常高,因为生产环境经常会通过hash生成很多bundle文件,如果不进行清理的话每次都会生成新的,导致文件夹非常庞大;
- 安装依赖:
npm i -D clean-webpack-plugin
- 配置示例:
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
//其他配置
plugins: [
new CleanWebpackPlugin()
]
}
3. mini-css-extract-plugin
mini-css-extract-plugin就可以帮我从js中单独抽离css样式文件。通常开发环境使用style-loader,生产环境使用mini-css-extract-plugin。
- 安装依赖:
npm i -D mini-css-extract-plugin
- 配置示例:
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
//其他配置
module: {
rules: [
{
test: /\.less/,
use: [{
loader: isDev ? 'style-loader' : MiniCssExtractPlugin.loader
},{
loader: 'css-loader'
},{
loader: 'less-loader'
}]
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: "[name].[hash:8].css",
})
]
}
4. optimize-css-assets-webpack-plugin
用于生产环境,对css进行压缩
- 安装依赖:
npm i optimize-css-assets-webpack-plugin -D
- 配置示例:
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
module.exports = {
// 其他配置
plugins: [
new OptimizeCSSAssetsPlugin(),
]
}
5. copy-webpack-plugin
打包的时候,将静态资源拷贝到dist目录
- 安装依赖:
npm i -D copy-webpack-plugin
- 配置示例:
const CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = {
plugins: [
new CopyWebpackPlugin({
patterns: [
{
from: 'static/js/*.js',
to: path.resolve(__dirname, 'dist', 'js'),
flatten: true,
}
]
}),
]
}
四、扩展
- 在webpack-dev-server中添加mock中间件实现前端模拟数据功能
- webpack打包原理&手写webpack核心打包过程
- 再来一打Webpack面试题
- Webpack HMR 原理解析
- Webpack配置全解析(优化篇)
五、参考
本文严重参考以下文章: