网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
从命令行就能看到,保存过后就会重新编译,这样热更新就完成了:
最终效果:
添加 source map
添加 source map 是为了能够方便 debug,现在打开 chrome 中的 source,显示的代码是不可读的:
如果是开发公共组件,在有些时候,直接提供打包好的 bundle 对其他的使用这个开源库的用户来说,就会有阅读困难的问题。所以,这里会加上添加 source map 的功能。
配置是内置的,只需要添加一行新的配置即可:
module.exports = {
// 其他不变
devtool: 'eval-cheap-module-source-map',
};
长试运行一下 npm run build
之后,就会看到打包出了一个新的文件:
在使用 Live Server 启用了一个服务器后,再去打开打包后的 index.html,会有下面这样的提示跳出来:
这就说明系统已经能够找到对应的源码,报错就可以直接定位到源码报错的地方。
选择 cheap-module-source-map 的原因很简单,它会将 webpack 打包好的模块按照 module 还原成源码,并且能够准确定位到报错的行。在正常的情况下,为了保证代码的可读性,每行代码在 80-120 个字符范围内的情况下,定位到行就已经够了。
另外,对于 React/Vue 来说,原生的 JavaScript 和二者的语法糖差异较大,很难从编译过后的 JavaScript 直接在脑中转换成对应框架的代码,所以这也是需要使用源码的原因。同理,在生产环境就应该使用 nosources/none 的选项,这样别人就比较难从编译过后的 JavaScript 了解到源码。
下面是来自 webpack-Devtool 官网上列举的差别:
devtool | performance | production | quality | comment |
---|---|---|---|---|
(none) | build: fastestrebuild: fastest | yes | bundle | Recommended choice for production builds with maximum performance. |
eval | build: fastrebuild: fastest | no | generated | Recommended choice for development builds with maximum performance. |
eval-cheap-source-map | build: okrebuild: fast | no | transformed | Tradeoff choice for development builds. |
eval-cheap-module-source-map | build: slowrebuild: fast | no | original lines | Tradeoff choice for development builds. |
eval-source-map | build: slowestrebuild: ok | no | original | Recommended choice for development builds with high quality SourceMaps. |
cheap-source-map | build: okrebuild: slow | no | transformed | |
cheap-module-source-map | build: slowrebuild: slow | no | original lines | |
source-map | build: slowestrebuild: slowest | yes | original | Recommended choice for production builds with high quality SourceMaps. |
inline-cheap-source-map | build: okrebuild: slow | no | transformed | |
inline-cheap-module-source-map | build: slowrebuild: slow | no | original lines | |
inline-source-map | build: slowestrebuild: slowest | no | original | Possible choice when publishing a single file |
eval-nosources-cheap-source-map | build: okrebuild: fast | no | transformed | source code not included |
eval-nosources-cheap-module-source-map | build: slowrebuild: fast | no | original lines | source code not included |
eval-nosources-source-map | build: slowestrebuild: ok | no | original | source code not included |
inline-nosources-cheap-source-map | build: okrebuild: slow | no | transformed | source code not included |
inline-nosources-cheap-module-source-map | build: slowrebuild: slow | no | original lines | source code not included |
inline-nosources-source-map | build: slowestrebuild: slowest | no | original | source code not included |
nosources-cheap-source-map | build: okrebuild: slow | no | transformed | source code not included |
nosources-cheap-module-source-map | build: slowrebuild: slow | no | original lines | source code not included |
nosources-source-map | build: slowestrebuild: slowest | yes | original | source code not included |
hidden-nosources-cheap-source-map | build: okrebuild: slow | no | transformed | no reference, source code not included |
hidden-nosources-cheap-module-source-map | build: slowrebuild: slow | no | original lines | no reference, source code not included |
hidden-nosources-source-map | build: slowestrebuild: slowest | yes | original | no reference, source code not included |
hidden-cheap-source-map | build: okrebuild: slow | no | transformed | no reference |
hidden-cheap-module-source-map | build: slowrebuild: slow | no | original lines | no reference |
hidden-source-map | build: slowestrebuild: slowest | yes | original | no reference. Possible choice when using SourceMap only for error reporting purposes. |
基本上来说,webpack 都已经显示了推荐用于不同情况下的不同环境,推荐使用哪种类型的 devtool 了,这里简单描述下:
- 带有 eval
将模块代码放到 eval 函数中去执行,从而产生独立的作用域,再通过 source-url 去标注文件的路径
只有 eval 的情况下,只能定位报错的文件
- 带有 source-map
这会将代码转译成转换过的代码,可定位到具体的行和列
- 带有 cheap-source-map
这会将代码转译成转换过的代码,代码会定位到行,但是不会定位到列
- 带有 module-source-map
会将代码翻译成原生代码,并不会进行转译。即,未经过 loader 转译过后的代码
- 带有 inline-source-map
将源码嵌入到 module 代码中去,webpack 推荐,这种情况可能在发布独立一个文件时发生
- hidden
开发模式下看不见源码,但是源码会被一起打包
比较适合用于开源项目
- nosources
会显示行列信息,但是不会列出源码
比较适合用于生产环境
所以说,正常来说我会选择使用 eval-cheap-module-source-map 作为开发环境,而 nosources/none 作为部署环境的代码。
下面是报错结果,我刻意在 Vue.js 中导入了一个不存在的文件:
import HelloWorld from './components/HelloWorld.vue';
// Error组件不存早,下面在源代码中是第10行
import Error from './components/Error.vue';
浏览器中的报错结果如下:
注意最后的 App.vue:formatted:11 这段,已经很好的提示错误所在了。
其实这里是强行刷新后产生的报错结果,出现报错的情况下 webpack 会自动停止热刷新,一直到错误修复为止。相似的错误信息也会出现在开启服务器的终端上。
HRM 的开启
这里使用的是 webpack5,一定要确认版本,v4 和 v5 之间配置的差别似乎不太一样,二者的配置不一定能通用。
HRM,即 Hot Module Replacement,即模块热替换,也就是只编译更新过的模块的功能。
之前的配置,即:
module.exports = {
// 这一行说明运行环境是类似浏览器的环境
target: 'web',
devServer: {
// 开启热更新
hot: true,
},
};
其实已经开启了 HMR 和 Live Reloading:
所以这一步相当于在之前的配置中已经完成了。
验证 HMR 效果
已知目录结构是这样的:
并且依赖关系是:main 引用 App.vue, App.vue 引用 HelloWorld.vue,所以可以分别修改 main.js, App.vue, 和 HelloWorld.vue 去验证重新打包的大小,借此验证 HMR 是否更新成功。
- 更新 HelloWorld.vue
assets by path *.js 2.54 MiB
asset bundle.js 2.53 MiB [emitted] (name: main)
asset main.598fea34c0d6bb419535.hot-update.js 17 KiB [emitted] [immutable] [hmr] (name: main)
asset index.html 602 bytes [emitted]
asset main.598fea34c0d6bb419535.hot-update.json 28 bytes [emitted] [immutable] [hmr]
Entrypoint main 2.54 MiB = bundle.js 2.53 MiB main.598fea34c0d6bb419535.hot-update.js 17 KiB
cached modules 863 KiB [cached] 264 modules
runtime modules 26.8 KiB 14 modules
javascript modules 9.46 KiB
这里可以看到两组对比:
+ **main.598fea34c0d6bb419535.hot-update.js** 17 KiB
热更新的部分的大小是 17KiB
+ **cached modules** 863 KiB [cached] 264 modules
缓存的大小是 863Kib接下来还原 Helloworld.vue,保存后,再更新 App.Vue
- 更新 App.Vue
assets by path *.js 2.54 MiB
asset bundle.js 2.53 MiB [emitted] (name: main)
asset main.815ce3af01699b267e86.hot-update.js 10.1 KiB [emitted] [immutable] [hmr] (name: main)
asset index.html 602 bytes [emitted]
asset main.815ce3af01699b267e86.hot-update.json 28 bytes [emitted] [immutable] [hmr]
Entrypoint main 2.54 MiB = bundle.js 2.53 MiB main.815ce3af01699b267e86.hot-update.js 10.1 KiB
cached modules 870 KiB [cached] 264 modules
+ **main.815ce3af01699b267e86.hot-update.js** 10.1 KiB
热更新的部分的大小是 10.1KiB
可以看到热更新的代码少了
+ **cached modules** 870 KiB [cached] 264 modules
缓存的大小是 870Kib
可以看到缓存的模块多了
继续还原后再给 main.js 加个空格
- 更新 main.js
assets by path *.js 2.53 MiB
asset bundle.js 2.53 MiB [emitted] (name: main)
asset main.fafa37f13c47741d83cd.hot-update.js 2.37 KiB [emitted] [immutable] [hmr] (name: main)
asset index.html 602 bytes [emitted]
asset main.fafa37f13c47741d83cd.hot-update.json 28 bytes [emitted] [immutable] [hmr]
Entrypoint main 2.53 MiB = bundle.js 2.53 MiB main.fafa37f13c47741d83cd.hot-update.js 2.37 KiB
cached modules 873 KiB [cached] 267 modules
+ **main.fafa37f13c47741d83cd.hot-update.js** 2.37 KiB
能看出热更新的部分又少了
+ **cached modules** 873 KiB
而缓存的模块又多了
这已经可以证明模块热替换的功能已经实现了。
ESLint 设置
在 webpack 中,ESLint 的也是通过 loader 进行实现。理论上来说,在 JavaScript 文件被处理之前,应该通过 ESLint 的 loader 对 JavaScript 源码加上该有的信息。
注*:来自 webpack 官网:
The loader
eslint-loader
will be deprecated soon, please use this plugin instead.
所以这里会使用对应的插件完成功能。
注 2*:使用 webpack 插件去运行时,ESLint 部分的运行失败,好像并不会影响项目的运行。
- 安装插件
这里也是根据报错信息来的,如果不是 vue 项目,不需要下载 eslint-plugin-vue
一路上报错……还挺多的
# 要用 ESLint 的 webpack 插件肯定要先安装 ESLint
npm install eslint --save-dev
Usage
# 安装对应的 webpack 插件
npm install eslint-webpack-plugin --save-dev
# 安装对应的 vue 版本
npm install eslint-plugin-vue --save-dev
# 又一个报错信息,提示需要 babel-eslint
npm install babel-eslint --save-dev
这些都安装完了之后,报错终于停止了,可以开始配置工作了。
2. 配置文件
这一步还蛮烦的,一点一点来。
1. 初始化 eslint
执行命令 `npx eslint --init`
```
D:\vue-webpack>npx eslint --init
? How would you like to use ESLint? ...
To check syntax only
> To check syntax and find problems
To check syntax, find problems, and enforce code style
```
第一步会有三个选项,第一个只会找语法错误,第二个会找语法错误和问题代码,如未使用的变量、不存在的变量等,第三个就是加上代码风格的检查,包括行太长,缩进之类的问题。
这里选择第三个,也检查代码风格
现在是第二个问题:
```
? What type of modules does your project use? ...
> JavaScript modules (import/export)
CommonJS (require/exports)
None of these
```
这里使用的时候 vue,不在二者之间,所以选择 None
然后是第三个问题:
```
? Which framework does your project use? ...
> React
Vue.js
None of these
```
这里用的是 Vue,就选 Vue 了
第四个问题:
```
? Does your project use TypeScript? » No / Yes
```
这里没有用 TypeScript,选择 No
第五个问题:
```
? Where does your code run? ... (Press <space> to select, <a> to toggle all, <i> to invert selection)
√ Browser
√ Node
```
这里虽然看不清楚,但是 Browser 和 Node 的 √ 的颜色其实不太一样。
是个网页项目,选择 Browser 即可。
第六个问题:
```
? How would you like to define a style for your project? ...
> Use a popular style guide
Answer questions about your style
Inspect your JavaScript file(s)
```
第一个选项就是用主流风格,第二个就是它会提示问题,然后自动生成,最后选项就是根据 JavaScript 文件自动生成。
我想躺不想努力了,用市面上现成的风格。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
```
第一个选项就是用主流风格,第二个就是它会提示问题,然后自动生成,最后选项就是根据 JavaScript 文件自动生成。
我想躺不想努力了,用市面上现成的风格。
[外链图片转存中…(img-eQeiJZsD-1715845658147)]
[外链图片转存中…(img-9tI80Knu-1715845658147)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新