打包样式资源(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({
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',
options: {
limit: 8 * 1024,
name: '[hash:6].[ext]'
}
},
{
test: /\.html$/,
loader: 'html-loader',
options: {
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 = {
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')
const MiniCssLoader = {
loader: MiniCssExtractPlugin.loader,
options: {
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"
]
}
const postCssLoader = {
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [
require('postcss-preset-env')()
]
}
}
}
process.env.NODE_ENV = 'development'
module.exports = {
module: {
rules: [{
test: /\.css$/,
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
"eslintConfig":{
"extends":"airbnb-base"
}
const EslintWebpackPlugin = require('eslint-webpack-plugin')
module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'eslint-loader',
enforce:'pre',
options: {
fix:true
}
}
]
},
plugins: [
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:{
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',
}
import print from './print.js';
if(module.hot){
module.hot.accept('js文件路径',function(){
模块();
})
}
生产环境性能优化
优化构建速度
优化代码运行性能
oneof
module.exports = {
module:{
rules:[
{
oneOf:[
{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),减少代码体积
{
"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')
}
optimization:{
splitChunks:{
chunks:'all'
}
}
}
多线程打包thread-loader
module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use:[
{
loader:'thread-loader',
options:{
worker: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']
}
}
import common from '$common/common.js';
开发服务devServer
module.exports = {
devServer:{
contentBase:resolve(__dirname,'build'),
compress:true,
port:5200,
host:'localhost',
open:true,
host:true,
watchContentBase:true,
watchOptions:{
ignored:/node_modules/
},
proxy:{
'xzp':{
target:'http://192.168.3.4:9080',
originTarget:true
}
}
}
}