webpack简介

环境

  • Ubuntu 22.04
  • VSCode 1.69.2
  • npm 8.11.0
  • webpack 5.74.0
  • Chrome 104.0.5112.79 (Official Build) (64-bit)

简介

webpack的官网( https://www.webpackjs.com/concepts/ )对其定义如下:

本质上,webpack是一个现代JavaScript应用程序的静态模块打包器(module bundler)。当webpack处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个bundle。

通俗的理解,webpack是一个前端项目工程化的具体解决方案。它提供了友好的前端模块化开发支持,以及代码压缩混淆、处理浏览器端JavaScript的兼容性、性能优化等强大的功能。

我们来通过一个实际的简单项目,了解一下webpack的功能和用法。

准备

新建文件夹 temp0806 ,并运行 npm init -y 初始化项目,生成 package.json 文件:

➜  temp0806 npm init -y
Wrote to /home/ding/temp/temp0806/package.json:

{
  "name": "temp0806",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

项目里会用到jQuery,所以先安装一下:

➜  temp0806 npm install jquery -S                   

added 1 package, and audited 2 packages in 2s

found 0 vulnerabilities

新建 src 目录,并在其中创建 index.htmlindex.js 文件:

  • index.html
<!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>
    <script src="../node_modules/jquery/dist/jquery.min.js"></script>
    <script src="index.js"></script>
</head>

<body>
    <ul>
        <li>No. 1</li>
        <li>No. 2</li>
        <li>No. 3</li>
        <li>No. 4</li>
        <li>No. 5</li>
        <li>No. 6</li>
        <li>No. 7</li>
        <li>No. 8</li>
    </ul>
</body>

</html>
  • index.js
$(function() {
    $('li:odd').css('background-color', 'red')
    $('li:even').css('background-color', 'yellow')
})

打开浏览器,访问 index.html

在这里插入图片描述

本例中,没有借助任何工具,使用了最原始的 <script src="../node_modules/jquery/dist/jquery.min.js"></script> 来导入jQuery。

问题

现在,我们把 index.html 中关于jQuery的部分去掉,改在 index.js 中导入jQuery:

    <!-- <script src="../node_modules/jquery/dist/jquery.min.js"></script> -->
import $ from 'jquery'

刷新浏览器,报错了:

在这里插入图片描述

当然,这个错误是意料之中的,因为 import $ from 'jquery' 没有正确识别。

安装运行webpack

这时就该webpack出场了。

首先要安装 webpackwebpack-cli

➜  temp0806 npm install webpack webpack-cli -D      

added 117 packages, and audited 119 packages in 16s

15 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

修改 package.json 文件,在 scripts 处添加配置 "dev": "webpack" (注意它的上一行末尾要添加 , ):

  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "webpack"
  },

其中 dev 是任意命名的,接下来就可以运行 dev

➜  temp0806 npm run dev

> temp0806@1.0.0 dev
> webpack

asset main.js 88.3 KiB [emitted] [minimized] (name: main) 1 related asset
runtime modules 663 bytes 3 modules
cacheable modules 282 KiB
  ./src/index.js 139 bytes [built] [code generated]
  ./node_modules/jquery/dist/jquery.js 282 KiB [built] [code generated]

WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value.
Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/configuration/mode/

webpack 5.74.0 compiled with 1 warning in 2013 ms

运行结束后,可见在项目里生成了 dist 目录:

在这里插入图片描述

dist 目录里的 main.js 就是打包生成的文件。

接下来我们要修改 index.html ,把 <script src="index.js"></script> 换成 <script src="../dist/main.js"></script> 。然后刷新页面,可见隔行变色的效果成功了,也没有报错了。

配置

配置mode选项

刚才打包时,输出结果里有一个warning,说没有配置 mode 选项,使用了默认的 production 选项。若要消除此warning,需要配置webpack。

在项目根目录下创建文件 webpack.config.js

module.exports = {
    mode: 'development'
}

再次运行 npm run dev

➜  temp0806 npm run dev    

> temp0806@1.0.0 dev
> webpack

asset main.js 323 KiB [emitted] (name: main)
runtime modules 937 bytes 4 modules
cacheable modules 282 KiB
  ./src/index.js 139 bytes [built] [code generated]
  ./node_modules/jquery/dist/jquery.js 282 KiB [built] [code generated]
webpack 5.74.0 compiled successfully in 361 ms

可见,没有warning信息了。

另外,对比 productiondevelopment ,可见前者生成的 main.js 文件较小,而打包花费的时间较长。顾名思义,在开发环境下,更在意打包速度,而在生产环境下,更在意文件大小。

配置entry和output

在webpack中,可以配置打包的入口文件以及输出文件。

  • 默认的打包入口文件为 src -> index.js
  • 默认的输出文件路径为 dist -> main.js

自定义打包的入口文件以及输出文件:

const path = require('path')

module.exports = {
    mode: 'development',
    entry: path.join(__dirname, './src/index.js'),
    output: {
        path: path.join(__dirname, 'dist'),
        filename: 'bundle.js'
    }
}

删掉 dist 文件夹,重新运行 npm run dev ,这回生成的就是 bundle.js 了。

在这里插入图片描述

别忘了 index.html 文件也得修改一下,把使用 index.js 改为使用 bundle.js

插件

webpack-dev-server

如果修改的是 index.html ,则直接刷新浏览器就行。如果修改的是 index.js ,则直接刷新浏览器无效,因为使用的是打包后的 bundle.js

使用 webpack-dev-server 插件,可以让webpack监听项目源代码的变化,并自动打包构建。

注意:如果修改的是 webpack.config.js ,还是需要重新运行打包命令。

首先安装 webpack-dev-server

➜  temp0806 npm install webpack-dev-server -D

added 187 packages, and audited 306 packages in 3s

37 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

接下来把 package.json 里的 "dev": "webpack" 改为 "dev": "webpack serve"

现在删掉 dist 目录,重新运行 npm run dev

➜  temp0806 npm run dev                      

> temp0806@1.0.0 dev
> webpack serve

<i> [webpack-dev-server] Project is running at:
<i> [webpack-dev-server] Loopback: http://localhost:8080/
<i> [webpack-dev-server] On Your Network (IPv4): http://192.168.1.88:8080/
<i> [webpack-dev-server] On Your Network (IPv6): http://[fe80::d0a4:4257:eda6:5aaf]:8080/
<i> [webpack-dev-server] Content not from webpack is served from '/home/ding/temp/temp0806/public' directory
asset bundle.js 560 KiB [emitted] (name: main)
runtime modules 27.3 KiB 12 modules
modules by path ./node_modules/ 440 KiB
  modules by path ./node_modules/webpack-dev-server/client/ 53.5 KiB 12 modules
  modules by path ./node_modules/webpack/hot/*.js 4.3 KiB
    ./node_modules/webpack/hot/dev-server.js 1.59 KiB [built] [code generated]
    ./node_modules/webpack/hot/log.js 1.34 KiB [built] [code generated]
    + 2 modules
  modules by path ./node_modules/html-entities/lib/*.js 81.3 KiB
    ./node_modules/html-entities/lib/index.js 7.74 KiB [built] [code generated]
    ./node_modules/html-entities/lib/named-references.js 72.7 KiB [built] [code generated]
    + 2 modules
  ./node_modules/jquery/dist/jquery.js 282 KiB [built] [code generated]
  ./node_modules/ansi-html-community/index.js 4.16 KiB [built] [code generated]
  ./node_modules/events/events.js 14.5 KiB [built] [code generated]
./src/index.js 139 bytes [built] [code generated]
webpack 5.74.0 compiled successfully in 517 ms

注意命令并没有结束,会一直运行,并且启动了一个HTTP server: http://localhost:8080/

注意:这回并没有生成 dist 目录,它是在内存里的项目根目录下生成了 bundle.js 文件。

  • 如果访问 http://localhost:8080/bundle.js 则会显示其内容。
  • 如果访问 http://localhost:8080/ 会报错 Cannot GET /

查看 webpack-dev-server 的版本:

➜  temp0806 npm list
temp0806@1.0.0 /home/ding/temp/temp0806
├── jquery@3.6.0
├── webpack-cli@4.10.0
├── webpack-dev-server@4.9.3
└── webpack@5.74.0

此处涉及 webpack-dev-server 不同版本的不同配置下的不同行为,为了简单起见,我们使用 npm uninstall webpack-dev-server 卸载当前版本,而指定其版本 3.11.2

➜  temp0806 npm install webpack-dev-server@3.11.2 -D
npm WARN deprecated source-map-url@0.4.1: See https://github.com/lydell/source-map-url#deprecated
npm WARN deprecated urix@0.1.0: Please see https://github.com/lydell/urix#deprecated
npm WARN deprecated resolve-url@0.2.1: https://github.com/lydell/resolve-url#deprecated
npm WARN deprecated source-map-resolve@0.5.3: See https://github.com/lydell/source-map-resolve#deprecated
npm WARN deprecated chokidar@2.1.8: Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies
npm WARN deprecated querystring@0.2.0: The querystring API is considered Legacy. new code should use the URLSearchParams API instead.
npm WARN deprecated uuid@3.4.0: Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.

added 392 packages, and audited 511 packages in 26s

35 packages are looking for funding
  run `npm fund` for details

6 vulnerabilities (1 moderate, 5 high)

To address all issues, run:
  npm audit fix --force

Run `npm audit` for details.

再次运行 npm run dev

➜  temp0806 npm run dev                             

> temp0806@1.0.0 dev
> webpack serve

ℹ 「wds」: Project is running at http://localhost:8080/
ℹ 「wds」: webpack output is served from /
ℹ 「wds」: Content not from webpack is served from /home/ding/temp/temp0806
ℹ 「wdm」: asset bundle.js 649 KiB [emitted] (name: main)
runtime modules 1.25 KiB 6 modules
cacheable modules 580 KiB
  modules by path ./node_modules/webpack-dev-server/client/ 20.9 KiB 10 modules
  modules by path ./node_modules/html-entities/lib/*.js 61 KiB 5 modules
  modules by path ./node_modules/url/ 37.4 KiB
    ./node_modules/url/url.js 22.8 KiB [built] [code generated]
    + 2 modules
  modules by path ./node_modules/querystring/*.js 4.51 KiB
    ./node_modules/querystring/index.js 127 bytes [built] [code generated]
    + 2 modules
  modules by path ./node_modules/webpack/hot/ 1.42 KiB
    ./node_modules/webpack/hot/emitter.js 75 bytes [built] [code generated]
    ./node_modules/webpack/hot/log.js 1.34 KiB [built] [code generated]
  + 8 modules
./node_modules/webpack/hot/ sync nonrecursive ^\.\/log$ 170 bytes [built] [code generated]
webpack 5.74.0 compiled successfully in 671 ms
ℹ 「wdm」: Compiled successfully.

访问 http://localhost:8080/

在这里插入图片描述
点击 src 目录:

在这里插入图片描述
这是因为 index.html 是默认页面,访问 http://localhost:8080/src/ 时会自动查找该页面,等同于 http://localhost:8080/src/index.html

但是由于没有生成 dist 目录,所以报错了。前面提到,是在内存里的项目根目录下生成了 bundle.js 文件。所以修改 index.html ,把 <script src="../dist/bundle.js"></script> 替换为 <script src="/bundle.js"></script>

注意, / 不能省略,表示项目根目录,否则就成了当前( src )目录了。

刷新页面,可见效果出来了。

修改 index.js ,把 yellow 改成 blue ,保存。在保存的同时,webpack会自动重新打包,甚至会自动刷新浏览器页面:

在这里插入图片描述

html-webpack-plugin

源代码是在 src 目录下,所以地址栏中包含了 src 的字样,如果想要在地址栏省略 src ,则可以使用 html-webpack-plugin 插件。

安装 html-webpack-plugin

➜  temp0806 npm install html-webpack-plugin -D      

added 30 packages, and audited 541 packages in 8s

45 packages are looking for funding
  run `npm fund` for details

6 vulnerabilities (1 moderate, 5 high)

To address all issues, run:
  npm audit fix

Run `npm audit` for details.

配置 html-webpack-plugin

const path = require('path')

const HtmlPlugin = require('html-webpack-plugin')

const htmlPlugin = new HtmlPlugin({
    template: './src/index.html',
    filename: './index.html'
  })

module.exports = {
    mode: 'development',
    entry: path.join(__dirname, './src/index.js'),
    output: {
        path: path.join(__dirname, 'dist'),
        filename: 'bundle.js'
    },
    
    plugins: [htmlPlugin]
}

重新运行打包命令 npm run dev ,现在,直接访问 http://localhost:8080 就可以打开 index.html 页面:

在这里插入图片描述当然,仍然可以用 http://localhost:8080/src 访问,效果是一样的。

但是,二者有一个不同之处:我们把 indext.html 中的 <script src="/bundle.js"></script> 删掉。

  • http://localhost:8080/src :隔行变色的效果没有了,这是期望的结果;
  • http://localhost:8080 :隔行变色的效果仍然存在,这是因为 html-webpack-plugin 在生成 index.html 时,会自动注入 bundle.js 文件;

在这里插入图片描述
这里没加 / ,因为 index.html 本来就在项目根目录下。

配置webpack-dev-server

可以通过 devServerwebpack-dev-server 插件进行配置,例如:

module.exports = {
......
    devServer: {
        open: true,
        host: '127.0.0.1',
        port: '9090'
    },
......

重新运行打包命令 npm run dev ,会自动打开浏览器窗口:

在这里插入图片描述

loader

webpack默认只能打包处理 .js 文件,对于其它文件,需要调用 loader 加载器才可以正常打包。比如:

  • css-loader :打包处理 .css 文件
  • less-loader :打包处理 .less 文件
  • babel-loader :打包处理webpack无法处理的高级JS语法

css-loader

src 目录下创建 css 目录,然后在 css 目录下创建 index.css 文件:

li {
    list-style: none;
}

index.js 中引入 index.css

import './css/index.css'

运行打包命令 npm run dev ,报错如下:

➜  temp0806 npm run dev

> temp0806@1.0.0 dev
> webpack serve

ℹ 「wds」: Project is running at http://127.0.0.1:9090/
ℹ 「wds」: webpack output is served from /
ℹ 「wds」: Content not from webpack is served from /home/ding/temp/temp0806
ℹ 「wdm」: wait until bundle finished: /
✖ 「wdm」: asset bundle.js 649 KiB [emitted] (name: main)
asset ./index.html 731 bytes [emitted]
runtime modules 1.25 KiB 6 modules
modules by path ./node_modules/ 580 KiB
  modules by path ./node_modules/webpack-dev-server/client/ 20.9 KiB 10 modules
  modules by path ./node_modules/html-entities/lib/*.js 61 KiB 5 modules
  modules by path ./node_modules/webpack/hot/ 1.58 KiB 3 modules
  modules by path ./node_modules/url/ 37.4 KiB
    ./node_modules/url/url.js 22.8 KiB [built] [code generated]
    + 2 modules
  modules by path ./node_modules/querystring/*.js 4.51 KiB
    ./node_modules/querystring/index.js 127 bytes [built] [code generated]
    + 2 modules
  + 7 modules
modules by path ./src/ 222 bytes
  ./src/index.js 192 bytes [built] [code generated]
  ./src/css/index.css 30 bytes [built] [code generated] [1 error]

ERROR in ./src/css/index.css 1:3
Module parse failed: Unexpected token (1:3)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
> li {
|     list-style: none;
|   }
 @ ./src/index.js 4:0-24

webpack 5.74.0 compiled with 1 error in 878 ms
ℹ 「wdm」: Failed to compile.

错误消息告诉我们,需要合适的loader来处理 .css 文件。

安装 style-loadercss-loader

➜  temp0806 npm i style-loader css-loader -D      

added 16 packages, and audited 557 packages in 6s

48 packages are looking for funding
  run `npm fund` for details

6 vulnerabilities (1 moderate, 5 high)

To address all issues, run:
  npm audit fix

Run `npm audit` for details.

添加配置:

    module: {
        rules: [
          { test: /\.css$/, use: ['style-loader', 'css-loader'] }
        ]
    }
  • test :匹配的文件类型。 /\.css$/ 是正则表达式,其中 \ 表示转义, $ 表示结尾,所以合起来就表示 .css 结尾的文件;
  • use :调用的loader,调用顺序是从右向左;

重新运行打包命令 npm run dev

➜  temp0806 npm run dev                       

> temp0806@1.0.0 dev
> webpack serve

ℹ 「wds」: Project is running at http://127.0.0.1:9090/
ℹ 「wds」: webpack output is served from /
ℹ 「wds」: Content not from webpack is served from /home/ding/temp/temp0806
ℹ 「wdm」: wait until bundle finished: /
ℹ 「wdm」: asset bundle.js 668 KiB [emitted] (name: main)
asset ./index.html 731 bytes [emitted]
runtime modules 1.29 KiB 7 modules
modules by path ./node_modules/ 588 KiB
  modules by path ./node_modules/webpack-dev-server/client/ 20.9 KiB 10 modules
  modules by path ./node_modules/style-loader/dist/runtime/*.js 5.75 KiB 6 modules
  modules by path ./node_modules/html-entities/lib/*.js 61 KiB 5 modules
  modules by path ./node_modules/webpack/hot/ 1.58 KiB 3 modules
  modules by path ./node_modules/url/ 37.4 KiB 3 modules
  modules by path ./node_modules/querystring/*.js 4.51 KiB 3 modules
  modules by path ./node_modules/css-loader/dist/runtime/*.js 2.33 KiB 2 modules
  + 7 modules
modules by path ./src/ 1.78 KiB
  ./src/index.js 192 bytes [built] [code generated]
  ./src/css/index.css 1.14 KiB [built] [code generated]
  ./node_modules/css-loader/dist/cjs.js!./src/css/index.css 464 bytes [built] [code generated]
webpack 5.74.0 compiled successfully in 973 ms
ℹ 「wdm」: Compiled successfully.

在浏览器中可见CSS的效果(小圆点不见了)。

在这里插入图片描述

url-loader

src 目录下创建 images 目录,并在 images 目录下复制一个图片 smile.jpeg

index.html 中添加该图片:

    <img src="" class="box">

当然,现在看不到效果:

在这里插入图片描述

修改 index.js 文件,添加代码如下:

import logo from './images/smile.jpeg'

$('.box').attr('src', logo)
$('.box').attr('width', 200)

保存文件,这时报错如下:

ℹ 「wdm」: Compiling...
✖ 「wdm」: asset bundle.js 669 KiB [emitted] (name: main)
asset ./index.html 778 bytes [emitted]
cached modules 590 KiB [cached] 41 modules
runtime modules 1.29 KiB 7 modules
cacheable modules 25.4 KiB
  ./src/index.js 261 bytes [built] [code generated]
  ./src/images/smile.jpeg 25.1 KiB [built] [code generated] [1 error]

ERROR in ./src/images/smile.jpeg 1:0
Module parse failed: Unexpected character '�' (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
(Source code omitted for this binary file)
 @ ./src/index.js 6:0-38 8:22-26

webpack 5.74.0 compiled with 1 error in 68 ms
ℹ 「wdm」: Failed to compile.

同样,还是提示需要合适的loader来处理 .jpeg 文件。

安装 url-loaderfile-loader

➜  temp0806 npm i url-loader file-loader -D      

added 6 packages, and audited 563 packages in 5s

50 packages are looking for funding
  run `npm fund` for details

6 vulnerabilities (1 moderate, 5 high)

To address all issues, run:
  npm audit fix

Run `npm audit` for details.

添加规则如下:

          { test: /\.jpg|jpeg|png|gif$/, use: ['url-loader?limit=10000']}

重新运行打包命令 npm run dev ,就可以看到图片了:

在这里插入图片描述
注意:limit设置为10000,其单位是byte,也就是10KB。它的含义是:如果图片大小不超过limit,就会转为base64方式,否则就用图片文件的方式。

本例中, smile.jpeg 文件大小为15KB,超出了limit设置,所以是图片的方式。

把limit改为20000,然后重新运行打包命令 npm run dev

在这里插入图片描述
可见,这次使用了base64的方式。

注:较小的图片,使用base64方式,可以减少网络开销。

babel-loader

webpack只能打包处理一部分高级的JavaScript语法。对于其它无法处理的高级语法,需要借助于 babel-loader 进行打包处理。

index.js 中添加代码如下:

function info(target) {
    target.info = 'Person info.'
}

@info
class Person { }

console.log(Person.info)

保存文件,这时报错如下:

ℹ 「wdm」: Compiling...
✖ 「wdm」: assets by status 328 KiB [cached] 1 asset
asset ./index.html 778 bytes [emitted]
cached modules 298 KiB (javascript) 432 bytes (runtime) [cached] 33 modules
./src/index.js 401 bytes [built] [1 error]

ERROR in ./src/index.js 20:0
Module parse failed: Unexpected character '@' (20:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| }
| 
> @info
| class Person { }
| 

webpack 5.74.0 compiled with 1 error in 38 ms
ℹ 「wdm」: Failed to compile.

同样,还是提示需要合适的loader来处理 .js 文件。

安装 babel-loader@babel/core@babel/plugin-proposal-decorators

➜  temp0806 npm i babel-loader @babel/core @babel/plugin-proposal-decorators -D 

added 47 packages, and audited 610 packages in 11s

54 packages are looking for funding
  run `npm fund` for details

6 vulnerabilities (1 moderate, 5 high)

To address all issues, run:
  npm audit fix

Run `npm audit` for details.

添加规则如下:

          { test: /\.js$/, use: 'babel-loader', exclude: /node_modules/ }

注: node_modules 无需webpack处理,所以将其排除在外。

在项目根目录下创建文件 babel.config.js

module.exports = {
    plugins: [['@babel/plugin-proposal-decorators', { legacy: true }]]
  }  

重新运行打包命令 npm run dev

  temp0806 npm run dev

> temp0806@1.0.0 dev
> webpack serve

ℹ 「wds」: Project is running at http://127.0.0.1:9090/
ℹ 「wds」: webpack output is served from /
ℹ 「wds」: Content not from webpack is served from /home/ding/temp/temp0806
ℹ 「wdm」: wait until bundle finished: /
ℹ 「wdm」: asset bundle.js 689 KiB [emitted] (name: main)
asset ./index.html 778 bytes [emitted]
runtime modules 1.29 KiB 7 modules
modules by path ./node_modules/ 588 KiB 39 modules
modules by path ./src/ 21.7 KiB
  modules by path ./src/css/*.css 1.59 KiB
    ./src/css/index.css 1.14 KiB [built] [code generated]
    ./node_modules/css-loader/dist/cjs.js!./src/css/index.css 462 bytes [built] [code generated]
  ./src/index.js 447 bytes [built] [code generated]
  ./src/images/smile.jpeg 19.7 KiB [built] [code generated]
webpack 5.74.0 compiled successfully in 1282 ms
ℹ 「wdm」: Compiled successfully.

页面效果如下:

在这里插入图片描述

打包发布

build

假设项目开发完成了,现在要做build。前面介绍中,使用了 webpack-dev-server ,所生成的东西都在内存里(注意并没有生成 dist 文件夹),而且没有经过压缩和优化。

package.json 文件的 scripts 中,添加 build 命令:

  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "webpack serve",
    "build": "webpack --mode production"
  },

注意:前面提到过 mode 选项,这里是通过命令行来覆盖 webpack.config.js 中的 mode 选项。

在发布之前,再稍微调整一下目录结构。

  • bundle.js 生成到 dist/js 目录下:
    output: {
        path: path.join(__dirname, 'dist'),
        filename: 'js/bundle.js'
    },
  • 配置 url-loader ,新增 outputPath 参数,指定图片文件的输出路径(否则会生成在 dist 目录下)。
    { test: /\.jpg|jpeg|png|gif$/, use: ['url-loader?limit=10000&outputPath=images']},

注:limit 要改回成10000,否则使用的是base64方式,就不会生成图片了。

运行 npm run build 命令:

➜  temp0806 npm run build

> temp0806@1.0.0 build
> webpack --mode production

asset js/bundle.js 92.8 KiB [emitted] [minimized] (name: main) 1 related asset
asset images/be0dcd475ffeb448fd2470bd1aa41ee4.jpeg 14.7 KiB [emitted] [immutable] [from: src/images/smile.jpeg] (auxiliary name: main)
asset ./index.html 424 bytes [emitted]
runtime modules 1.75 KiB 6 modules
orphan modules 1.22 KiB [orphan] 2 modules
cacheable modules 292 KiB
  modules by path ./node_modules/ 290 KiB
    modules by path ./node_modules/style-loader/dist/runtime/*.js 5.75 KiB
      ./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js 2.44 KiB [built] [code generated]
      ./node_modules/style-loader/dist/runtime/styleDomAPI.js 1.38 KiB [built] [code generated]
      + 4 modules
    modules by path ./node_modules/css-loader/dist/runtime/*.js 2.33 KiB
      ./node_modules/css-loader/dist/runtime/noSourceMaps.js 64 bytes [built] [code generated]
      ./node_modules/css-loader/dist/runtime/api.js 2.26 KiB [built] [code generated]
    ./node_modules/jquery/dist/jquery.js 282 KiB [built] [code generated]
  modules by path ./src/ 2.11 KiB
    ./src/index.js + 2 modules 1.66 KiB [built] [code generated]
    ./node_modules/css-loader/dist/cjs.js!./src/css/index.css 462 bytes [built] [code generated]
webpack 5.74.0 compiled successfully in 2668 ms

现在就生成了 dist 目录:

在这里插入图片描述

注意:修改了 bundle.js 和图片生成的目录,并不需要调整 index.html 相应的代码。即使在打包后也OK,因为 bundle.js 会自动注入到 index.html 里,而图片的src属性是在webpack里配置的, bundle.js 也是webpack生成的,所以它知道图片的位置。

clean-webpack-plugin插件

当webpack生成 dist 目录和其中的文件时,并不会删除其中原有的内容。如果想要在每次打包发布时,自动清理掉 dist 目录中的旧文件,可以使用 clean-webpack-plugin 插件。

安装 clean-webpack-plugin 插件:

➜  temp0806 npm i clean-webpack-plugin -D 

added 1 package, and audited 611 packages in 3s

54 packages are looking for funding
  run `npm fund` for details

6 vulnerabilities (1 moderate, 5 high)

To address all issues, run:
  npm audit fix

Run `npm audit` for details.

修改 webpack.config.js ,添加如下代码:

const { CleanWebpackPlugin } = require('clean-webpack-plugin')

修改如下代码:

module.exports = {
......
    plugins: [htmlPlugin, new CleanWebpackPlugin()],
......

现在,每次重新运行 npm run build 命令,都会先清理 dist 目录,再生成新的内容。

Source Map

修改 index.js 中第23行代码:

console.loga(Person.info)

这里故意把 log 写错。

开发环境

运行打包命令 npm run dev ,在浏览器的console中报错如下:

在这里插入图片描述
可见,虽然生成了 bundel.js ,仍然能定位到是 index.js 出错。但是报错的位置信息不正确,报错说是第25行,而实际是第23行出错。

解决办法,添加如下配置:

module.exports = {
......
    devtool: 'eval-source-map',
......

重新运行打包命令 npm run dev

在这里插入图片描述
现在,报错信息定位到了正确的文件和行号。

build环境

删掉刚才添加的配置。运行 npm run build 命令,打开 dist 目录下生成的 index.html 文件:

在这里插入图片描述这是因为生产环境下默认不包含source map,这也是出于安全性考虑。

如果配置了 devtool: 'eval-source-map' ,则与开发环境下该配置的效果相同:

在这里插入图片描述
点击右上角的 index.js ,可以看到其源码,这是不安全的。

另一种解决办法是,在生产环境下,只定位出错的行号,而不暴露源码,可用如下设置:

module.exports = {
......
    devtool: 'nosources-source-map',
......

重新运行打包命令 npm run build 命令,报错信息不变,但是点击右上角 index.js 时,不会暴露源码:

在这里插入图片描述

总结

  • 开发环境:设置为 eval-source-map
  • 生产环境:关闭(不设置),或者设置为 nosources-source-map

npm list总结

安装的模块清单如下:

➜  temp0806 npm list
temp0806@1.0.0 /home/ding/temp/temp0806
├── @babel/core@7.18.10
├── @babel/plugin-proposal-decorators@7.18.10
├── babel-loader@8.2.5
├── clean-webpack-plugin@4.0.0
├── css-loader@6.7.1
├── file-loader@6.2.0
├── html-webpack-plugin@5.5.0
├── jquery@3.6.0
├── style-loader@3.3.1
├── url-loader@4.1.1
├── webpack-cli@4.10.0
├── webpack-dev-server@3.11.2
└── webpack@5.74.0

注意版本信息,不同的版本可能配置和行为都各有不同,而且各模块之间可能会有兼容性问题。

安装包时,我们使用了 -D 或者 -S 选项:

  • -D :即 --save-dev ,表示开发阶段使用的包,其信息会出现在 package.jsondevDependencies 下;
  • -S :即 --save ,表示开发和生产环境都使用的包,其信息会出现在 package.jsondependencies 下;

本文中,只有 jquery 使用了 -S ,其它包都是开发包,使用了 -D

参考

  • https://www.bilibili.com/video/BV1zq4y1p7ga
  • https://www.webpackjs.com
  • https://www.npmjs.com
  • https://babeljs.io
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值