Webpack学习笔记
学习来源:尚硅谷
学习时间:2022年3月23日
1 简介
1.1 webpack是什么
webpack 是一种前端资源构建工具,一个静态模块打包器(module bundler
)。
在 webpack 看来, 前端的所有资源文件(js/json/css/img/less/...
)都会作为模块处理。
它将根据模块的依赖关系进行静态分析,打包生成对应的静态资源(bundle
)。
1.2 五个核心概念
Entry
:入口(Entry)指示 webpack 以哪个文件为入口起点开始打包,分析构建内部依赖图。
Output
:输出(Output)指示 webpack 打包后的资源 bundles 输出到哪里去,以及如何命名。
Loader
:Loader 让 webpack 能 够 去 处 理 那 些 非 JavaScript 文 件 (webpack 自身只理解JavaScript)
Plugins
: 插件(Plugins)可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩, 一直到重新定义环境中的变量等。
Mode
:模式(Mode)指示 webpack 使用相应模式的配置。
选项 |
描述 |
特点 |
development |
会将 DefinePlugin 中 process.env.NODE_ENV 的值设置 为 development。启用 NamedChunksPlugin 和 NamedModulesPlugin。 |
能让代码本地调试 运行的环境 |
production |
会将 DefinePlugin 中 process.env.NODE_ENV 的值设置 为 production。启用 FlagDependencyUsagePlugin, FlagIncludedChunksPlugin, ModuleConcatenationPlugin, NoEmitOnErrorsPlugin, OccurrenceOrderPlugin, SideEffectsFlagPlugin 和 TerserPlugin。 |
能让代码优化上线 运行的环境 |
2 初体验
2.1 初始化配置
- 新建项目文件夹
/webpack/exp
,初始化包管理文件:
- 新建文件夹
src
和build
,前者存放要打包的入口文件和各类静态资源,后者存放打包后的文件
- 下载并安装webpack:包括全局模式和开发模式
1 2
| npm i webpack@4.41.6 webpack-cli@3.3.11 -g npm i webpack@4.41.6 webpack-cli@3.3.11 -D
|
2.2 编译打包应用
- 在src下新建文件
index.js
和data.json
:
1 2 3 4
| { "name": "Hongyi", "age": 12 }
|
1 2 3 4 5 6 7 8 9
| import data from "./data.json"
console.log(data);
function add(x, y) { return x + y; }
console.log(add(1, 2));
|
运行结果:
1 2 3 4 5 6 7 8 9
| Hash: 56e483aa30f05a7456dd Version: webpack 4.41.6 Time: 57ms Built at: 2022-03-23 8:21:22 ├F10: PM┤ Asset Size Chunks Chunk Names built.js 5.2 KiB main [emitted] main Entrypoint main = built.js [./src/data.json] 42 bytes {main} [built] [./src/index.js] 732 bytes {main} [built]
|
打包生成后的built.js
文件可以直接执行:
1 2
| { name: 'Hongyi', age: 12 } 3
|
- 在src下新建页面
index.html
,引用该打包文件:
1 2 3 4 5 6 7 8 9 10 11 12 13
| <!DOCTYPE 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>Document</title> </head> <body> <script src="./built.js"></script> </body> </html>
|
执行结果:
结论
- webpack能处理js/json资源,不能处理css/img等其他资源
- 生产环境比开发环境多一个压缩js代码
- 生产环境和开发环境将es6模块化编译成浏览器能够识别的模块化
3 开发环境的基本配置
前言:总项目文件夹为webpack
,下面建立各个分项目,例如01exp
、02csspack
等,下载模块时,统一在总项目文件夹下执行npm i
命令。这样分项目在找模块时,统一从上级目录,即总项目文件夹下寻找模块node_modules
。
3.1 创建配置文件
- 新建项目文件夹
webpack/02csspack
,并新建src
和build
。
- 在
02csspack
新建webpack的配置文件webpack.config.js
,基本框架为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
|
const {resolve} = require("path");
module.exports = {
entry: "", output: { filename: "", path: resolve(__dirname, "build") }, module: { rules: [ { test: , use: [ ] } ] }, plugins: [
], mode: "", }
|
3.2 打包样式资源
需求:打包css
和less
样式资源
- 在src下新建文件
index.js
,index.css
和index.less
1 2 3 4 5 6
| html, body{ margin: 0; padding: 0; height: 100%; background-color: pink; }
|
1 2 3
| #title{ color: green; }
|
1 2 3
| import "./index.css"; import "./index.less";
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| 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" ] }, { test: /\.less$/, use: [ "style-loader", "css-loader", "less-loader" ] } ] }, plugins: [
], mode: "development", }
|
- 下载打包css和less需要的loader模块(在父项目中运行)
1
| npm i css-loader@3.4.2 style-loader@1.1.3 less-loader@5.0.0 -D
|
打包文件built.js
的部分内容
- 在
build
下新建页面index.html
,引入样式资源
1 2 3 4 5 6 7 8 9 10 11 12 13
| <!DOCTYPE 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>Document</title> </head> <body> <h1 id="title">Hello World</h1> <script src="./built.js"></script> </body> </html>
|
运行结果
可见样式资源生效,其中<head>
标签中插入了解析好的<style>
标签:
3.3 打包html资源
- 按上两节的同样结构创建子项目
03htmlpack
- 新建
index.js
和index.html
,注意后者并没有显式地引用前者
1 2 3 4 5
| function add(x, y) { return x + y; }
console.log(add(2, 3));
|
1 2 3 4 5 6 7 8 9 10 11
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <h1 id="title">Hello World</h1> </body> </html>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| 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: [ new HtmlWebpackPlugin() ], mode: "development" }
|
打包html资源,需要使用html-webpack-plugin
插件:
1
| npm i html-webpack-plugin@3.2.0 -D
|
执行打包命令后,在build
目录下会创建好built.js
和index.html
,其中,index.html
会自动引入built.js
,但是没有结构(即没有./src/index.html
里的结构内容):
1 2 3 4 5 6 7 8 9
| <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Webpack App</title> </head> <body> <script type="text/javascript" src="built.js"></script></body> </html>
|
- 修改webpack配置文件,输出有结构的html:
1 2 3 4 5 6 7 8 9 10 11 12 13
| module.exports = { plugins: [ new HtmlWebpackPlugin({ template: "./src/index.html" }) ] }
|
执行打包命令,输出的html内容如下:
1 2 3 4 5 6 7 8 9 10 11 12
| <!DOCTYPE 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>Document</title> </head> <body> <h1 id="title">Hello World</h1> <script type="text/javascript" src="built.js"></script></body> </html>
|
3.4 打包图片资源
- 新建子项目
04imgpack
,新建入口文件index.js
、页面index.html
和样式文件index.less
,并在src下存放三张图片:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <!DOCTYPE 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>Document</title> </head> <body> <div id="box1"></div> <div id="box2"></div> <div id="box3"></div> <img src="./angular.jpg"> </body> </html>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| #box1{ width: 100px; height: 100px; background-image: url("./vue.jpg"); background-repeat: no-repeat; background-size: 100% 100%; }
#box2{ width: 200px; height: 200px; background-image: url("./react.png"); background-repeat: no-repeat; background-size: 100% 100%; }
#box3{ width: 300px; height: 300px; background-image: url("./angular.jpg"); background-repeat: no-repeat; background-size: 100% 100%; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| 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: [ { test: /\.less$/, use: [ "style-loader", "css-loader", "less-loader" ] }, { test: /\.(jpg|png|gif)$/, loader: "url-loader", options: { limit: 8 * 1024, esModule: false, name: "[hash:10].[ext]" } }, { test: /\.html$/, loader: "html-loader" } ] }, plugins: [ new HtmlWebpackPlugin({ template: "./src/index.html" }) ], mode: "development" }
|
打包样式中引入的图片资源,需要下载url-loader
,它又依赖file-loader
:
1
| npm i url-loader@3.0.0 file-loader@5.0.2 -D
|
打包html页面中通过img标签引入的图片资源,需要下载tml-loader
:
1
| npm i html-loader@0.5.5 -D
|
- 执行打包指令:在build目录下生成对应的js、html和图片,其中小于8kb的图片不会生成,它直接被base64编码为字符串,供浏览器直接解析为图片
打包产生的index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <!DOCTYPE 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>Document</title> </head> <body> <div id="box1"></div> <div id="box2"></div> <div id="box3"></div> <img src="9a4a32dc0c.jpg"> <script type="text/javascript" src="built.js"></script></body> </html>
|
执行结果
3.5 打包其他资源
打包其他资源需要file-loader
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <!DOCTYPE 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>Document</title> </head> <body> <span class="iconfont icon-dizhi"></span> <span class="iconfont icon-hongbao"></span> <span class="iconfont icon-fanhui"></span> </body> </html>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| 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: [ { test: /\.css$/, use: [ "style-loader", "css-loader" ] }, { exclude: /\.(css|html|js)$/, loader: "file-loader" } ] }, plugins: [ new HtmlWebpackPlugin({ template: "./src/index.html" }) ], mode: "development" }
|
3.6 devServer
devServer
用于热打包,自动打包(自动编译,自动打开浏览器,自动刷新浏览器…)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| const {resolve} = require("path"); module.exports = { devServer: { contentBase: resolve(__dirname, "build"), compress: true, port: 3000, open: true } }
|
1
| npm i webpack-dev-server@3.10.3 -D
|
运行输出后,光标闪烁,并自动打开浏览器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| Version: webpack 4.41.6 Time: 800ms Built at: 2022-03-25 3:35:25 ├F10: PM┤ Asset Size Chunks Chunk Names 13c51607b8.png 74.3 KiB [emitted] 9a4a32dc0c.jpg 12.7 KiB [emitted] built.js 390 KiB main [emitted] main index.html 521 bytes [emitted] Entrypoint main = built.js [./src/index.js] 22 bytes {main} [built] [./src/index.less] 611 bytes {main} [built] + 27 hidden modules Child html-webpack-plugin for "index.html": 1 asset Entrypoint undefined = index.html [../node_modules/html-webpack-plugin/lib/loader.js!./src/index.html] 572 bytes {0} [built] i 「wdm」: Compiled successfully.
|
特点
devServer只会在内存中编译打包,不会在硬盘中有任何输出。
说明:例如将build
文件夹删除,再执行devServer启动命令,项目下不会有build
及其打包后文件的创建,它只是在内存中创建,关闭服务器后又会将这些在内存中的内容删除。
而webpack执行命令后则会严格按照流程,在硬盘中生成相应的打包文件。
3.7 开发环境配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| const { resolve } = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: './src/js/index.js', output: { filename: 'js/built.js', path: resolve(__dirname, 'build') }, module: { rules: [ { test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] }, { test: /\.css$/, use: ['style-loader', 'css-loader'] }, { test: /\.(jpg|png|gif)$/, loader: 'url-loader', options: { limit: 8 * 1024, name: '[hash:10].[ext]', esModule: false, outputPath: 'imgs' } }, { test: /\.html$/, loader: 'html-loader' }, { exclude: /\.(html|js|css|less|jpg|png|gif)/, loader: 'file-loader', options: { name: '[hash:10].[ext]', outputPath: 'media' } } ] }, plugins: [ new HtmlWebpackPlugin({ template: './src/index.html' }) ], mode: 'development', devServer: { contentBase: resolve(__dirname, 'build'), compress: true, port: 3000, open: true } };
|
运行:
4 生产环境的基本配置
4.1 css优化
4.1.1 提取css成单独文件
之前的打包操作,是将css样式资源全部打包进了built.js
代码中,并由style-loader
创建style标签,将样式放到html中。这样会导致:
- 打包后的js文件过大
- 页面加载时,样式出现屏闪现象
因此打包时,需要将css单独提取出来。
1 2 3 4 5
| #box1 { width: 100px; height: 100px; background-color: pink; }
|
1 2 3 4 5
| #box2 { width: 200px; height: 200px; background-color: red; }
|
1 2
| import "../css/a.css"; import "../css/b.css";
|
1 2 3 4 5 6 7 8 9 10 11 12
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div id="box1"></div> <div id="box2"></div> </body> </html>
|
- 提取css成单独文件,需要下载插件:
mini-css-extract-plugin
1
| npm i mini-css-extract-plugin@0.9.0 -D
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| const {resolve} = require('path'); const HtmlWebpackPlugin = require("html-webpack-plugin"); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); module.exports = { entry: './src/js/index.js', output: { filename: 'js/built.js', path: resolve(__dirname, 'build') }, module: { rules: [ { test: /\.css$/, use: [ MiniCssExtractPlugin.loader, "css-loader" ] }
] }, plugins: [ new HtmlWebpackPlugin({ template: "./src/index.html" }), new MiniCssExtractPlugin({ filename: "css/built.css" }) ], mode: 'development' }
|
执行打包命令,生成相应的打包后的资源:
其中,html页面内容:<link href="css/built.css" rel="stylesheet">
即引入了打包后单独建立的css资源。
1 2 3 4 5 6 7 8 9 10 11 12 13
| <!DOCTYPE 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>Document</title> <link href="css/built.css" rel="stylesheet"></head> <body> <div id="box1"></div> <div id="box2"></div> <script type="text/javascript" src="js/built.js"></script></body> </html>
|
页面效果
4.1.2 css兼容性处理
1 2 3 4 5 6 7
| #box1 { width: 100px; height: 100px; background-color: pink; display: flex; backface-visibility: hidden; }
|
- css兼容性处理需要下载插件
postcss-loader
和postcss-preset-env
1
| npm i postcss-loader@3.0.0 postcss-preset-env@6.7.0 -D
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| const {resolve} = require('path'); const HtmlWebpackPlugin = require("html-webpack-plugin"); const MiniCssExtractPlugin = require("mini-css-extract-plugin");
process.env.NODE_ENV = "development"; module.exports = { entry: './src/js/index.js', output: { filename: 'js/built.js', path: resolve(__dirname, 'build') }, module: { rules: [ { test: /\.css$/, use: [ MiniCssExtractPlugin.loader, "css-loader",
{ loader: "postcss-loader", options: { ident: "postcss", plugins: () => [ require("postcss-preset-env")() ] } } ] }
] }, plugins: [ new HtmlWebpackPlugin({ template: "./src/index.html" }), new MiniCssExtractPlugin({ filename: "css/built.css" }) ], mode: 'development' }
|
注意:打包时,默认采用生产环境对css兼容性问题进行处理,与配置文件中的mode无关。如果要使用开发环境对css处理,采用第5行代码。
- 在项目根目录的
package.json
中,添加浏览器兼容版本的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| { "name": "webpack_code", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC", "devDependencies": { "css-loader": "^3.4.2", "file-loader": "^5.0.2", "html-loader": "^0.5.5", "html-webpack-plugin": "^3.2.0", "less": "^3.11.1", "less-loader": "^5.0.0", "mini-css-extract-plugin": "^0.9.0", "postcss-loader": "^3.0.0", "postcss-preset-env": "^6.7.0", "style-loader": "^1.1.3", "url-loader": "^3.0.0", "webpack": "^4.41.6", "webpack-cli": "^3.3.11", "webpack-dev-server": "^3.10.3" }, "browserslist": { "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ], "production": [ ">0.2%", "not dead", "not op_mini all" ] } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| #box1 { width: 100px; height: 100px; background-color: pink; display: flex; -webkit-backface-visibility: hidden; backface-visibility: hidden; } #box2 { width: 200px; height: 200px; background-color: red; }
|
4.1.3 css代码压缩
- 下载压缩插件:
optimize-css-assets-webpack-plugin
1
| npm i optimize-css-assets-webpack-plugin@5.0.3 -D
|
1 2 3 4 5 6 7 8 9 10 11
| const OptimizeCssAssetsWebpackPlugin = require("optimize-css-assets-webpack-plugin"); module.exports = { plugins: [ new OptimizeCssAssetsWebpackPlugin() ], mode: 'development' }
|
执行打包命令,压缩后的css代码:
1
| #box1{width:100px;height:100px;background-color:pink;display:flex;-webkit-backface-visibility:hidden;backface-visibility:hidden}#box2{width:200px;height:200px;background-color:red}
|
4.2 js优化
4.2.1 js语法检查
1
| npm i eslint@6.8.0 eslint-loader@3.0.3 eslint-config-airbnb-base@15.0.0 eslint-plugin-import@2.20.1 -D
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| 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: [ { test: /\.js$/, exclude: /node_modules/, loader: "eslint-loader", options: { fix: true } } ] }, plugins: [ new HtmlWebpackPlugin({ template: "./src/index.html" }) ], mode: 'development' }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| { "name": "webpack_code", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC", "devDependencies": { "css-loader": "^3.4.2", "eslint": "^6.8.0", "eslint-config-airbnb-base": "^15.0.0", "eslint-loader": "^3.0.3", "eslint-plugin-import": "^2.20.1", "file-loader": "^5.0.2", "html-loader": "^0.5.5", "html-webpack-plugin": "^3.2.0", "less": "^3.11.1", "less-loader": "^5.0.0", "mini-css-extract-plugin": "^0.9.0", "optimize-css-assets-webpack-plugin": "^5.0.3", "postcss-loader": "^3.0.0", "postcss-preset-env": "^6.7.0", "style-loader": "^1.1.3", "url-loader": "^3.0.0", "webpack": "^4.41.6", "webpack-cli": "^3.3.11", "webpack-dev-server": "^3.10.3" }, "browserslist": { "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ], "production": [ ">0.2%", "not dead", "not op_mini all" ] }, "eslintConfig": { "extends": "airbnb-base" } }
|
4.2.2 js兼容性处理
1
| npm i babel-loader @babel/core@ @babel/preset-env -D
|
- 问题1:只能转换基本语法,但promise等高级语法则不能转换
- 解决:对全部js语法做兼容性处理,利用
@babel/polyfill
1
| npm i @babel/polyfill -D
|
- 问题2:我只要解决部分兼容性问题,但是将所有兼容性代码全部引入,导致打包后代码体积过大
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| const add = (x, y) => { return x+y; }
console.log(add(1, 1));
const promise = new Promise((resolve) => { setTimeout(() => { console.log("定时器执行完毕"); resolve(); }, 1000); })
console.log(promise);
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| 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: [ { 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" } } ] ] } } ] }, plugins: [ new HtmlWebpackPlugin({ template: "./src/index.html" }) ], mode: 'development' }
|
4.2.3 js和html代码压缩
- 压缩js代码:将mode转换至生产模式即可压缩
- 压缩html代码:增加
HtmlWebpackPlugin
配置
待打包的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <h1>Hello World</h1>
</body> </html>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| const add = (x, y) => { return x+y; }
console.log(add(1, 1));
const promise = new Promise((resolve) => { setTimeout(() => { console.log("定时器执行完毕"); resolve(); }, 1000); })
console.log(promise);
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| 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: [ new HtmlWebpackPlugin({ template: "./src/index.html", minify: { collapseWhitespace: true, removeComments: true } }) ], mode: 'production' }
|
执行打包命令后产生的打包文件:
1
| <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Document</title></head><body><h1>Hello World</h1><script type="text/javascript" src="built.js"></script></body></html>
|
1
| !function(e){var t={};function n(o){if(t[o])return t[o].exports;var r=t[o]={i:o,l:!1,exports:{}};return e[o].call(r.exports,r,r.exports,n),r.l=!0,r.exports}n.m=e,n.c=t,n.d=function(e,t,o){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:o})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(n.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(o,r,function(t){return e[t]}.bind(null,r));return o},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=0)}([function(e,t){console.log(1+1);const n=new Promise(e=>{setTimeout(()=>{console.log("定时器执行完毕"),e()},1e3)});console.log(n)}]);
|
4.3 生产环境配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
| const { resolve } = require('path'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin' ); const HtmlWebpackPlugin = require('html-webpack-plugin');
process.env.NODE_ENV = 'production';
const commonCssLoader = [ MiniCssExtractPlugin.loader, 'css-loader', { loader: 'postcss-loader', options: { ident: 'postcss', plugins: () => [require('postcss-preset-env')()] } } ];
module.exports = { entry: './src/js/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/, enforce: 'pre', loader: 'eslint-loader', options: { fix: true } }, { test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader', options: { presets: [ [ '@babel/preset-env', { useBuiltIns: 'usage', corejs: {version: 3}, targets: { chrome: '60', firefox: '50' } } ] ] } }, { test: /\.(jpg|png|gif)/, loader: 'url-loader', options: { limit: 8 * 1024, name: '[hash:10].[ext]', outputPath: 'imgs', esModule: false } }, { test: /\.html$/, loader: 'html-loader' }, { exclude: /\.(js|css|less|html|jpg|png|gif)/, loader: 'file-loader', options: { outputPath: 'media' } } ] }, plugins: [ new MiniCssExtractPlugin({ filename: 'css/built.css' }), new OptimizeCssAssetsWebpackPlugin(), new HtmlWebpackPlugin({ template: './src/index.html', minify: { collapseWhitespace: true, removeComments: true } }) ], mode: 'production' };
|
运行:
5 优化配置
5.1 HMR
著作権表示: 此文章版权归Kisugi Takumi所有,如有转载,请注明来自原作者