头图

后端视野学 Webpack ,文武双全?

蔡不菜丶
English

大家好,我是小菜。
一个希望能够成为 吹着牛X谈架构 的男人!如果你也想成为我想成为的人,不然点个关注做个伴,让小菜不再孤单!

本文主要介绍 Webpack 使用

如有需要,可以参考

如有帮助,不忘 点赞

微信公众号已开启,小菜良记,没关注的同学们记得关注哦!

前端认知

挺多人对前端开发是存在一定的误解的,感觉会点 H5 + C3 + JS 就等于会前端开发,但近几年前后端分离的模式逐渐流行起来,就说明前端早已没有之前那么简单。

站在我这个后端的视角上倒觉得, 前端是个文官,后端是个武将,不能说做到能文能武,但起码求武的同时不能不识一丁,退一两步来说,当前端实习妹子遇到 Bug 束手无措的时候,你这伪境前端若能出手相助~那在她人眼中你就是一位 '架着七彩祥云而来的盖世英雄~'

如果说你会 Bootstrap 加上 Layui,那么就说你会前端,难免会被人拍死在沙滩上~ 实际上的前端开发是由以下几个模块组成:

  • 模块化(js 的模块化,css 的模块化,资源的模块化)
  • 组件化(复用现有的 UI 结构,样式,行为)
  • 规范化(目录结构的划分、编码规范化、接口规范化、文档规范化、Git分支管理)
  • 自动化(自动化构建、自动部署、自动化测试)

image-20210827151331330

与后端如出一辙,该有的模块都有。

说到工程化,在后端开发中存在主流的解决方案有 Maven 工程Gradle 工程。前端工程化解决方案也有 webpackvite。那么就进入我们今天的正题,走进 Webpack

Webpack

一、概念认知

本质上,webpack 是一个用于现代 JavaScript 应用程序的静态模块打包工具。当 webpack 处理应用程序时,它会在内部从一个或多个入口点构建一个依赖图,然后将你的项目中所需的每一个模块组合成一个或多个 bundles,它们均为静态资源,用来展示你的内容。

以上内容摘于官网,官里官气的。下面我们简单概括一下
  • 概念总结webpack 是前端项目工程化的具体解决方案
  • 功能总结

    1. 提供了友好的前端模块化开发的支持
    2. 提供了代码压缩混淆、处理浏览器兼容Js、以及性能优化等强大功能
  • 优点总结:提高了前端开发效率和项目的可维护性

二、基本使用

实践出真知!我们直接使用来加强认识。

首先我们需要创建一个空白目录,然后在空白目录中执行 npm init -y 来初始化包管理配置文件 package.json

可以简单理解为这个 package.json 就相当于 maven 工程中的 pom.xml 文件

Maven 工程中我们通常上都是把源代码放在 src 目录底下,该 webpack 工程类似,因此我们下一步便是在该目录下创建 src 目录,继而创建两个文件 index.html (首页)index.js (脚本文件)

我们传统上要引入 Jquery 文件,一般有两种方式

  • 一种是下载 jquery.mini.js 文件,然后在项目中引入
<script src="../js/jquery.js"></script>
  • 一种是引用网上现成的 CDN 库,这样可以不用下载
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>

两种方式各有优劣,这里不做过多说明!

既然我们该项目是使用 npm 初始化的,那我们便可以使用 npm 来帮我们下载好所需要的包

npm install jquery -s

添加成功后我们可以在 package.json 文件中看到我们刚刚下载的包,这种方式有没有让你回想到 mavenmaven install 命令,这种奇怪的熟悉感~

等 jquery 包安装完成后,我们就可以在 node_modules 目录下查看到刚刚安装的包

然后在项目中进行引用

浏览器查看 JS 运行正常

以上方式也是传统的引包方式,跟 webpack 仍是没有半点关系。接下来我们就来看看 webpack 是如何使用的。

1、webpack 安装

在终端中运行如下命令,安装与 webpack 相关的两个包:

npm install webpack@5.42.1 webpack-cli@4.7.2 -D

扩展

  • npm install xxx -S,也就是 npm install module_name --save 写入dependencies
  • npm install xxx -D,也就是 npm install module_name --save-dev写入devDependencies

devDependencies ,是我们开发的时候需要用到的一些包,只需要用于开发阶段,真正打包上线的时候并不需要这些包,
dependencies,这个则是需要发布到生产环境中的。

2、webpack 配置

我们需要在项目的根目录中,创建一个名为 webpack.config.js 的 webpack 配置文件,并初始化如下的基本配置:

module.exports = {
    mode: "development"
}

其中的 mode 是个可变值,存在两个可选值

  • development

1、 适用于开发环境

2、不会对打包生成的文件进行代码压缩和性能优化

3、打包速度快,适合在开发阶段使用,能够快速响应页面的更改

  • production

1、适用于生产环境

2 、会对打包生成的文件进行代码压缩和性能优化

3、打包速度很慢,仅适合在项目发布阶段使用

1)配置文件的作用

webpack.config.js 是 webpack 的配置文件,webpack 在真正开始打包构建之前,会 先去读取这个配置文件,从而基于给定的配置,对项目进行打包

由于 webpack 是基于 node.js 开发出来的打包工具,因此在它的配置文件中是支持 node.js 相关的语法和模块进行 webpack 个性化配置的

然后我们这里先打个 载入点① ,先回到刚刚说到的 webpack 使用,等会再回来介绍 webpack!

在Java中有句熟悉的话:万物皆对象 ,因此在前端工程中我们同样有句话:万物皆模块

我们已经不需要传统的 js 导入方式:

<script src="../node_modules/jquery/dist/jquery.min.js"></script>

我们可以在有需要 jquery 的地方使用 import 的方式导入,jquery 是页面 index.html 需要的吗?并不是,而是 index.js 脚本文件需要,所以我们只需要在 index.js 文件中导入

然后我们还需要修改 package.json 文件:

我们新增了 dev 脚本 ,在 script 节点下的脚本,可以通过 npm run 执行。

然后我们在终端上运行 npm run dev 命令,启动 webpack 进行项目的打包构建

啪一下,很快啊!就在项目目录中生成了一个 dist 目录,并存在 main.js 脚本文件

我们继而在 index.html 文件中引入该 main.js 文件,先直接看结果,我们右键在浏览器打开

可以发现,js 运行正常,那么 main.js 是啥玩意?

webpack 4.x 和 5.x 的版本中有如下默认约定:

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

规定是die的,人是活的,因此我们可以在 webpack.config.js 中修改打包的默认约定!

既然了解了约定,因此我们就可以知道在 main.js 中包含了 index.js 内容,我们可以直接查看 main.js 文件,结果如我们所料

我们回到之前的 载点① 继续刚刚 webpack.config.js 配置文件的说明

我们在 webpack.config.js 文件中可以通过 entry 节点指定打包的入口,然后通过 output节点指定打包的出口。

这就是我们上面所说的打破默认规则!

上面我们也说完了 webpack 的基本使用,那我们下面就来看看 webpack 中的插件使用

三、插件使用

插件 顾名思义就是用来扩展 webpack 的功能,通过安装和配置第三方的插件,可以扩展 webpack 的能力,从而让 webpack 使用起来更加方便。最常用的 webpack 有两个:

  • webpack-dev-server

1、类似于 node.js 阶段用到的 nodemon 工具

2、每当修改了源代码,webpack 会自动进行项目的打包和构建

  • html-webpack-plugin

1、类似于一个模板引擎

2、可以通过此插件自定制 index.html 页面中的内容

我们先来看如何使用第一个插件

1)webpack-dev-server

webpack-dev-server 可以让 webpack 监听项目源代码的变化,从而进行自动打包构建

① 安装

使用以下命令即可在项目中安装该插件

npm install webpack-dev-server@3.11.2 -D
② 配置

1、需要修改 package.json 中的 script

"scripts": {
    "dev": "webpack server"
}

2、运行 npm run dev 命令

可以看到一句话:项目正在运行于 localhost:8080/ 。并且运行后并没有出现 dist 目录

然后我们通过该地址访问却没有看到我们想要的页面,而是需要点击 src 目录才能访问

根据以上结果,我们可能有如下疑问:

  • 为什么运行 npm run dev 会出现了一个访问地址呢?

这是因为 webpack-dev-server 会启动一个 实时打包的 http 服务器

  • 打包生成的文件在哪?

想要解答这个问题,我们就得需要知道两点 - 配置和不配置 webpack-dev-server 的区别

1、不配置 webpack-dev-server 的情况下,webpack 打包生成的文件,会存放到实际的物理磁盘上(根据 output 指定路径进行存放)

2、配置 webpack-dev-server 的情况下,打包生成的文件会存放到内存上,不再根据 output 节点指定的路径存放,这样的好处是提高了实时打包输出的性鞥你,因此内存比物理磁盘速度快很多

  • 生成到内存中的文件该如何访问?

生成到内存中的文件,默认是放到了项目的根目录中,但是是虚拟不可见的,我们可以直接用 / 表示项目根目录,后面跟上要访问的文件名称, 即可访问内存中的文件。

以三个问题收尾,我们来说下一个插件 html-webpack-plugin

2)html-webpack-plugin

我们上面通过访问 webpack server 给定的 URL 地址,发现不能直接访问到我们的 index 页面,这难免有些缺陷,有缺陷自然就会有改进,这就可以聊到 html-webpack-plugin 这个插件了~!

① 安装

老样子,我们需要通过以下命令进行安装

npm install html-webpack-plugin@5.3.2 -D
② 配置

③ 运行

我们通过运行 npm run dev ,然后看结果

通过该插件,我们可以看到已经可以直接通过路径访问该页面~

这里有小伙伴可能会提出问题,如果我不想通过 8080 端口可以吗,甚至不想通过 localhost 访问可以吗?答案是可以的,我们可以通过 devServer 节点webpack-dev-server 插件进行更多的配置:

devServer: {
    // 首次打包成功后,自动打开浏览器
    open: true,
    // 在 http 协议中,如果端口号是 80,则可以被省略
    port: 8081,
    // 指定运行的主机地址
    host: '127.0.0.1'
},

然后我们运行项目后通过 127.0.0.1:8081 访问页面:

到这里我们就已经介绍了两个插件的使用,接下来我们将看点不一样的东西~!

四、loader使用

我们在开头的时候已经说过一句话,在前端工程化中,万物皆模块。因此我们可以在 index.js 脚本文件中通过 import 的方式导入 jquery js文件。那遇到 css 文件是否一样能够通过 import 导入?我们不妨一试:

当我们想要通过 import 的方式导入该 css文件,控制台却给了我们一句话 :你可能需要一个适当的loader来处理这种文件类型适当的?loader?。那就进入正题,什么是 loader

在实际开发过程中,webpack 默认只能打包处理以 .js 后缀名结尾的模块。其他非 .js 后缀名结尾的模块,webpack 是处理不了,也就是会出现我们上面的那种情况,但怎么处理呢?就需要像提示文本所说的那样,我们需要下载一个适当的 loader 来处理这种文件类型。

loader 加载器有许多种,但它们的作用就只有一个,那就是 帮助 webpack 来打包处理特定的文件模块

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

接下来我们就来处理上面遇到 css 导包的问题

① 安装

通过以下命令来安装处理 css 文件的 laoder

npm i style-loader@3.0.0 css-loader@5.2.6 -D
② 配置

我们需要在 webpack .config.js 文件中配置相应的 loader 规则

module: {
  rules: [
    // 处理 .css 文件的 loader
    { test: /\.css$/, use: ['style-loader', 'css-loader'] },
  ]
}
③ 运行

继而我们运行文件,浏览器看效果

该结果已经说明了 css-loader 已经起到作用了。我们看下规则的编写方式是怎么样的:

{ test: /\.css$/, use: ['style-loader', 'css-loader'] }

其中 test 表示匹配的文件类型, use 表示对应要调用的 loader

  • use 数组中的 loader 顺序是固定的
  • 多个 loader 的调用顺序是 从后往前调用

其它loader的使用方式与上面一致,都是需要先安装,然后在 webpack.config.js 文件中配置

1)less-loader

安装

npm i less-loader@10.0.1 less@4.1.1 -D

配置

module: {
  rules: [
    // 处理 .css 文件的 loader
    { test: /\.css$/, use: ['style-loader', 'css-loader'] },
    // 处理 .less 文件的 loader
    { test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] },
  ]
}

2)babel-loader

安装

npm i babel-loader@8.2.2 @babel/core@7.14.6 @babel/plugin-proposal-decorators@7.14.5 -D

配置

module: {
  rules: [
    // 处理 .css 文件的 loader
    { test: /\.css$/, use: ['style-loader', 'css-loader'] },
    // 处理 .less 文件的 loader
    { test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] },
    // 处理JS高级语法的 loader
    { test: /\.js$/, use: 'babel-loader', exclude: /node_modules/ }
  ]
}

上面我们看到几种 loader 的作用,那么其中处理流程是怎么样的呢?我们用张图解释下:

五、打包发布

完成以上项目开发后,我们就要来到 打包发布 的阶段,前面所做的一切,到最后肯定都是需要发布的,那么为了能让项目在生产环境中高性能运行,就需要对项目打包发布。

① 配置

打包发布同样需要配置,我们需要在 package.json 文件下的 script 节点 进行配置:

其中 --model 是一个参数项,用来指定 webpack 的运行模式,我们在上面已经介绍过了~然后通过指令 npm run build,我们就可以在项目的根路径下看到我们熟悉的 dist 目录了

但是如果没有指定的规则配置,默认会将打包后的文件都放到 dist 目录下,但是如果我们想要将 js 文件 放到 js目录下image 文件放到 image 目录下 我们就需要在 webpack.config.js 进行相应的配置

前面我们 js 文件的生成目录已经通过 output 节点 进行配置了

那么我们还需要配置其他文件的输出目录,这里以图片类型的文件为例:

我们同样是在 webpack.config.js 文件中配置,不过此时是在 rules 节点 中进行配置:

进行到这步我们已经差不多完成了打包任务,但是我们如果更改了 js 生成目录,这个时候会发生什么呢?

image-20210828235635349

我们发现会生成冗余的文件,并没有把旧文件删除,这难道每次打包都要进行手动删除吗?当然不是!为了在每次打包发布时 自动清理掉 dist 目录中的旧文件,可以安装并配置 clean-webpack-plugin 插件

安装

npm install clean-webpack-plugin@3.0.0 -D

配置

运行

六、Source Map

这种 Source Map 就有点意思了,我们后端上线后,如果出现问题,我们通常会进入到服务器中查看报错日志。那么前端如果出现问题就很方便了,我们可以直接通过 F12 打开控制台查看报错日志,而且也可以对 js 文件进行 debug。但是我们上面说过通过 mode 指定 production 值后会对代码进行压缩,那么调试是一件即为困难的事情。

Source Map 就是用来解决这种问题的。

1)概念

Source Map 是一个信息文件,里面存储着位置信息,也就是 转换后 -> 转换前 的位置映射。在它的帮助下,出错的时候,可以直接显示原始代码,而不是转换后的压缩代码,可以在一定程度上提高排错效率。

2)使用

正常在开发环境下,webpack 是默认开启了 Source Map 功能,当程序运行出错的时候,可以直接在控制台提示错误位置的信息

image-20210829113705544

但是这种提示是不友好的,它记录的是压缩后代码的位置,这样导致的问题就是实际运行报错的行数源代码的行数 不匹配,这将成为我们排错路上的 绊脚石 ~!

既然如此,那我们就带着问题解决问题!

3)所遇问题
① 问题 1:实际运行报错的行数源代码的行数 不匹配

那么要解决这个问题也很简单,就需要在 webpack.config.js 中添加以下配置:

配置完查看结果,至此我们可以发现 运行报错的行数源代码的行数 是相匹配的!

② 问题 2:生产环境中容易暴露源码

以上我们虽然已经可以定位到源码的错误,但是如果在生产环境中,暴露源码终归不是一件好事,因此我们同样要解决该问题。

解决该问题的方式也很暴力,直接打包的时候在webpack.config.js文件中将mode 指定为 production,这样不会显示报错行数,也不会显示源码内容

mode: "production"

③ 问题 3:生产环境需显示行数隐藏源码

上面那种方式过于暴力,行数和源码一股脑都不给你显示了。那有没有比较这种的方式,可以显示行数但不显示源码?答案肯定是有的!我们只需将 devtool 的值配置为 nosources-source-map 即可

devtool: 'nosources-source-map'

配置完毕我们看效果:

该方式既可以显示报错行数也可以隐藏源码,是一种十分合适解决方案。

因此我们做个总结

4)总结
  • 开发环境

devtool 的值设置为 eval-source-map ,有利于精准定位到具体的错误行

  • 生产环境

关闭 Source Map 或将 devtool 的值设置为 nosource-source-map ,有利于防止源码泄漏,提高安全性

END

咱们这篇从 点去归纳了 webpack 的基本使用,后端的同学可以锦上添花,再不济看完后也可以和前端妹子有些共同话题~!前端的同学可以温故知新,可能这篇略显粗糙,但帮忙挑错,也不免是为自己巩固基础~!

不要空谈,不要贪懒,和小菜一起做个吹着牛X做架构的程序猿吧~点个关注做个伴,让小菜不再孤单。咱们下文见!

看完不赞,都是坏蛋

今天的你多努力一点,明天的你就能少说一句求人的话!

我是小菜,一个和你一起变强的男人。 💋

微信公众号已开启,小菜良记,没关注的同学们记得关注哦!

阅读 1.3k

小菜良记
搬砖爱好者 @公众号:小菜良记

搬砖爱好者

419 声望
1.7k 粉丝
0 条评论
你知道吗?

搬砖爱好者

419 声望
1.7k 粉丝
宣传栏