- 安装webpack
1.安装nodejs
2.npm init -y
3.npm i webpack webpack-cli --save--dev
- 执行webpack打包
使用npx webpack
- 查看打包的信息命令
webpack --stats detailed
- 自定义webpack配置
- 使用npx webpack --entry(设置入口文件) ./src/index.js --mode production(模式) 不推荐不直观
- 新建webpack.config.js在文件中配置
配置如下
const path=require("path")
const HtmlWebpackPlugin=require("html-webpack-plugin")
module.exports={
entry:'./src/index.js' //入口文件
output:{
filename:'bundle,js' //输出文件名
path:path.resolve(__dirname,'./dist') //输出路径
clean:true //清理上一次打包的内容
}
mode:'development' //设置生产模式
devtool:"inline-source-map" //可以精确定位代码位置
plugins:[
new HtmlWebpackPlugin({
//对象形式
template:'./index.html', //模板
filename:"app.html", //文件名
inject:"body" //script标签插入的位置 默认为head
})
] //注意是数组
}
- 设置用watch mode打包(观察模式)
终端命令 npx webpack --watch //会监测文件的变化
- webpack-dev-server(无需刷新浏览器)热模替换、自动刷新
npm i webpack-dev-server -D 安装插件
在webpack.config.js文件中增加配置
devserver:{
static:'./dist'
}
资源模块
- Resource资源
modules:{
rules:[
{
test:\/.png$\, //$表示以png为扩展类型的文件
type:'asset/resource' //定义类型
}
]
}
自定义文件目录和文件名
1.在output配置中添加
output:{
.....
assetModuleFilename:'image/[contenthash][ext]'
//contenthash代表哈希生成文件名,ext为扩展名(类型)
}
2.
modules:{
rules:[
{
test:\/.png$\, //$表示以png为扩展类型的文件
type:'asset/resource', //定义类型
generator:{
filename:'image/test.png' //新增项,且同时配置1和2时优先级高于1
}
}
]
}
- inline资源
如上resource类似,在modules的rules下新增一条规则
...
{
test:\/.svg$\
type:'asset/inline'
}
//inline并不会打包到dist文件夹下而是会以DataURL64的格式在浏览器中显示
- source资源
...
{
test:\/.txt$\,
type:'asset/source'
}
//source也并不会打包到dist文件夹下而是浏览器中显示
通用数据格式
{
test:\/.jpg$\,
type:'asset', //定义为常用类型
parser:{
dataUrlCondition:{
maxSize:4*1024*1024
} //默认为4*1024,超过这个size才会打包为resource资源否则为inline
}
}
loader
引入css-loader和style-loader为例
npm i css-loader -D
{
test:\/.(css|less)$\
use:['style-loader','css-loader','less-loader'] //顺序不可换,先执行css-loader后style-loader
}
抽离和压缩CSS文件
npm i mini-css-extract-plugin //webpack5 //引入插件 const MiniCssExtractPlugin=require('mini-css-extract-plugin') //在plugins中增加配置项 new MiniCssExtractPlugin({filename:'styles/[contenthash].css'}) //将上文的规则 { test:\/.(css|less)$\ use:['style-loader','css-loader','less-loader'] //顺序不可换,先执行css-loader后style-loader } //修改为 { test:\/.(css|less)$\ use:[MiniCssExtractPlugin.loader,'css-loader','less-loader'] //顺序不可换,先执行css-loader后style-loader } //压缩css npm i css-minizer-webpack-plugin -D const CssMinizerPlugin=require('css-minizer-webpack-plugin') 在新的配置项 optimization:{ minizer:[ new CssMinizerPlugin() ] } mode:'production' //mode改为生产模式
{ test: /\.js$/, exclude: /node_modules/, //不编译node_modules use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env'], plugins: [ ['@babel/plugin-transform-runtime'] ] } } }
配置公共路径
在output配置项中添加
publicPath:'http://localhost:8080'
配置环境变量
module.exports=(env)=>{ return { ... } } npx webpack --env production/development
npm i terser-webpack-plugin -D //引入js压缩插件
const TerserPlugin = require('terser-webpack-plugun')
minimizer:{
...
new TerserPlugin ()
}
配置npm脚本
package.json文件 "scripts"{ "start":"webpack serve -c ./config/webapck.config.dev.js" "build":"webpack -c ./config/webapck.config.pro.js" }
打包体积过大会有性能提示,如下配置可以关闭
//性能提示 performance:{ hints:false }
拆分配置文件
新建一个config文件夹,在文件夹中建立两个文件
webpack.config.dev.js //开发环境
webpack.config.pro.js //生产环境
运行时命令为
npx webpack -c ./config/webpack.config.dev/pro.js 来不同打包
提取公共配置
webpack.config.common.js const path = require("path") const HtmlWebpackPlugin = require("html-webpack-plugin") const MiniCssExtractPlugin = require('mini-css-extract-plugin') module.exports = { entry: { index: './src/index.js', another: './src/another_module.js' //入口文件 }, //入口文件 output: { path: path.resolve(__dirname, '../dist'), //输出路径 clean: true, //清理上一次打包的内容 assetModuleFilename: 'image/[contenthash][ext]', }, plugins: [ new HtmlWebpackPlugin({ //对象形式 template: './index.html', //模板 filename: "app.html", //文件名 inject: "body" //script标签插入的位置 默认为head }), new MiniCssExtractPlugin({ filename: 'styles/[contenthash].css' }) //用于抽离CSS ], //注意是数组 module: { rules: [ { test: /\.jpg$/, //$表示以png为扩展类型的文件 type: 'asset/resource' //定义类型 }, { test: /\.png$/, //$表示以png为扩展类型的文件 type: 'asset/resource', //定义类型 generator: { filename: 'image/test.png' //新增项,且同时配置1和2时优先级高于1 } }, { test: /\.svg$/, type: 'asset/inline' }, { test: /\.txt$/, type: 'asset/source' }, { test: /\.(css|less)$/, // use: ['style-loader', 'css-loader', 'less-loader'] //顺序不可换,先执行css-loader后style-loader use: [MiniCssExtractPlugin.loader, 'css-loader', 'less-loader'] //使用了抽离css插件的配置 }, { test: /\.js$/, exclude: /node_modules/, //不编译node_modules use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env'], plugins: [ ['@babel/plugin-transform-runtime'] ] } } } ], }, //需要配合production模式才能生效 optimization: { //(静态导入)单独抽离模块 splitChunks: { cacheGroups: { //缓存第三方库 vendor: { test: /[\\/]node_modules[\\/]/, name: 'vendors', chunks: 'all' } } } } }
webpack.config.dev.js module.exports = { output: { filename: 'scripts/[name].bundle.js', //输出文件名 }, mode: 'development', //设置生产模式 devtool: "inline-source-map", //可以精确定位代码位置 devServer: { static: './dist' }, }
webpack.config.pro.js const CssMinizerPlugin = require('css-minimizer-webpack-plugin') const TerserPlugin = require('terser-webpack-plugun') module.exports = { output: { filename: 'scripts/[name].bundle.js', //输出文件名 publicPath: 'https://localhost:8080/' //指定公共路径 }, mode: 'production' , //设置生产模式 //需要配合production模式才能生效 optimization: { minimizer: [ new CssMinizerPlugin(), //压缩css new TerserPlugin() //压缩js ], //(静态导入)单独抽离模块 }, performance:{ hints:false } }
合并配置文件
安装npm i webpack-merge -D
const { merge } = require('webpack-merge') const commonConfig = require('./webpack.config.common') const productionConfig = require('./webpack.config.pro') const developmentConfig = require('./webpack.config.dev') module.exports = (env) => { switch (true) { case env.development: return merge(commonConfig, developmentConfig) case env.production: return merge(commonConfig, productionConfig) default: return new Error('No matching configuration was found') } }
npm脚本修改
"scripts"{ "start":"webpack serve -c ./config/webapck.config.js --env development" "build":"webpack -c ./config/webapck.config.js --env production" }