webpack
项目 | 地址 |
---|---|
晓智科技 | 晓智科技 |
晓智文档 | 晓智文档 |
源码地址 | 源码地址 |
文档源码 | 文档源码 |
处理 css 资源
- webpack 本身不能识别样式资源,需要借助 loader 来帮助 webpack 解析样式资源
npm i css-loader style-loader -D
- css-loader 负责将 css 编译成 webpack 能识别的模块
- style-loader 会动态创建一个 style 标签里面放置 webpack 中 css 内容
{
test: /\.css$/,
// 执行顺序从右到左(从下到上)
use: ["style-loader", "css-loader"],
}
处理 less 资源
npm install less less-loader -D
- less-loader 负责将 less 文件编译成 css 文件
{
test:/\.less$/,
// 执行顺序从右到左(从下到上)
use:['style-loader','css-loader','less-loader']
}
处理 sass 资源
npm i sass saas-loader -D
- sass: saas-loader 依赖 sass 进行编译
- sass-loader 负责将 saas 文件编译为 css 文件
{
test:/\.s[ac]ss$/,
// 执行顺序从右到左(从下到上)
use:['style-loader','css-loader','sass-loader']
}
处理 styl 资源
npm i stylus stylus-loader -D
- stylus-loader 负责将 styl 文件编译成 css 文件
{
test:/\.styl$/,
// 执行顺序从右到左(从下到上)
use:['style-loader','css-loader','stylus-loader']
}
图片资源处理
- webpack5 已经将 file-loader 和 url-loader 功能内置到 webpack 里了,只需要简单配置就可处理图片资源
{
test:/\.(png|jpe?g|gif|webp)$/,
type:"asset",
parser:{
dataUrlCondition:{
// 小于10kb
maxSize:10 * 1024
}
}
}
修改图片输出路径
{
test:/\.(png|jpe?g|gif|webp)$/,
type:"asset",
parser:{
dataUrlCondition:{
// 小于10kb
maxSize:10 * 1024
}
},
generator:{
filename:'img/[hash:8][ext][query]'
}
}
字体图标资源处理
- 设置 asset/resource ,静态资源文件打包时不会转 base64
{
test:/\.(ttf|woff2?|eot|ttf|otf)$/,
type:'asset/resource',
generator:{
filename:'font/[hash:8][ext][query]'
}
}
eslint 代码检查
npm i eslint eslint-webpack-plugin
- 用来检测 js 和 jsx 语法的工具,可对代码进行检查
module.exports = {
// 继承Eslint规则
extends: ['eslint.recommended'],
env: {
// 启用node中全局变量
node: true,
// 启用浏览器中全局变量
browser: true,
},
parserOptions: {
ecmaVersion: 2022, // 或者更高的版本
sourceType: 'module',
},
rules: {
// 不能使var定义变量
'no-var': 2,
},
};
const EsLintWebpackPluin = require('eslint-webpack-plugin');
new EsLintWebpackPluin({
context: path.resolve(__dirname, 'src'),
});
bebel 使用
npm i babel-loader @babel/core @babel/preset-env -D
- bebel 主要用于将 es6 语法编写的代码转换成向后兼容的 es5 语法,以版能够在浏览器或其它环境中运行
{
"presets": ["@babel/preset-env"],
"plugins": []
}
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ["@babel/preset-env"],
},
},
},
处理 html 资源
npm i html-webpack-plugin -D
- 动创建 HTML:在构建过程中自动生成一个 HTML5 文件,该文件可以包含所有 webpack 打包过程中生成的 bundles。这意味着你不需要手动创建 HTML 文件,插件会为你处理这一切。
- 自动注入资源:自动将打包生成的 JavaScript、CSS 等文件注入到生成的 HTML 文件中,无需手动添加
new HtmlWebpackPlugin({
inject:'body',
template: path.resolve(__dirname,'public/index.html'),
}),
静态服务器
npm i webpack-dev-server -D
- 检测到文件的修改后会自动编译,提高开发效率
devServer:{
port:8080,
open:true,
}
"scripts": {
"build": "webpack --config webpack.config.js"
},
抽离 css 文件
sudo npm i mini-extract-plugin -D
- css 和 js 共同打包在一个文件会出现闪屏现在用户体验不好
- 单独抽离 css 文件这过 link 标签加载性能才更好
//plugin
new MiniCssExtractPlugin({
filename:'css/main.css'
})
//rules
{
test: /\.css$/,
// 执行顺序从右到左(从下到上)
use: [MiniCssExtractPlugin.loader, "css-loader"]
}
样式兼容
npm i postcss-loader postcss postcss-preset-env -D
- 首先,了解不同浏览器之间的差异是解决兼容性问题的关键。不同浏览器可能对 CSS 规范的解释不同,这可能导致样式显示不一致。以下是一些常见的浏览器差异
"browserslist":[
"last 2 version",
"> 1%",
"not dead"
]
{
test: /\.less$/,
// 执行顺序从右到左(从下到上)
use: [
MiniCssExtractPlugin.loader,
"css-loader",
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [
'postcss-preset-env'
]
}
}
},
"less-loader"
],
},
css 压缩
npm install css-minimizer-webpack-plugin -D
const CssMinimizerWebpackPlugin = require('css-minimizer-webpack-plugin');
plugins: [new CssMinimizerWebpackPlugin()];
soucemap
module.exports = {
devtool:'source-map',
}
HMR
- HotModuleReplacement(HMR/热模块替换):在程序运行中,替换添加或删除模块,而无需重新加载整个页面
devServer: {
port: 8080,
open: true,
hot:true, // 开启HMR功能
}
oneOf
- 打包时每个文件都经过所有 loader 处理,虽然因为 test 正则原因实际没有处理上,但是都要通过一遍比较慢,用 oneOf 只能匹配上一个 loader 余下的就不匹配
module: {
rules: [
{
oneOf: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
},
},
},
],
},
];
}
Include/Exclude
- 开发时需要使用第三方的库和插件,所有文件都下载到 node_modules 中,而这些文件是不需要编译可直接使用
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ["@babel/preset-env"],
},
},
}
Cache 缓存
- 每次打包 js 文件都要经地 eslint 检查和 babel 编译,速度比较慢。可以缓存之前的 eslint 栓查和 babel 编译结果,这样每二次打包速度就会更快
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ["@babel/preset-env"],
// 开启babel缓存
cacheDirectory: true,
// 关闭缓存文件压缩
// cacheCompression: false,
},
},
}
多进程打包
npm i thread-loader -D
- 当项目变来越来越庞大时,打包速度越来越慢,而对 js 文件处理主要是 eslint,babel,terser 三个工具,可以开启多进程同时处理 js 文件,这个速度比单进程快
{
test: /\.js$/,
exclude: /node_modules/,
use:[
{
// 需放babel-loader前
loader:'thread-loader',
options:{
threads:threads
}
},
]
},
babal 文件处理
npm i @babel/plugin-transform-runtime -D
- @babel/plugin-transform-runtime 禁用了 babel 自动对每个文件的 runtime 注入,而是引入@babel/plugin-transform-runtime 所辅助代码
{
loader: "babel-loader",
options: {
presets: ["@babel/preset-env"],
// 开启babel缓存
cacheDirectory: true,
// 关闭缓存文件压缩
// cacheCompression: false,
plugins:['@babel/plugin-transform-runtime']
},
}
图片压缩
npm i image-minimizer-webpack-plugin imagemin -D
- 开发中引用了较多图片,图片休积会比较大,可以对图片进行压缩,减少图片体积
- 注意:如果图片都是在线链接,那么就不需要压缩
module.exports = {
optimization: {
minimizer: [
'...',
new ImageMinimizerPlugin({
minimizer: {
implementation: ImageMinimizerPlugin.sharpMinify,
},
generator: [
{
type: 'asset',
implementation: ImageMinimizerPlugin.sharpGenerate,
options: {
encodeOptions: {
webp: {
quality: 90,
},
},
},
},
],
}),
],
},
plugins: [new CopyPlugin({ patterns: ['images/**/*.png'] })],
};
多入口
- 打包时将所有 js 文件打包到一个文件中,休积太大了,如果只要渲染首页,就只加载首页的 js 文件其它文件不应该加载
- 将打包的文件进行代码分割,生成多个 js 文件渲染对应的 js 文件这样加载资源就少速度就快
module.exports = {
// 多入口
entry: {
app: './src/app.js',
main: './src/main.js',
},
// 出口
output: {
// 文件输出路径
path: path.resolve(__dirname, 'build'),
// 输出文件名
filename: 'js/[name].js',
// 自动清空上次打包内容
clean: true,
},
};
Preload/Prefetch
npm install --save-dev preload-webpack-plugin
- preload/prefetch 告诉浏览器空闲时间加载需要的资源
- preload 浏览器立即加载资源
- prefetch 在空闲时才开始加载资源
- 都会加载资源,并不执行都有缓存
- preload 加载优先级高,prefetch 加载优先级低
- preload 只能加载当前页面需要使用的资源,prefetch 加载当前页面资源,也可以加载下一个页面需要使用的资源
plugins: [
new HtmlWebpackPlugin({
inject: "body",
template: path.resolve(__dirname, "public/index.html"),
}),
new MiniCssExtractPlugin({
filename: "css/main.css",
}),
new CssMinimizerWebpackPlugin(),
// 开启Preload预加载
new PreloadWebpackPlugin({
rel: 'preload',
as: 'script'
})
],
js 兼容处理
npm i core-js
- core-js 是专门用来做 es6 以及上 api 处理的 polyfill
- polyfill 补丁就用用社用上提供的一段代码,让在不兼容某些特性新特性的浏览器上,使用该新特性
//app.js
import 'core-js';
//动态引入配置
module.exports = {
presets: [
"@babel/preset-env",
{
targets: "> 0.25%, not dead",
corejs: { version: 3, proposals: true }, // 设置corejs版本
useBuiltIns: 'usage', // 根据使用情况引入polyfill
},
],
plugins: [],
};
PWA
npm i workbox-webpack-plugin -D
- 渐进式网络应用程序:是一种可以提供类似于navive app(原生应用程序)体验的web app技术
- 其中最重要的是在离线offline时应用程序能够继续运行功能
- 内部通过service workers技术实现的
// https://www.webpackjs.com/guides/progressive-web-application/#adding-workbox
//webpack.config.js
new WorkboxPlugin.GenerateSW({
// 这些选项帮助快速启用 ServiceWorkers
// 不允许遗留任何“旧的” ServiceWorkers
clientsClaim: true,
skipWaiting: true,
}),
//入口index.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);
});
});
}
联系作者
![](https://devpress.csdnimg.cn/9ea0b4566eb54d54b1b0d2c87ea6c2e0.webp)