目录
Webpack 是 前端资源打包工具,它会根据模块之间的依赖关系进行静态分析,将模块按照指定的规则生成对应的静态资源。
webpack会从入口文件开始打包,先形成依赖关系图,根据依赖图把不同的资源引进来形成一个chunk代码块, 然后根据chunk根据不同的资源进行处理,比如: less => css, 这个处理过程就是 打包,打包之后输出去,输出去的文件 就是 bundle。
Webpack 处理是会构建出一个依赖图,该依赖图映射项目所需的每个模块,并将多种静态资源 js、css、less 转换成一个静态文件bundle.js,减少了页面的请求。
从 v4.0.0 开始,webpack 可以不用再引入一个配置文件来打包项目,然而,但它仍然有着 高度可配置性
入口指示Webpack 以哪个文件为起点开始打包,分析构建内部 依赖图(dependency graph) 。默认是 './src/index.js', 可以通过配置指定 entry 属性,指定一个或多个 入口起点。
webpack.config.js
- module.exports = {
- entry: './src/index.js'
- }
输出指示Webpack打包后的资源bundle 输出到哪里去,以及如何命名。
Loader 让 Webpack 能够去处理那些非 JavaScript 文件(Webpack 自身只理解JavaScript),把文件转成 webpack可以识别的 js 文件。
插件(plugins)可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量等。
通过选择 development
, production
或 none
之中的一个,来设置 mode
参数,你可以启用 webpack 内置在相应环境下的优化。其默认值为 production
。
1. 新建文件夹, npm init
2. 引入 webpack webpack-cli, 先 -g 全局引入(这样可以直接用 webpack-cli 的命令),再 -D 引入
- npm webpack webpack-cli -g
-
- npm webpack webpack-cli -D
3. 新建代码文件夹 src, 打包输出的文件夹 build
新建 index.js 入口文件
-
- function add(x, y) {
- return x+y;
- }
- console.log(add(1,2));
/**
* index,js: webpack 入口起点文件
* 1. 运行指令
* 开发环境: webpack ./src/index.js -o ./build/built.js --mode=development
* webpack会以 ./src/index.js 为入口文件开始打包,打包输出到 ./build/built/main.js
* 整体打包环境,是开发环境
*
* 生产环境:webpack ./src/index.js -o ./build/built.js --mode=production
* webpack会以 ./src/index.js 为入口文件开始打包,打包输出到 ./build/built/main.js
* 整体打包环境,是生产环境
*/
webpack ./src/index.js -o ./build/built.js --mode=development
会生成built.js/main.js, main.js里面是 打包的内容
main.js 文件 eval 函数 包含了 index.js 的所有内容,包括注释。
webpack ./src/index.js -o ./build/built.js --mode=production
文件 main.js 里面 是 webpack帮你压缩好的 代码了,我的是 webpack5, 好家伙,直接剩下一个运行语句
node .\build\built.js\main.js
1. webpack 能处理 js/json文件,不能处理css/img等其他资源
2. 生产环境和开发环境将 ES6 模块化编译成浏览器能识别的模块化
3. 生产环境比开发环境多一个压缩 js 代码。
src 文件夹 下建 index.js(入口文件), index.css 样式文件, index.less 样式
build 文件夹,建 index.html
根目录新建一个 webpack.config.js 文件
初始配置模板:
- /**
- * webpack.config.js webpack的配置文件
- *
- * 作用: 指示webpack 干哪些活( 当运行 webpack 指令时,会加载里面的配置)
- *
- * 所有构建工具都是基于 node.js 平台运行的 —— 模块化默认采用 common.js
- */
- // resolve 用来拼接绝对路径的方法
- const { resolve } = require('path');
- module.exports = {
- // 入口
- entry: './src/index.js',
- // 输出
- output: {
- // 输出文件名
- filename: 'built.js',
- // 输出路径,绝对路径
- // __dirname nodejs的变量,代表当前文件的目录绝对路径
- path: resolve(__dirname, 'build')
- },
- // loader 的配置
- module: {
- rules: [
- // 详细 loader 配置
- // 不同文件必须配置不同loader 配置
- {
- // test 匹配哪些文件
- test: /\.css$/,
- //使用哪些 loader 进行处理
- use: [
- // use 数组中 loader 执行顺序: 从右到左,从下到上,依次执行
- // 创建style 标签,将 js 中的样式资源插入进去,添加到 head 中生效
- 'style-loader',
- // 将css文件变成commonjs模块加载 js 到中,里面内容是样式字符串
- 'css-loader'
- ]
- },
- {
- test: /\.less$/,
- use: [
- 'style-loader',
- 'css-loader',
- // 将less文件编译成 css文件
- 'less-loader'
- ]
- }
- ]
- },
- // plugins 的配置
- plugins: [
- // 详细 plugins 的配置
- ],
- // 模式
- mode: 'development', // 或 'production'
- }
注意:__dirname 是两个 _ , 写少一个 bug找半天
控制台输入 webpack 即可 运行打包,并且 index.css的样式 生效于 index.html中
/**
* loader : 1.下载 2. 使用(配置loader)
* plugins: 1. 下载 2. 引入 3. 使用
*/
plugins 引入 html-webpack-plugins
-
- const { resolve } = require('path')
- const HtmlWebpackPlugin = require('html-webpack-plugin');
-
- module.exports = {
- entry: './src/index.js',
- output: {
- filename: 'built.js',
- path: resolve(__dirname, 'build')
- },
- module: {
- rules: []
- },
- plugins: [
- // html-webpack-plugin
- // 功能: 默认会创建一个空的 html,自动引入打包输出的所有资源(JS/CSS)
- // 需要有结构的html文件
- new HtmlWebpackPlugin({
- // 复制 ./src/index.html 文件, 并自动引入打包输出的所有资源(JS/CSS)
- template: './src/index.html'
- })
- ],
- mode: 'development'
- }
webpack5 自带图片处理,可以直接使用 assets Module, webpack4 的话 就要 加上 url-loader, 有的还需要 加 file-loader.
在index.less 文件中 引入 图片
- body,html {
- margin: 0;
- padding:0;
- }
-
- .one {
- height: 100px;
- width: 200px;
- background-image: url('./1.jpg');
- background-repeat: no-repeat;
- background-size: 100% 100%;
- }
- .tow {
- height: 200px;
- width: 200px;
- background-image: url('./2.png');
- background-repeat: no-repeat;
- background-size: 100% 100%;
- }
- .three {
- height: 300px;
- width: 300px;
- background-image: url('./3.jpg');
- background-repeat: no-repeat;
- background-size: 100% 100%;
- }
index.html 文件
- html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>打包图片资源title>
- head>
- <body>
- <div id="app">
- <div class="one">div>
- <div class="tow">div>
- <div class="three">div>
- <img src="./1.jpg" alt="图片">
- div>
- body>
- html>
url-loader: webpack5的 不用 加该loader, webpack5会自动处理.
-
- {
- // 处理图片资源
- test: /\.(jpg|png|gif)$/,
- // 下载url-loader file-loader
- loader: 'url-loader',
- options: {
- // 图片大小小于 300kb, 就会被 base64处理
- // 优点:减少请求数量(减轻服务器压力)
- // 优点: 图片体积会更大(文件请求速度更慢)
- limit: 200 * 1024,
- // 问题: 因为url-loader默认使用 es6 模块化解析,而 html-loader 引入图片是 commonjs
- // 解析时会出现问题: [object Module]
- // 解决: 关闭 url-loader 的 es6 模块化, 使用 commonjs 解析
- esModule: false,
- // 给图片进行重命名(没必要)
- // [hash:10] 取图片的hash 的前 10位
- // [ext] 取文件原来扩展名
- // name: '[hash:10].[ext]'
- }
- }
html-loader: 处理html文件的img 图片(负责引入img,从而被 url-loader 进行处理)
-
- {
- test: /\.html$/,
- // 处理html文件的img 图片(负责引入img,从而被 url-loader 进行处理)
- loader: 'html-loader'
- }
同样 webpack 5 会自动处理或用 asset Module 处理,不需要另外加 url-loader
以 引入 iconfont 字体库 为例
- module.exports = {
- ........
- ..........
- ............
- {
- // 处理图片资源 webpack5图片新打包方法
- test: /\.(jpg|png|gif)$/,
- // webpack5中使用assets-module(url-loader已废弃)
- type: 'asset/resource',
- parser: {
- dataUrlCondition: {
- maxSize: 10 * 1024
- }
- },
- generator: {
- filename: 'img/[name].[hash:6][ext]',
- publicPath: './'
- }
- },
- ...
- ...
- }
index.js 引入 iconfont.css
webpack.config.js
- const HtmlWebpackPlugin = require("html-webpack-plugin")
- const { resolve } = require('path')
- module.exports = {
- entry: './src/index.js',
- output: {
- filename: 'built.js',
- path: resolve(__dirname, 'build'),
- },
- module: {
- rules:[
- {
- test: /\.css$/,
- use: ['style-loader', 'css-loader']
- }
- ]
- },
- plugins: [
- new HtmlWebpackPlugin({
- template: './src/index.html'
- })
- ],
- mode: 'development'
- }
- // 打包其他资源( 除了 html/css/js 资源以外的资源
- {
- // 排除css/js/html资源
- exclude: /\.(css|js|html)$/,
- loader: 'url-loader',
- options: {
- type: 'javascript/auto',
- esModule: false,
- }
- }
下载 webpack-dev-server
// 开发服务器 devServer: 用来自动化(自动编译,自动打开浏览器,自动刷新浏览器~)
// 特点: 只会在内存中编译打包,不会有任何输出
// 启动 devServer 指令:
webpack4: npx webpack-dev-server
webpack5: npx webpack server
- const HtmlWebpackPlugin = require("html-webpack-plugin")
- const { resolve } = require('path')
- module.exports = {
- entry: './src/index.js',
- output: {
- filename: 'built.js',
- path: resolve(__dirname, 'build'),
- },
- module: {
- rules:[
- {
- test: /\.css$/,
- use: ['style-loader', 'css-loader']
- },
- ]
- },
- plugins: [
- new HtmlWebpackPlugin({
- template: './src/index.html'
- })
- ],
- mode: 'development',
-
- // 开发服务器 devServer: 用来自动化(自动编译,自动打开浏览器,自动刷新浏览器~)
- // 特点: 只会在内存中编译打包,不会有任何输出
- // 启动 devServer 指令为: npx webpack-dev-server
- devServer: {
- static: {
- directory: resolve(__dirname, 'public')
- },
- // 启动gzip压缩
- compress: true,
- port: 9000,
- // 启动后打开默认浏览器
- open: true
- }
- }
下载 mini-css-extract-plugin
配置loader 和 plugin
loader:
- module: {
-
- rules: [
- {
- test: /\.css$/,
- MiniCssExtractPlugin.loader,
- 'css-loader',
- ]
- }
plugin:
- plugins: [
- new MiniCssExtractPlugin({
- filename: 'css/built.css',
- })
- ]
结果:
/** postcss-loader
* css 兼容性处理: postcss ---> postcss-loader postcss-preset-env
* 帮助 postcss 找到 package.json 中 browserslist 里面的配置,通过配置加载指定的css兼容性样式
*/
1. 设置 nodejs 环境变量
webpack.config.js 加上
process.env.NODE_ENV = 'development';
loader 中配置:webpack5
- {
- test: /\.css$/,
- use: [
- // 创建style标签,插入
- // 'style-loader',
- // 取代 style-loader, 提取js中的 css成单独文件
- MiniCssExtractPlugin.loader,
- // 将css文件 整合到js文件中
- 'css-loader',
- // 使用默认配置
- // 'postcss-loader'
- // 需修改 postcss loader 配置
- {
- loader: 'postcss-loader',
- options: {
- postcssOptions: {
- plugins: [
- ['postcss-preset-env',{}]
- ]
- }
- }
- }
- ]
- },
package.json 加上browserslist 配置
-
- "browserslist": {
- "development": [
- "last 1 chrome version",
- "last 1 firefox version",
- "last 1 safari version"
- ],
- "production": [
- ">0.2%",
- "not dead",
- "not op_mini all"
- ]
- }
webpack4 用插件: optimize-css-assets-webpack-plugin
webpack5 用插件:css-minimizer-webpack-plugin
添加配置
- optimization: {
- minimizer: [
- // 在 webpack@5 中,你可以使用 `...`
- // 语法来扩展现有的 minimizer(即 `terser-webpack-plugin`),将下一行取消注释
- // `...`,
- new CssMinimizerPlugin(),
- ],
- minimize:true,
- },
webpack.config.js
- const { resolve } = require("path");
- const HtmlWebpackPlugin = require('html-webpack-plugin')
- const MiniCssExtractPlugin = require('mini-css-extract-plugin')
- const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')
- // 设置 nodejs 环境变量
- process.env.NODE_ENV = 'development';
-
- module.exports = {
- entry: './src/index.js',
- output: {
- filename: 'js/built.js',
- path: resolve(__dirname, 'build')
- },
- module: {
- rules: [
- {
- test: /\.css$/,
- use: [
- // 取代 style-loader, 提取js中的 css成单独文件
- MiniCssExtractPlugin.loader,
- // 将css文件 整合到js文件中
- 'css-loader',
- // 需修改 postcss loader 配置
- {
- loader: 'postcss-loader',
- options: {
- postcssOptions: {
- plugins: [
- ['postcss-preset-env',{}]
- ]
- }
- }
- }
- ]
- },
- {
- test: /\.html$/,
- loader: 'html-loader'
- }
- ]
- },
- optimization: {
- minimizer: [
- // 在 webpack@5 中,你可以使用 `...`
- // 语法来扩展现有的 minimizer(即 `terser-webpack-plugin`),将下一行取消注释
- new CssMinimizerPlugin(),
- ],
- minimize:true,
- },
- plugins: [
- new HtmlWebpackPlugin({
- template: './src/index.html'
- }),
- new MiniCssExtractPlugin({
- filename: 'css/built.css', // 输出的内容重命名
- }),
- ],
- mode: 'development',
- devServer: {
- static: {
- directory: resolve(__dirname, 'public')
- },
- // 启动 gzip压缩
- compress: true,
- port: 3000,
- open: true,
- }
- }
webpack5 插件: eslint-webpack-plugin
webpack4 : eslint-loader (webpack5 已弃用)
webpack5
-
- const ESLintWebpackPlugin = require('eslint-webpack-plugin');
- ............
- ...............
- ....................................
- plugins: [
- new ESLintWebpackPlugin({
- fix: true,
- }),
- ],
package.json 还需要加上 eslint 配置
- "eslintConfig": {
- "env": {
- "browser": true
- }
- },
如果代码没有做兼容性处理, 代码 根本无法在 IE浏览器正常运行,IE 不认识 ES6 、以及ES6以上的语法;
/**
* js兼容性处理: babel-loader @babel/core @babel/preset-env
* 1. 基本js 兼容处理 => @babel/preset-env
* 问题: 只能转换基本语法, 如 promise 高级语法不能转换
* 2. 全部js 兼容性处理 => @babel/polyfill, 直接在文件中 引入 即可使用
* 问题: 只要解决部分兼容性问题,不需要全部兼容性的代码全部引入,体积太大
* 3. 需要做兼容性处理: 按需引入 => core.js
*/
结合: babel-loader @babel/core 和 core.js 即可 解决 js兼容性问题
- module: {
- rules: [
- {
- test: /\.js$/,
- exclude: /node_modules/,
- loader: 'babel-loader',
- options: {
- // 预设: 指示babel 做什么样的兼容性处理, 智能按需引入polyfill
- presets: [['@babel/preset-env',{
- // 按需加载
- useBuiltIns: 'usage',
- // 指定 core-js版本
- corejs: {
- version: 3
- },
- // 指定兼容哪个版本浏览器
- targets: {
- chrome: '60',
- firefox: '60',
- ie: '9',
- safari: '10',
- edge: '17'
- }
- }]]
- },
- }
- ]
- }
// 生产环境下会自动压缩代码
mode: 'production',
html 压缩,直接配置 HtmlWebpackPlugin
- plugins: [
- new HtmlWebpackPlugin({
- template: './src/index.html',
- // 压缩 html代码
- minify: {
- // 移除空格
- collapseWhitespace: true,
- // 移除空格
- removeComments: true
- }
- })
- ]
webpack.config.js
-
- const { resolve } = require('path')
- const MiniCssExtractPlugin = require('mini-css-extract-plugin')
- const CssMinimizerWebpackPlugin = require('css-minimizer-webpack-plugin')
- const HtmlWebpackPlugin = require('html-webpack-plugin')
-
- process.env.NODE_ENV = 'production'
- const commonCssLoader = [
- MiniCssExtractPlugin.loader,
- 'css-loader',
- {
- loader: 'postcss-loader',
- options: {
- postcssOptions: {
- plugins:[
- [
- 'postcss-preset-env',
- {
-
- }
- ]
- ]
- }
- }
- }
- ]
- module.exports = {
- entry: './src/index.js',
- output: {
- filename: 'js/built.js',
- path: resolve(__dirname, 'build')
- },
- module: {
- rules: [
- {
- test: /\.css$/,
- use: [...commonCssLoader]
- },
- {
- test: /\.less$/,
- use: [...commonCssLoader, 'less-loader']
- },
- {
- test: /\.js$/,
- exclude: /node_modules/,
- loader: 'babel-loader',
- options: {
- presets: [
- [
- '@babel/preset-env',
- {
- useBuiltIns: 'usage',
- corejs: { version: 3},
- targets: {
- chrome: '60',
- firefox: '60',
- ie: '9',
- safari: '10',
- edge: '17'
- }
- }
- ]
- ]
- }
- },
- {
- // 处理图片资源 webpack5图片新打包方法
- test: /\.(jpg|png|gif)$/,
- // webpack5中使用assets-module(url-loader已废弃)
- type: 'asset/resource',
- parser: {
- dataUrlCondition: {
- maxSize: 10 * 1024
- }
- },
- generator: {
- filename: 'img/[name].[hash:6][ext]',
- publicPath: './'
- }
- },
- {
- test: /\.(eot|ttf|otf|woff2?)$/,
- type: 'asset',
- generator: {
- filename: 'fonts/[name].[hash:8][ext]'
- }
- },
- {
- test: /\.html/,
- loader: 'html-loader'
- },
- {
- exclude: /\.(js|css|less|html|jpg|png|gif|eot|ttf|otf|woff2)$/,
- loader: 'file-loader',
- options: {
- outputPath: 'media'
- }
- }
- ]
- },
- optimization: {
- minimizer: [
- new CssMinimizerWebpackPlugin()
- ],
- minimize: true,
- },
- plugins: [
- new HtmlWebpackPlugin({
- template: './src/index.html',
- minify: {
- collapseWhitespace: true,
- removeComments: true,
- }
- }),
- // 提取css成单独文件
- new MiniCssExtractPlugin({
- filename: 'css/built.css'
- }),
- ],
- mode: 'production',
- devServer: {
- static: {
- directory: resolve(__dirname, 'public')
- },
- compress: true,
- port: 3000,
- open: true,
- // 当修改了 webpack配置,想要 新配置生效,必须要重新打包
- hot: true,
- }
- }
优化打包构建速度
* HMR
优化代码调试
*source-map
优化打包构建速度
* oneOf
* babel缓存
* 多进程打包
*extrernals
*dll
优化代码运行速度
*文件资源缓存 (hash - chunkhash - contenthash)
hash 每次打包都会成功一个 hash 值
chunkhash 同一个chunkhash 共用一个 chunkhash 值
contenthash 一个内容文件一个 contenthash, 内容不变,contenthash不变
* tree shaking
*code split
*l懒加载/ 预加载
*pwa
HMR: hot module replacement 热模块替换 / 模块热替换
作用: 一个模块发生变化,只会重新打包这一模块(而不会打包所有模块)
极大提高构建速度
直接在 devServer配置 加上 hot: true
- devServer: {
- static: {
- directory: resolve(__dirname, 'public')
- },
- compress: true,
- port: 3000,
- open: true,
- // 当修改了 webpack配置,想要 新配置生效,必须要重新打包
- hot: true,
- }
样式文件:可以使用HMP 功能, 因为 style-loader 内部实现了
js文件:默认不能使用HMP功能
html文件:默认不能使用 HMP功能, 同时会导致问题,html 文件不能热更新了(不需要做HMP功能)
解决: 修改entry 入口,将html 文件引入
entry: ['./src/index.js', './src/index.html'],
source-map: 能提供 源代码 到 构建后代码的 映射 关系,通过映射追踪可以定位到具体代码出错的位置。
在webpack.config.js 中配置 devtool: 'source-map' 即可开启
可选值:[inline-|hidden-|eval_][nosources-][cheap-[module-]]source-map
- module.exports = {
- devtool: 'source-map',
- }
开发环境下: 速度快,调试更友好
速度快(eval > inline > cheap....)
eval-cheap-source-map
eval-source-map
调试更友好
source-map
cheap-module-source-map
cheap-source-map
生产环境:源码要不要隐藏?调试要不要友好
内联会让代码体积变大,所以生产环境下不用内联
nosources-source-map 全部隐藏
hidden-source-map 只隐藏源代码,会提示构建后代码错误信息
--》source-map / cheap-module-source-map
把loader 放到 oneOf下,oneOf 下的loader 只会匹配一个
// 注意: 不能有两个匹配处理同一种类型的文件,如有两个loader处理同一种类型文件( 如下两个loader 都处理 js 文件,把有限的一种 放在 oneOf外面),只需要把 有限处理的loader 放到 oneOf上面即可,
- module: {
- rules: [
- {
- test: /\.js$/,
- exclude: /node_modules/,
- exforce: 'pre',
- loader: 'eslint-loader',
- options: {
- fix: true
- }
- },
- {
- oneOf: [
- {
- test: /\.js$/,
- exclude: /node_modules/,
- loader: 'babel-loader',
- options: {
- presets: [
- [
- '@babel/preset-env',
- {
- useBuiltIns: 'usage',
- corejs: { version: 3},
- targets: {
- chrome: '60',
- firefox: '60',
- ie: '9',
- safari: '10',
- edge: '17'
- }
- }
- ]
- ]
- }
- },
- ]
- }
- ],
- },
cacheDirectory: true
--> 让第二次打包构建速度更快
在webpack中使用babel-loader是去为了兼容我们的js代码,将更高级的语法转译成浏览器所能识别语法,但是这个过程编译过程会很慢。
- {
- test: /\.js$/,
- exclude: /node_modules/,
- loader: 'babel-loader',
- options: {
- presets: [
- [
- '@babel/preset-env',
- {
- useBuiltIns: 'usage',
- corejs: { version: 3},
- targets: {
- chrome: '60',
- firefox: '60',
- ie: '9',
- safari: '10',
- edge: '17'
- }
- }
- ]
- ],
- // 开启babel缓存
- // 第二次构建时,会读取之前的缓存
- cacheDirectory: true
- }
- },
hash: 每次webpack 构建时会生成一个唯一的 hash 值;
问题: 因为js 和 css 同时使用一个 hash 值。如果重新打包,会导致所有缓存失效(可能只改一个文件)。
chunkhash: 根据 chunk 生成的 hash 值。如果打包来源同一个 chunk,那hash值一样。
问题: js 和 css 的hash 值还是一样的,因为 css 是在 js 中被引入的,所有属于同一个 chunk.
contenthash: 根据文件的内容生成 hash 值。不同文件hash 值不同。 推荐使用。
输出js文件:取 contenthash 值 10位
- output: {
- filename: 'js/built.[contenthash:10].js',
- path: resolve(__dirname, 'build')
- },
提取的 css文件:取 contenthash 值 10位
- plugins: [
- // 提取css成单独文件
- new MiniCssExtractPlugin({
- filename: 'css/built.[contenthash:10].css'
- }),
- ],
去掉没有用代码
前提: 1. 必须使用ES6模块化 2. 开启 production 环境
作用: 减少代码体积
在package.json 中配置
"sideEffect": false 所有代码都没有副作用,都可以进行tree shaking
问题: 可能会把css / @babel/polyfill 文件干掉
"sideEffects": ["*.css", "*.less"]
1. 多入口文件
有几个入口,就会生成 几个js文件
- // 多入口
- entry: {
- main: './src/index.js',
- test: './src/test.js'
- },
2. module.exports中 配置 optimization
/**
* 1. 可以将 node_modules中代码单独打包成一个 chunk 最终输出
* 2. 自动分析多入口 chunk 中, 有没有公共的文件,如果有会打包成单独一个 chunk
*/
- optimization: {
- splitChunks: {
- chunks: 'all',
- },
- // 将当前模块记录其他模块的hash 单独打包为一个文件 runtime
- // 解决: 修改 test.js文件 导致 indexjs 文件的 contenthash 变化
- runtimeChunk: {
- name: entrypoint => `runtime-${entrypoint.name}`
- }
- },
3. 通过js 代码单独打包
通过 js 代码,让某个文件被单独打包成一个 chunk
import 动态导入语法: 能将某个文件单独打包
- import('./test.js')
- .then(({ mul, count}) => {
- // 文件加载成功
- console.log(mul(2, 5))
- console.log(count([1,2,3,4,5]))
- }).catch(() => {
- // 文件加载失败
- })
懒加载: 当文件需要使用时才加载
预加载 prefetch:会在使用前,提前加载 js 文件。(等其他资源加载完毕,浏览器空闲了,载加载资源)慎用预加载,会有兼容性问题。
点击按钮的时候,在 import 文件
- document.getElementById('bnt').onclick = function () {
- import(/*webpackChunkName: 'test'*/'./test.js')
- .then(({ mul, count}) => {
- console.log(mul(2, 5))
- console.log(count([1,2,3,4,5]))
- }).catch(() => {
-
- })
- }
官网上截取:
添加 workbox-webpack-plugin 插件,然后调整 webpack.config.js
文件:
npm install workbox-webpack-plugin --save-dev
webpack.config.js
- plugins: [
- new WorkboxPlugin.GenerateSW({
- // 这些选项帮助快速启用 ServiceWorkers
- // 不允许遗留任何“旧的” ServiceWorkers
- clientsClaim: true,
- skipWaiting: true,
- }),
- ],
接下来我们注册 Service Worker,使其出场并开始表演。通过添加以下注册代码来完成此操作:
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);
- + });
- + });
- + }
注意 package.json 如果项目加上了Eslint 检查,需要加上 支持全局变量
- "eslintConfig": {
- "env": {
- "browser": true
- }
- },
thread-loaderhttps://webpack.docschina.org/loaders/thread-loader/#root
externals 排除某些文件的打包, 例如 ’jQuery'
官网截取:
string
object
function
RegExp
[string, object, function, RegExp]
防止将某些 import
的包(package)打包到 bundle 中,而是在运行时(runtime)再去从外部获取这些扩展依赖(external dependencies)。
例如,从 CDN 引入 jQuery,而不是把它打包:
index.html
- <script
- src="https://code.jquery.com/jquery-3.1.0.js"
- integrity="sha256-slogkvB1K3VOkzAI8QITxV3VzpOnkeNVsKvtkYLMjfk="
- crossorigin="anonymous"
- ></script>
webpack.config.js
- module.exports = {
- //...
- externals: {
- jquery: 'jQuery',
- },
- };
DllPlugin 用法https://webpack.docschina.org/plugins/dll-plugin#usage