https://mp.csdn.net/console/article
webpack理解很到位哦
包配置搜索
npmjs.com/package/html-webpack-plugin
__dirname代表当前文件的绝对路径
npm list -g --depth 0
第一章 webpack五个核心概念
entry
output
loader
plugins
mode
第二章 webapck开发环境的基本配置
- 创建配置文件
- 打包样式资源
- 打包html资源
- 打包图片资源
- 打包其他资源
- devserver
- 开发环境配置
第三章 webapck生产环境的基本配置
- 提取css成单独的文件
- css兼容处理
- 压缩css
- js语法检查
- js兼容处理
- js压缩
- html压缩
- 生产环境配置
第四章 webpack配置优化
- HMR 热模块替换 代码更新的时候不是全部更新,只是更新一部分
- source-map 映射代码
- oneOf
- 缓存
- tree shaking
- code split
- lazy loading
- pwa
- 多进程打包
- externals
- dll 对代码进行单独打包
第五章 webpack配置闲情
第六章 webpack5介绍和使用
webpack5变化
- 通过持久缓存提高构建性能
- 通过更好的算法和默认值来改善长期缓存
- 通过更好的摇树和代码生成来改善捆绑包大小
- 清除处于怪异状态的内部结构,同时在v4种实现功能而不引入任何重大变化
- 通过引入重大更改来为将来的功能做准备,使我们能长期使用v5
webpack5具体变化
自动删除Node.js Polyfills
ChunkID
Tree Shaking
Output
SplitChunk
Caching
监视输出文件
默认值
装的依赖
cnpm i webpack webpack-cli --save-dev
cnpm i webpack-dev-server --save-dev
启动命令 npx webpack
配置启动命令package.json scripts
入口出口配置
入口起点指示 webpack 应该使用哪个模块,来作为构建其内部 依赖图 的开始。
output 属性告诉 webpack 在哪里输出它所创建的 bundle,以及如何命名这些文件。主要输出文件的默认值是 ./dist/main.js,其他生成文件默认放置在 ./dist 文件夹中。
const path = require('path');
module.exports = {
entry: './path/to/my/entry/file.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'my-first-webpack.bundle.js',
},
};
cnpm i vue -S
cnpm i vue -S
使用vue,就要安装vue包
还需要
cnpm i vue-loader vue-template-compiler -D
vue-loader 编译vue文件
vue-template-compiler:
把vue-loader提取出的HTML模板编译成可执行的jacascript代码'
const { VueLoaderPlugin } = require('vue-loader');
new VueLoaderPlugin(),
module: {
rules: [
{
test: /\.vue$/,
use: [ "vue-loader"],
},
],
},
cnpm i html-webpack-plugin -D
cnpm i html-webpack-plugin -D
该插件将为你生成一个 HTML5 文件,
在 body 中使用 script 标签引入你所有 webpack 生成的 bundle
cnpm i clean-webpack-plugin -D
清除打包后的文件
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
title: 'Output Management',
}),
],
cnpm install --save-dev css-loader
cnpm install --save-dev css-loader
cnpm install --save-dev style-loader
css-loader 会对 @import 和 url() 进行处理,
就像 js 解析 import/require() 一样。
module: {
rules: [
{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
},
],
},
处理图片资源
cnpm i url-loader file-loader -D
将文件作为 data URI 内联到 bundle 中
将文件发送到输出目录
v5版本将弃用,内置资源模块 asset module
不需要再引入任何插件
module: {
rules: [
{
test: /\.png/,
type: 'asset/resource'
}
]
},
babel
在使用.vue文件之前先要安装babel(将es6语法转化为es5)
cnpm install -D babel-loader @babel/core @babel/preset-env
cnpm install - D @babel/plugin-transform-runtime
cnpm install @babel/runtime
webpack配置
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
plugins: ['@babel/plugin-transform-runtime']
}
}
}
单独根目录创建.babelrc配置
{
"presets": [
"@babel/preset-env"
],
"plugins": [
"@babel/plugin-transform-runtime"
]
}
HMR模块热更新
此功能可以很大程度提高生产效率
webpack 内置的 HMR 插件
css热更新
hot: true,
js热更新
在index.js
if (module.hot) {
module.hot.accept('./print.js', function() {
console.log('Accepting the updated printMe module!');
printMe();
})
}
源代码映射 source-map
源代码到打包后的代码技术映射
eval-source-map 内联 开发推荐
具有高质量SourceMaps的开发版本的推荐选择。
eval-cheap-source-map
只精确到行所以比eval-source-map更快
source-map 生产调试推荐
具有高质量SourceMaps的生产版本的推荐选择。
devtool:""
Rule.oneOf
规则数组,当规则匹配时,只使用第一个匹配规则。
不能有2个配置处理同一种类型文件
rules: [
{
test: /\.css$/,
oneOf: [
{
resourceQuery: /inline/, // foo.css?inline
use: 'url-loader'
},
{
resourceQuery: /external/, // foo.css?external
use: 'file-loader'
}
]
}
]
eslint-loader bug error
该加载程序eslint-loader将很快被弃用,请改用此插件
cnpm install eslint --save-dev
cnpm install eslint-webpack-plugin --save-dev
const ESLintPlugin = require('eslint-webpack-plugin');
plugins: [new ESLintPlugin(options)],
提取css
cnpm install --save-dev mini-css-extract-plugin
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
plugins: [new MiniCssExtractPlugin()],
use: [MiniCssExtractPlugin.loader, 'css-loader'],
压缩css
cnpm install css-minimizer-webpack-plugin --save-dev
压缩html
npm install html-minimizer-webpack-plugin --save-dev
const HtmlMinimizerPlugin = require("html-minimizer-webpack-plugin");
optimization: {
minimize: true,
minimizer: [
// For webpack@5 you can use the `...` syntax to extend existing minimizers (i.e. `terser-webpack-plugin`), uncomment the next line
// `...`
new HtmlMinimizerPlugin(),
],
},
缓存 cache
babel缓存和静态资源缓存
缓存生成的 webpack 模块和 chunk,来改善构建速度。
cache会在开发模式被设置成 type: 'memory' 磁盘存储
而且在 生产模式中被禁用。
memory 选项很简单,webpack 将内容存放在 内存中
cache: { 磁盘存储
type: 'filesystem',
cacheDirectory: path.resolve(__dirname, '.temp_cache'),
},
需要第二次刷新 network查看
304协商缓存
协商缓存的2个字段
ETag: W/"17b-1781a5e7a60"
Last-Modified: Wed, 10 Mar 2021 04:21:42 GMT
200+memory cache 说明是强制缓存
请求头客可见
Status Code: 200 OK (from memory cache)
响应头可见
Cache-Control: public, max-age=3600
这里会出现问题
所以要用contenthash
filename: 'js/bundle.[contenthash:6].js',
{ filename: "css/built.[contenthash:6].css" },
hash 所有文件全部生成同一个hash,一个变所有的都重新打包
chunkhash 根据chunk生成同一个hash,如果打包来源于同一个chunk
contenthash 根据不同的文件内容生成的hash
服务器下查看缓存结果
const express = require("express");
const app = express();
app.use(express.static("dist", { maxAge: 1000 * 3600 }));
app.listen(3333)
cache-loader
允许缓存以下 loaders 到(默认)磁盘或数据库
rules: [
{
test: /\.js$/,
use: ['cache-loader', 'babel-loader'],
include: path.resolve('src')
}
]
tree shaking去除无用代码
tree shaking 去除无用代码
1. 必须使用es6模块化
2. 开启production
3. v5已经支持commonjs啦,但不是所有情况都支持
并且5版本比4更牛逼,多层没用到的依赖也可以摇掉
Tree Shaking只支持ES Module
usedExprots: true意思就是我们去查看哪些导出的模块被使用,
然后再进行打包;然后我们在package.json中进行下面的配置:
添加"sideEffects": false,意思就是,对所有的模块都进行
Tree Shaking也就是将没有引入的方法等不进行打包到打包输出文件中。
生产环境下自动开启
开发环境下
mode: 'development',
optimization: {
usedExports: true,
},
package.json中进行下面的配置
"sideEffects": [
"*.css" css不进行树妖检查
]
SplitChunksPlugin
代码分割
all 可能特别强大,因为这意味着 chunk
可以在异步和非异步 chunk 之间共
optimization: {
splitChunks: {
chunks: 'all',
},
},
},
懒加载和预加载
PWA
npm install workbox-webpack-plugin --save-dev
eslint不认识window navigator全局变量
需要修改packjson种eslintconfig配置
"env":{
"browser/node":true
}
sw必须运行在服务器 npm i serve -g
serve -s build
const WorkboxPlugin = require('workbox-webpack-plugin');
new WorkboxPlugin.GenerateSW({
// 帮助快速启用 ServiceWorkers
// 删除“旧的” ServiceWorkers
clientsClaim: true,
skipWaiting: true,
}),
在入口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);
});
});
}