浅谈vite与webpack的区别及Vite为什么那么快

webpack

家喻户晓耳熟能详的前端编译工具在经历这么久的磨练后也开始显现出自己的颓势

  1. 繁重的编译过程
  2. 缓慢的加载及打包
  3. 因为依赖node.js每次编译都要进行繁琐的递归去构建依赖图谱,导致热更新效率低下

vite

新一代的前端开发和构建工具强大的拥有强大的编译及高效的处理能力

build

webpack打包过程
1.识别入口文件
2.通过逐层识别模块依赖。(Commonjs、amd或者es6的import,webpack都会对其进行分析。来获取代码的依赖)
3.webpack做的就是分析代码。转换代码,编译代码,输出代码
4.最终形成打包后的代码
webpack 打包原理

1.先逐级递归识别依赖,构建依赖图谱

2.将代码转化成AST抽象语法树

3.在AST阶段中去处理代码

4.把AST抽象语法树变成浏览器可以识别的代码, 然后输出

因为需要递归识别依赖,构建依赖图谱。图谱对象就是类似下面这种

{ 
'./app.js':    { dependencies: { './test1.js': './test1.js' },   
code:'"use strict";\n\nvar _test = _interopRequireDefault(require("./test1.js"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }\n\nconsole.log(test 1);' },  
'./test1.js':  { dependencies: { './test2.js': './test2.js' }, 
code:  '"use strict";\n\nvar _test = _interopRequireDefault(require("./test2.js"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }\n\nconsole.log(\'th is is test1.js \', _test["default"]);' },   './test2.js':    { dependencies: {},      code:       '"use strict";\n\nObject.defineProperty(exports, "__esModule", {\n  value: true\n});\nexports["default"] = void 0;\n\nfunction test2() {\n  console.log(\'this is test2 \');\n}\n\nvar _default = tes t2;\nexports["default"] = _default;' } }

Vite 原理
每声明一个script 标签类型为 module 时,

浏览器就会像服务器发起一个GET  http://localhost:3000/src/main.js请求main.js文件:   // /src/main.js: import { createApp } from 'vue' import App from './App.vue' createApp(App).mount('#app') 浏览器请求到了main.js文件,检测到内部含有import引入的包,又会对其内部的 import 引用发起 HTTP 请求获取模块的内容文件  如:GET http://localhost:3000/@modules/vue.js  如:GET http://localhost:3000/src/App.vue

Vite 的主要功能就是通过劫持浏览器的这些请求,并在后端进行相应的处理将项目中使用的文件通过简单的分解与整合,然后再返回给浏览器,Vite整个过程中没有对文件进行打包编译,所以其运行速度比原始的webpack开发编译速度快出许多!

Vite 解决的问题

1.Vite 通过在一开始将应用中的模块区分为 依赖 和 源码 两类,改进了开发服务器启动时间。依赖 大多为纯 JavaScript 并在开发时不会变动。一些较大的依赖(例如有上百个模块的组件库)处理的代价也很高。依赖也通常会以某些方式(例如 ESM 或者 CommonJS)被拆分到大量小模块中。Vite 将会使用 esbuild 预构建依赖。Esbuild 使用 Go 编写,并且比以 JavaScript 编写的打包器预构建依赖快 10-100 倍。源码 通常包含一些并非直接是 JavaScript 的文件,需要转换(例如 JSX,CSS 或者 Vue/Svelte 组件),时常会被编辑。同时,并不是所有的源码都需要同时被加载。(例如基于路由拆分的代码模块)。Vite 以 原生 ESM 方式服务源码。这实际上是让浏览器接管了打包程序的部分工作:Vite 只需要在浏览器请求源码时进行转换并按需提供源码。根据情景动态导入的代码,即只在当前屏幕上实际使用时才会被处理。
2.Vite 将会使用 esbuild 预构建依赖。Esbuild 使用 Go 编写,并且比以 Node.js 编写的打包器预构建依赖快 10-100 倍。
3.在 Vite 中,HMR 是在原生 ESM 上执行的。当编辑一个文件时,Vite 只需要精确地使已编辑的模块与其最近的 HMR 边界之间的链失效(大多数时候只需要模块本身),使 HMR 更新始终快速,无论应用的大小。Vite 同时利用 HTTP 头来加速整个页面的重新加载(再次让浏览器为我们做更多事情):源码模块的请求会根据 304 Not Modified 进行协商缓存,而依赖模块请求则会通过 Cache-Control: max-age=31536000,immutable 进行强缓存,因此一旦被缓存它们将不需要再次请求

Vite 面临的问题

1.生态不如webpack,wepback牛逼之处在于loader和plugin非常丰富,但任何事情不是绝对的路还很远
2.prod环境的构建,目前用的Rollup,原因在于esbuild对于css和代码分割不是很友好
3.还没有被大规模使用,很多问题或者诉求没有真正暴露出来,Vue3普及下Vite应该很快会被大家首先考虑使用

你可能感兴趣的:(js,Vue,webpack,前端,javascript)