1、安装
安装:npm install webpack webpack-cli -D
npx webpack -v查看版本 利用npx执行 本地文件夹里的webpack
npx webpack 进行打包
npx webpack --watch将文件进行监听,不用每次都重新输入npx webpack编译,但是需要手工刷新浏览器.
2、使用
2.1webpack.config.js中进行自定义配置
2.2HtmlWebpackPlugin使用
简化了 HTML 文件的创建,生成一个 HTML5 文件, 在 body 中使用 script
标签引入你所有 webpack 生成的 bundle
2.3 webpack-dev-server使用
npm install webpack-dev-server -D
监听文件变化、重新编译、自动实现浏览器刷新
2.4 loader
webpack自带只能解析js和JSON这种文件,loader可以让webpack去解析其他类型的文件
css-loader 负责加载css文件
style-loader 负责将css文件放到页面上
npm install mini-css-extract-plugin 抽离和压缩css 基于webpack5
2.5拆分config
由于环境的切换,在config中使用环境变量会很乱,所以将config拆分为两个单独的config
2.6配置npm
每次编译都需要输入很长的命令,所以我们将父目录的package node_modules
package-lock,拷贝到当前目录下,然后配置npm
2.7提取公共配置,并进行合并
npm install webpack-merage -D
合并文件后,此时文件夹中没有dist文件夹,我先执行npm run start ,报错Content not from webpack is served from ,然后通过localhost访问页面报cannot get /,目录中也没有dist文件夹
原因:
run start 走的的dev-server.js
会启动webpack-dev-server,相应的代码会读进内存,不会在当前目录下产生dist文件夹,此时需要先执行npm run build 打包,dist文件夹就会出来,然后在run start访问页面
2.8webpack基础总结
webpack配置文件夹
webpack.config.common.js
// 抽离公共配置 保留通用代码
const path=require('path')//引入path模块
const HtmlWebpackPlugin = require('html-webpack-plugin');//引入插件 简化了 HTML 文件的创建
const MiniCssExtractPlugin = require('mini-css-extract-plugin');//引入插件 抽离css
const CssMinimizerWebpackPlugin = require('css-minimizer-webpack-plugin');//引入插件 压缩css 优化配置中注册
const TerserWebpackPlugin = require('terser-webpack-plugin')//压缩 生产环境JavaScript
// 自定义模块 npm install toml yaml json5 -D
const toml=require('toml')
const yaml=require('yaml')
const json5=require('json5')
// 然后将mode的环境切换为production
// 将module.exports ={}改写为module.exports =()=>{return {object}}函数,用来配置--env环境变量
//由于用代码区分环境配置比较不直观,所以采用拆分环境文件进行配置
//恢复为扁平对象,拆分环境配置
module.exports ={
// npx webpack --env production --env goal=loca 编译时传递参数
// console.log(env.goal);
// entry: './src/index.js',//入口
//分离代码 方法一 配置多个入口 ,但是会有代码重复问题
// entry:{
// index:'./src/index.js',
// another:'./src/another-module.js'
// },
// 方法二、分离代码,防止重复
// entry:{
// index:{
// import:'./src/index.js',
// dependOn:'shared',//可以把共享的文件抽离出来
// },
// another:{
// import:'./src/another-module.js',
// dependOn:'shared',//可以把共享的文件抽离出来
// },
// shared:'lodash',//抽离lodash命名为shared
// },
// 方法三 配置splitChunks 代码分割
entry:{
index:'./src/index.js',
another:'./src/another-module.js'
},
// 方法4,动态导入:在单独js文件中导入模块,然后引用该js
output: { //出口
// filename: 'bundle.js',
// filename:'[name].bundle.js', //配合多入口命名
//缓存,我们打包好的文件部署在服务器之后,浏览器第一次访问会缓存打包好的模块
//如果我们修改了代码,文件名没有变,浏览器会使用本地缓存内容,因此通过修改输出文件名来解决这个问题,
// 使用可替换模版字符串,缓存第三方库在cacheGroups中配置,节省网络流量,提升速度
// filename:'[name].[contenthash].js',//缓存自己每次更新代码
// filename:'script/[name].[contenthash].js',//将所有js文件放到一个文件夹
path: path.resolve(__dirname,'../dist'),//__dirname基于当前文件路径,找到./dist的绝对路径,更改为两个.
// 上层目录
clean:true, //清理上次打包的文件
// assetModuleFilename:'images/test.png'//资源文件及文件名
assetModuleFilename:'images/[contenthash][ext]',//根据文件内容生成文件名字,使用原文件扩展名
// publicPath:'http://localhost:8080/'//配置公共路径 开发环境不需要
},
//实例化插件
plugins: [
new HtmlWebpackPlugin({
template:'./index.html',//将自动生成的html文件按照index.html模版进行生成
filename:'app.html' ,//更改文件名字
inject:'body'//将script放入body中
}),
new MiniCssExtractPlugin({
filename:'styles/[contenthash].css' ,//更改文件路径及名字
}),
],
// devtool:'inline-source-map',//精准定位代码行数 //生产不需要
// mode:'development',//配置编译模式
// mode:env.production?'production':'development',//根据传入参数判断环境
// devServer:{ //webpack-dev-server支持代码热更新,能迅速将更改后的代码更新到浏览器中。在这个模式下
// // 构建后的代码在内存中,不会写入硬盘,所以读写速度快了很多。
// static:'./dist'//指向的物理路径
// },
module:{//资源模块
rules:[
{
test:/\.png$/,//以png作为扩展名
type:'asset/resource',//资源模块类型: 发送一个单独的文件并导出 URL 打包后文件中显示
generator:{//generator优先级高于assetModuleFilename
filename:'images/[contenthash][ext]',
}
},
{
test:/\.svg$/,//以svg作为扩展名
type:'asset/inline',//资源模块类型: 导出一个资源的 data URI 打包后文件中不显示
},
{
test:/\.txt$/,//以txt作为扩展名
type:'asset/source',//资源模块类型: 导出资源的源代码 打包后文件中不显示
},
{
test:/\.jpg$/,//以jpg作为扩展名
type:'asset',//资源模块类型: asset/resource 与 asset/inline之间自动选择 小于8k为inline
parser:{//自己设置临界值
dataUrlCondition:{
maxSize: 4 * 1024 * 1024
}
}
},
{
test:/\.(css|less)$/,//两种扩展名
// use:'css-loader'
// use:['style-loader','css-loader','less-loader']//注意顺序,从后往前加载,css-loader结果传递给style-loader,
// less-loader解析css文件,然后传递给css-loader
// 抽离css文件,替换style-loader在页面注入css,改用MiniCssExtractPlugin.loader
use:[MiniCssExtractPlugin.loader,'css-loader','less-loader']
},
{
//加载解析字体
test:/\.(woff|woff2|eot|ttf|otf)$/,//字体文件格式很多
type:'asset/resource'
},
// 以下两种加载数据文件
{
test:/\.(csv|tsv)$/,
use:'csv-loader'
//将文件转化为一个数组
},
{
test:/\.xml$/,
use:'xml-loader'
//将文件转化为一个对象
},
// 自定义parser模块
{
test:/\.toml$/,
type:'json',
parser:{
parse:toml.parse
}
},
{
test:/\.yaml$/,
type:'json',
parser:{
parse:yaml.parse
}
},
{
test:/\.json5$/,
type:'json',
parser:{
parse:json5.parse
}
},
// babel-loader使用,可以将es6代码转换es5也支持代码
// babel-loader @babel/core @babel/preset-env
// @babel/runtime regeneratorRuntime运行时候需要的内容
//@babel/plugin-transform-runtime 自动处理regeneratorRuntime
{
test:/\.js$/,
exclude:/node_modules/,//排除node_modules里面js
use:{
loader:'babel-loader',
options:{
presets:['@babel/preset-env'],//使用babel插件
plugins:[
[
'@babel/plugin-transform-runtime'//使用插件
]
]
},
}
},
]
},
//优化配置
optimization:{
// 开发环境不压缩
// minimizer:[
// new CssMinimizerWebpackPlugin(),
// new TerserWebpackPlugin()
// ]
splitChunks:{
// chunks:'all',//代码分割 与动态导入一起使用时也要打开
cacheGroups:{//缓存第三方插件到浏览器
vendor:{
test:/[\\/]node_modules[\\/]/,
name:'vendors',
chunks:'all'
}
}
}
}
};
prod与dev
合并后的webpack.config.js
3、webpack高级
3.1 source-map (webpack内置)
devtool:'eval',
// devtool:'source-map',
// devtool:'hidden-source-map',
// devtool:'inline-source-map',
// devtool:'eval-source-map',
// devtool:'cheap-source-map',
//开发环境一般不配置,因为有暴露源码风险,而且体积较大
devtool:'cheap-module-source-map',//推荐使用
3.2devServer
模拟一个用户从浏览器中访问我们的web服务,读取我们的打包产物,观测代码在客户端的表现。
3.4githooks-husky
下载git后 git init 报错 git : 无法将“git”项识别为 cmdlet、函数、脚本文件或可运行程序的名称
配置环境变量解决
3.5依赖图
npm i webpack-bundle-analyzer -D
const {BundleAnalyzerPlugin} = require('webpack-bundle-analyzer');
new BundleAnalyzerPlugin()
3.6psstcss与css模块
3.7webpack5通用提升构建性能
通用环境提升构建性能
1.升级工具最新版
2.将loader用于最少数量的必要模块
3.每个loader和pligin都有启动时间,尽量少用
4.解析
5,减小编译结果的体积
6 dll 拆分 bundles,同时还大幅度提升了构建的速度
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const {BundleAnalyzerPlugin} = require('webpack-bundle-analyzer');
const WorkboxPlugin=require('workbox-webpack-plugin')
const webpack=require('webpack')
module.exports = {
mode:'production',
entry: './app.js',
output:{
clean:true,
// publicPath:'/' ,
path: path.resolve(__dirname, 'dist'),
filename: 'mylib.js', //如果代码没用使用,在生产环境会被tree-shaking,所以配置library
library: {
name:'mylib',//暴露从入口起点导出的内容,避免tree-shaking
type:'umd',
globalObject:'globalThis'//全局对象来挂载 library。
},
},
resolve:{
alias:{
'@':path.resolve(__dirname,'./src')//创建 import 或 require 的别名,来确保模块引入变得更简单
},
extensions:['.json','.js','.vue']//如果有多个文件有相同的名字,但后缀名不同,webpack 会解析列在数组首位的后缀的文件 并跳过其余的后缀。
},
externalsType:'script',//指定 externals 的默认类型
externals:{//防止将某些 import 的包(package)打包到 bundle 中,而是在运行时(runtime)再去从外部获取这些扩展依赖。
jquery: [//与import的from后面同步
'https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js',
'jQuery'
],
// 例如,从 CDN 引入 jQuery,而不是把它打包
},
devServer: {
static:path.resolve(__dirname,'./dist'),
compress: true,//服务端压缩文件,保证服务器到浏览器的传输是压缩的 浏览器网络中出现content-Encoding:gzip,
//自己设置过程中发现如果没有向服务器请求的代码,即使设置了,浏览器也不会出现content-Encoding:gzip,
port:3000,//更改端口号
// 配置响应头
headers:{
'X-Access-Token':'abc123'
},
// 开启代理 例如我们的客户端地址是在http://localhost:3000/
// 假如我们的接口来自http://localhost:4000/,此时项目中的请求就会跨域
proxy:{
'/api':'http://localhost:9000'
},
// https:true,//配置为https 由于默认配置使用的是自签名证书,所以浏览器提示不安全,但是我们可以继续访问
// http2:true,//自带https证书
historyApiFallback:true,//页面不存在时跳转到根页面
// host:'0.0.0.0'//开发服务器主机,同一局域网下你的同伴可以通过ip访问你的服务
//模块热替换与热加载,程序运行中修改模块,无需重新加载整个页面
hot:true,//热替换
liveReload:true,//热加载
client:{
overlay:false,//浏览器报错覆盖层
}
},
optimization: {
usedExports: true,//tree shaking移除 JavaScript 上下文中的死代码,但是移除不完全,需要sideEffects配合
// 在 package.json 中添加 "sideEffects" 属性如果被标记为无副作用的模块没有被直接导出使用,
// 打包工具会跳过进行模块的副作用分析评估”。
},
module:{
rules:[
{
test:/\.js$/,
exclude:/node_modules/,
use:{
loader:'babel-loader',
options:{
presets:[
[
'@babel/preset-env',
{
targets:[ //设置babel-polyfill使用的浏览器
'last 1 version',
'> 1%'
],
useBuiltIns:'usage',//按需加载
corejs:3 //core版本为3
}
]
]
}
}
},
{
test:/\.css$/,
exclude:/node_modules/,
use:[
'style-loader',
{
loader:'css-loader',
options:{
modules:true,//开启css模块
}
},
'postcss-loader',//配合相关插件使用,在postcss。config.js中
]
}
]
},
// 默认为eval,可以设置false关掉,也可以手动设置eval
// devtool:'eval',
// devtool:'source-map',
// devtool:'hidden-source-map',
// devtool:'inline-source-map',
// devtool:'eval-source-map',
// devtool:'cheap-source-map',
//开发环境一般不配置,因为有暴露源码风险,而且体积较大
// devtool:'cheap-module-source-map',//推荐使用
plugins: [
new HtmlWebpackPlugin(),
new WorkboxPlugin.GenerateSW({
// 离线环境运行项目
clientsClaim:true,//快速启用service-worker
skipWaiting:true,//跳出等待
//浏览器注销 chrome://serviceworker-internals/
}),
// new BundleAnalyzerPlugin() //依赖图
new webpack.ProvidePlugin({//shimming 预置全局依赖
_: 'lodash',
}),
],
};