webpack
- 以一个或多个文件作为入口,将整个项目所有文件编译成一个或多个文件输出出去
- 输出文件就是编译好的文件,可以直接在浏览器中运行
- webpack输出文件叫做bundle
初始使用
初始
- npm init -y 初始化
- npm i webpack webpack-cli -D 下载依赖
- npx webpack ./src/main.js --mode=development 开发模式下打包
基本配置
输出配置
output: {
path: path.resolve(__dirname,"dist"),
filename: "js/main.js",
clean: true,
},
generator: {
filename: 'static/images/[hash][ext][query]'
}
{
test: /\.(ttf|woff2?)/,
type: 'asset/resource',
generator: {
filename: 'static/font/[hash:10][ext][query]'
}
},
loader
处理CSS文件
webpack中文文档
- npm install --save-dev css-loader
- npm i style-loader -D
- webpack.config.js写入
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
},
],
},
};
处理less文件
- npm install less less-loader --save-dev
- npm install --save-dev css-loader
- npm i style-loader -D
- webpack.config.js写入
{
test: /\.less$/i,
use: [
'style-loader',
'css-loader',
'less-loader',
]
},
处理图片资源
- webpack内部继承了file-loader和url-loader
- webpack.config.js写入
{
test: /\.pnh|jpe?g|gif|svg$/,
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 60*1024,
}
}
},
5个核心概念
entry(入口)
提示webpack从哪开始打包
output(输出)
提示webpack打包完文件到哪去,如何命名
loader (加载器)
webpack本身只处理js,json资源,需要借助loader,webpack处理
loader开发
- 下载npm i loader-utils
- 下载npm i schema-utils
plugins(插件)
扩展webpack功能
plugins开发
- 是一个类,在webpack执行时调用方法apply()方法,传入参数compiler
- 在thisCompilation实例化后可以拿到compilation
mode (模式)
- 生产模式 production
- 开发模式 development
处理JS资源
Eslint
- 文档
- npm install eslint-webpack-plugin --save-dev
- npm install eslint --save-dev
- webpack.config.js写入
plugins:[
new ESLintPlugin({
context: path.resolve(__dirname,'src')
})
],
module.exports={
extends:["eslint:recommended"],
env:{
node:true,
browser:true,
},
parserOptions:{
ecmaVersion: 6,
sourceType: "module",
},
rules:{
"no-var": 2,
},
}
Babel
将es6语法转换为向后兼容代码
- npm install -D babel-loader @babel/core @babel/preset-env
- webpack.config.js写入
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
}
},
module.exports={
presets:['@babel/preset-env'],
}
处理html资源
- npm install --save-dev html-webpack-plugin
- webpack.config.js写入
const HtmlWebpackPlugin = require('html-webpack-plugin');
new HtmlWebpackPlugin({
template:path.resolve(__dirname,'public/index.html')
}),
搭建本地服务器&自动化
- npm i webpack-dev-server -D
- webpack.config.js写入
devServer:{
host:"localhost",
port: "8080",
open: true,
},
生产模式搭建
配置
- 新建config文件夹,定义webpack.dev.js和webpack.prod.js
- package.json文件中配置
"dev": "webpack serve --config ./config/webpack.dev.js",
"prod": "webpack --config ./config/webpack.prod.js"
CSS处理
- css单独打包并通过外链式调用性能才好
- npm install --save-dev mini-css-extract-plugin
- 用MiniCssExtractPlugin.loader替换带style-loader
CSS兼容处理
- npm install --save-dev postcss-loader postcss postcss-preset-env
- webpack.prod.js配置
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [
[
'postcss-preset-env',
],
],
},
},
},
- package.json配置,告诉webpack应该兼容到什么程度
"browserslist": [
"last 2 version",
"> 1%",
"not dead"
]
提取公共样式
function getStyleLoader(pre){
return [
MiniCssExtractPlugin.loader,
"css-loader",
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [
[
'postcss-preset-env',
],
],
},
},
},
pre
].filter(Boolean)
}
{
test: /\.less$/i,
use: getStyleLoader('less-loader')
},
CSS压缩
- npm install css-minimizer-webpack-plugin --save-dev
- 插件中调用
new CssMinimizerPlugin(),
webpack优化
SourceMap
- webpack输出式压缩后(编译后代码),出现错误不好查找,需借助与源代码与构建后代码映射关系
- 启动映射文件
devtool: 'cheap-module-source-map',
devtool: 'source-map',
hot module replacement
- 将打包后文件缓存,在有新的内容时只打包新文件
- main.js中配置
// 判断浏览器是否支持热模块更新
if(module.hot){
module.hot.accept('./js/sum')
module.hot.accept('./js/count',function (count){
console.log(count);
})
}
oneof
- 在用loader处理文件时,让文件遇到自己匹配的第一个正则就停止
- 在webpack.config中配置
{
loader: [
]
}
Include/Exclude
- node_modules中文件已经被编译过了,所以我们在编译过程中不需要再编译一次
- Include || Exclude
- include 只处理XXX文件
- exclude 除了XXX文件都处理
- webpack.config配置
{
test: /\.js$/,
include: path.resolve(__dirname,'../src'),
use: {
loader: 'babel-loader',
}
},
CaChe
- 每次打包时都会对Eslint和Babel进行处理,但这样速度较慢,我们缓存每次处理后的结果,这样二次运行时只对新内容进行处理速度较快
- webpack.config中配置
{
loader: "babel-loader",
options: {
cacheDirectory: true,
cacheCompression: false,
}
}
new ESLintPlugin({
context: path.resolve(__dirname,'../src'),
cache: true,
cacheLocation: path.resolve(__dirname,"../node_modules/.cache/cacheEslint"),
threads,
}),
- 开启多线程模式进行优化
- 引入内置OS模块,判断CPU模块数
const os = require('os');
const threads = os.cpus().length;
- npm i thread-loader -D 下载多线程插件
- webpack.config中配置
optimization: {
minimizer: [
new CssMinimizerPlugin(),
new TerserWebpackPlugin({
parallel: threads,
})
]
},
减小代码体积
Tree Shaking
- tree shaking默认功能,会自动剔除掉没被使用的代码
Babel
- babel会为每个文件插入辅助代码,导致体积变大
- npm i -D @babel/plugin-transform-runtime
- webpack.config中配置
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{
loader: "thread-loader",
options: {
works: threads,
}
},
{
loader: "babel-loader",
options: {
cacheDirectory: true,
cacheCompression: false,
plugins: ['@babel/plugin-transform-runtime'],
}
}
]
},
压缩图片
- 下载包 npm i image-minimizer-webpack-plugin imagemin --save-dev
- 有损压缩与无所压缩
- 有损压缩
npm install imagemin-gifsicle imagemin-mozjpeg imagemin-pngquant imagemin-svgo --save-dev - 无损压缩
npm install imagemin-gifsicle imagemin-jpegtran imagemin-optipng imagemin-svgo --save-dev
优化代码运行性能
提取公共模块
- 在打包时会将所有JS文件打包到一个JS文件中,对于首页渲染速度较慢,所以代码分割,页面需要用什么文件就加载哪个文件
- SplitChunksPlugin进行修改
按需加载
- 需要时在加载对应JS文件
- import动态加载
单入口
- npm i babel-eslint@8允许出现不出现顶层import
- npm i eslint-plugin-import允许eslint动态导入
模块命名
- 输出中配置
output: {
path: path.resolve(__dirname,"../dist"),
filename: "static/js/main.js",
chunkFilename: "static/js/[name].js",
clean: true,
},
- 引入时配置
document.getElementById('btn').onclick=function (){
console.log(11111);
import('./js/count.js').then(({count})=>{
console.log(count([1,2,3]))
})
}
Preload/Prefetch
- 当我们运用路由懒加载时,当JS文件过大时,用户会感觉到明显卡顿,所以我们希望在浏览器空闲时对资源进行加载
- perload告诉浏览器立即加载资源
- prefetch告诉浏览器空闲时加载资源
- npm install --save-dev @vue/preload-webpack-plugin
- webpack.config中配置
new PreloadWebpackPlugin({
rel: 'prefetch',
}),
runtime
- 当A文件的依赖发生变化时,会导致A也会变化,所以我们将A的依赖的hash存入在一个runtime文件中,变化时再runtime中寻找,以更好缓存
- webpack.config配置
runtimeChunk: {
name:(entrypoint)=> `runtime~${entrypoint.name}.js`
}
- 需要缓存的地方修改,通过hash确定变与不变
new MiniCssExtractPlugin({
filename: 'static/css/[name].[contenthash:10].css',
chunkFilename: 'static/css/[name].chunk.[contenthash:10].css'
}),
Core-js
- core-js专门用来做ES6及以上API的polyfill
- npm i core-js
PWA
- 为浏览器提供离线访问功能
- npm install workbox-webpack-plugin --save-dev
- 注册生成main.js中
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/service-worker.js').then(registration => {
console.log('SW registered: ', registration);
}).catch(registrationError => {
console.log('SW registration failed: ', registrationError);
});
});
}
- npm i serve -g 部署本地资源
|