打包样式资源(css、less)
下载包:style-loader,css-loader,less-loader,less
webpack.config.js webpack的配置文件默认采用commonjs
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
test: /\.less$/,
use: ['style-loader', 'css-loader', 'less-loader']
}
]
}
}
打包HTML资源
下载插件:html-webpack-plugin
// 引入插件
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
plugins: [
new HtmlWebpackPlugin({
// 文件自动引入打包输出所有的资源js/css不需要引入js
template: './src/index.html'
})
]
}
打包图片资源
下载包:url-loader,file-loader,html-loader(html中引入图片,需要url-loader关闭esModule)
module.exports = {
module: {
rules: [
{
test: /\.(jpg|png|gif)$/,
loader: 'url-loader', // 单个:loader,多个:use
options: {
// 图片小于8kb,base64处理
// 优点:减少请求数量
// 缺点:图片体积更大
limit: 8 * 1024,
name: '[hash:6].[ext]' // 重命名
}
},
{
test: /\.html$/,
loader: 'html-loader', // 处理HTML中图片(负责引入,从而url-loader处理
options: { // webpack5需要添加
esModule: false
}
}
]
}
}
打包其他资源
下载包:file-loader,使用配置exclude排除其他文件
module.exports = {
module: {
rules: [
{
exclude: /\.(css|less|js|html|jpg|png|gif)/,
loader: 'file-loader',
options:{
name:'[hash:7].[ext]' // 文件重新命名
}
}
]
}
}
自动编译devServer
下载包:webpack-dev-server
启动命令:webpack serve(5) | npx webpack-dev-server(4)
module.exports = {
// 自动化编译, 不存在输出,启动命令:webpack serve(5) | npx webpack-dev-server(4)
devServer: {
contentBase: resolve(__dirname, 'build'),
compress: true,
port: 9080, // 端口
open:true // 默认打开
}
}
测试环境配置
js输出于js文件夹,css输出于css文件夹,其他资源输出于其他资源文件夹
options:{outputPath:''}
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { resolve } = require("path");
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/build.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
test: /\.less$/,
use: ['style-loader', 'css-loader', 'less-loader']
},
{
test: /\.(jpg|png|gif)$/,
loader: 'url-loader',
options: {
limit: 10 * 1024,
name: '[hash:10].[ext]',
outputPath: 'images' // 文件输出目录
}
},
{
test: /\.html$/,
loader: 'html-loader',
options: {
esModule: false
}
},
{
exclude: /\.(html|js|css|less|jpg|png|gif)/,
loader: 'file-loader',
options: {
name: '[hash:8].[ext]',
outputPath: 'media' // 文件输出目录
}
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
devServer: {
contentBase: resolve(__dirname, 'build'),
compress: true,
port: 8080,
open: true
},
mode: 'development'
}
css分离成单独css文件
下载插件:mini-css-extract-plugin
MiniCssExtractPlugin.loader替换style-loader
输出文件于new MiniCssExtractPlugin({filename:'css/build.css'})
css/less中图片路径需要配置publicPath:'../'
// 引入插件
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
// 插件loader配置
const MiniCssLoader = {
loader: MiniCssExtractPlugin.loader,
options: { // 解决css样式引入背景图片路径问题
publicPath: '../'
}
}
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssLoader, 'css-loader']
},
{
test: /\.less$/,
use: [MiniCssLoader, 'css-loader', 'less-loader']
}
]
},
plugins: [
// 插件使用
new MiniCssExtractPlugin({
filename: 'css/build.css'
})
]
}
css样式兼容性处理
下载包:postcss-loader、postcss-preset-env
packag.json配置browserslist
"browserslist":{
"development":[
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
],
"production":[
">0.2%",
"not dead",
"not op_mini all"
]
}
// loader配置
const postCssLoader = {
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [
require('postcss-preset-env')()
]
}
}
}
// 兼容开发环境,若不配置默认生产环境
process.env.NODE_ENV = 'development'
module.exports = {
module: {
rules: [{
test: /\.css$/,
// loader配置引入
use: [MiniCssLoader, 'css-loader', postCssLoader]
},
{
test: /\.less$/,
use: [MiniCssLoader, 'css-loader', postCssLoader, 'less-loader']
}
]
}
}
压缩css
下载插件:optimize-css-assets-webpack-plugin
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')
module.exports = {
plugins: [
// 插件使用
new OptimizeCssAssetsWebpackPlugin()
]
}
配置合集
const HtmlWebpackPlugin = require("html-webpack-plugin");
const {
resolve
} = require("path");
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')
const MiniCssLoader = {
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: '../'
}
}
const postCssLoader = {
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [
require('postcss-preset-env')()
]
}
}
}
process.env.NODE_ENV = 'development'
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/build.js',
path: resolve(__dirname, 'build'),
},
module: {
rules: [{
test: /\.css$/,
use: [MiniCssLoader, 'css-loader', postCssLoader]
},
{
test: /\.less$/,
use: [MiniCssLoader, 'css-loader', postCssLoader, 'less-loader']
},
{
test: /\.html$/,
loader: 'html-loader',
options: {
esModule: false
}
},
{
test: /\.(png|jps|gif)$/,
loader: 'url-loader',
options: {
limit: 10 * 1024,
name: '[hash:9].[ext]',
outputPath: 'images'
}
},
{
exclude: /\.(js|html|css|less|png|jps|gif)/,
loader: 'file-loader',
options: {
name: '[hash:8].[ext]',
outputPath: 'media'
}
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new MiniCssExtractPlugin({
filename: 'css/build.css'
}),
new OptimizeCssAssetsWebpackPlugin()
],
mode: 'development',
devServer: {
contentBase: resolve(__dirname, 'build'),
compress: true,
port: 9090,
open: true
}
}
eslint语法检查
下载插件:eslint-webpack-plugin
下载包:eslint
// eslint-loader需要配置package.json
"eslintConfig":{
"extends":"airbnb-base"
}
// 新插件
const EslintWebpackPlugin = require('eslint-webpack-plugin')
module.exports = {
module: {
rules: [
// eslint-loader (已弃用)
// 需要设置eslint检查规则:airbnb
// 需要下载eslint-config-airbnb-base eslint-plugin-import
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'eslint-loader',
enforce:'pre', // 优先执行
options: {
fix:true
}
}
]
},
plugins: [
// 需要配置.eslintrc.js
new EslintWebpackPlugin({
fix:true
}),
]
}
语法兼容性处理
下载包:babel-loader、@babel/preset-env、@babel/core
可以处理部分语法兼容性问题,如Promise未处理
按需加载兼容性处理:按需加载,下载包core-js
module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
// 新版本
presets: [
['@babel/preset-env',
{
useBuiltIns:'usage',
corejs:{ version:3 },
targets: { edge: '8', firefox: '60', chrome: '58', safari: '11' }
}
]
]
}
}
]
}
}
完整生产环境配置
const EslintWebpackPlugin = require('eslint-webpack-plugin')
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { resolve } = require("path");
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')
const MiniCssLoader = {
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: '../'
}
}
const postCssLoader = {
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [
require('postcss-preset-env')()
]
}
}
}
process.env.NODE_ENV = 'development'
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/build.js',
path: resolve(__dirname, 'build'),
},
module: {
rules: [{
test: /\.css$/,
use: [MiniCssLoader, 'css-loader', postCssLoader]
},
{
test: /\.less$/,
use: [MiniCssLoader, 'css-loader', postCssLoader, 'less-loader']
},
{
test: /\.html$/,
loader: 'html-loader',
options: {
esModule: false
}
},
{
test: /\.(png|jps|gif)$/,
loader: 'url-loader',
options: {
limit: 10 * 1024,
name: '[hash:9].[ext]',
outputPath: 'images'
}
},
{
exclude: /\.(js|html|css|less|png|jps|gif)/,
loader: 'file-loader',
options: {
name: '[hash:8].[ext]',
outputPath: 'media'
}
},
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: [
['@babel/preset-env',
{
useBuiltIns: 'usage',
corejs: {
version: 3
},
targets: {
edge: '8',
firefox: '60',
chrome: '58',
safari: '11'
}
}
]
]
}
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
minify:{ // html压缩
collapseWhitespace:true,
removeComments:true
}
}),
new MiniCssExtractPlugin({
filename: 'css/build.css'
}),
new OptimizeCssAssetsWebpackPlugin(),
new EslintWebpackPlugin({
fix: true
}),
],
mode: 'production'
}
热更新(开发环境)
样式文件:支持HMR功能,webpack5需要配置target:'web'
html文件:入口文件配置,默认不使用HRM功能
js文件:
module.exports = {
entry: ['./src/js/index.js', './src/index.html'],
target:'web',
}
// index.js
import print from './print.js';
if(module.hot){
module.hot.accept('js文件路径',function(){
模块();//执行
})
}
生产环境性能优化
优化构建速度
优化代码运行性能
oneof
module.exports = {
module:{
rules:[
{
oneOf:[//下列存在loader命中,将停止遍历,注意不可以存在多个配置处理同一类型的文件
//需要提取出来
{test:/\.xxx$/,loader:'xxx-loader'}
]
}
]
}
}
source-map 构建后代码映射技术(代码错误信息)
module.exports = {
devtool:'eval-source-map'
}
缓存babel编译js
module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: [
['@babel/preset-env',
{
useBuiltIns:'usage',
corejs:{ version:3 },
targets: { edge: '8', firefox: '60', chrome: '58', safari: '11' }
}
]
], // 开启缓存
cacheDirectory:true
}
}
]
}
}
树摇tree_shaking去除无用代码
前提:1.需要使用ES6模块化 2.开启production环境
作用:去除无用代码(css、js),减少代码体积
// package.json配置
{
// "sideEffects":false 问题:样式代码被去除
"sideEffects":["*.css","*.less"]
}
代码分割code-split
module.export = {
// 多页面
entry:{
index:'./src/js/index.js',
utils:'./src/public/utils.js'
},
output:{
filename:'js/[name].[contenthash:10].js',
path:resolve(__dirname, 'build')
}
// 单页面
// node_modules中代码单独打包一个chunk输出
// 自动分析多入口chunk,若有公共入口,则单独打包成单个chunk
optimization:{
splitChunks:{
chunks:'all'
}
}
}
多线程打包thread-loader
// js打包与babel-loader一起使用,启动时间600ms
module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use:[ // thread-loader
{
loader:'thread-loader',
options:{
worker:2 // 开启2个进程
}
}
]
}
]
}
}
忽略某些包的被打包
使用dll技术,对第三方库(react、vue、jQuery...)单独打包,页面使用需要重新引入
module.exports = {
externals:{
jquery:'jQuery'
}
}
解析模块规则(别名)
配置解析模块的路径别名:优点简写路径,缺点无路径提示
const {resolve} = require('path')
module.exports = {
resolve:{
alias:{ // 配置路径别名
$common:resolve(__dirname, 'src/common')
},
// 配置省略文件路径的后缀名
extensions:['.js','.jsx','.css'],
modules:[resolve(__dirname,'../node_modules'), 'node_modules']
}
}
// 访问common下的文件:
import common from '$common/common.js';
开发服务devServer
module.exports = {
devServer:{
// 运行代码目录
contentBase:resolve(__dirname,'build'),
compress:true,// 启动gzip压缩
port:5200,// 端口号
host:'localhost',// 域名
open:true,// 自动打开默认浏览器
host:true,// 热模式 HRM
// 监视contentBase目录下的文件,文件产生变化则reload
watchContentBase:true,
watchOptions:{// 忽视监视
ignored:/node_modules/
},
proxy:{// 服务器代理
'xzp':{
target:'http://192.168.3.4:9080',
originTarget:true
}
}
}
}