《打包系列|序章》

前端史

前端的发展迅速,新技术层出不穷,不跟上步伐,你将成为前浪,被时代所淘汰。
依稀记得最开始写MVC框架的快感,简称web1时代。

那时候问得最多的不过是什么是mvc, 路由控制器监听到路径发生变化处理数据
更新到数据库,返回携带html文本的报文。页面的交互用ajax,无需刷新页面就可以更新数据,ui用bootstrap响应式布局,还要用jquery写一堆的dom操作,事件处理。聊聊弊端吧:

  1. ajax请求没有记住事务状态的能力,不向单页面,你弹出一个弹框或者滚动到某处以后,从别的路由回到当前路由,这些状态都会重置。因为路由
    发生变化,服务端下发新的响应浏览器解析并渲染,状态全部重置
  2. jquery是用起来爽,但是一堆的js dom操作,事件操作时很头疼的
  3. 数据交互频繁,一个模块的数据变动,导致很多模板要更新,都得进行很多的人为视图处理操作

到后来的单页面机制的出现,前端出现了mvvm架构,简称web2时代.
这个时候前后端开始了分离,程序员的分工更加明显,一个专注于数据的处理,一个专注于用户的交互。这让人的工作量减少很多,而且可以专注于一方面的发展。不管是vue的观察订阅者模式加上Object.defineProperty的代理劫持。还是react的fiber diff render。视图变化的处理工作大大减少,基本上很多dom操作,文本操作都由react.js或者vue.js处理了。jquery也慢慢退出了舞台。另外都有各自的路由处理vue-router,react-router-dom.同样是更新数据不刷新页面但是有了记录页面状态的能力。但是如果单纯的vue.js或者react.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
<head>
<link rel="stylesheet" ref="./index.css"/>
<link rel="stylesheet" ref="./header.css"/>
<link rel="stylesheet" ref="./content.css"/>
<link rel="stylesheet" ref="./slider.css"/>
<link rel="stylesheet" ref="./footer.css"/>
<link rel="stylesheet" ref="./common.css"/>
<script src="./react.js"></script>
<script src="./reactDOM.js"></script>
</head>
<body>
<div id="app">
</div>
</body>

<script>
import Header from 'Header.js'
import Content from 'Content.js'
import Slider from 'Slider.js'
import Footer from 'Footer.js'

Class App extends React.Component {
return (
<>
<Header />
<Conetent>
<Slider/>
<article/>
</Content>
<Footer />
</>
)
}

ReactDOM.render(<App/>, document.querySelector('#app'))
</script>

显然如果这个页面内容很多的话,比如会有如下缺点:

  • css 命名,你得确保这么多内容里面不出现重复的名字,造成样式混乱
  • 我只能用es6语法写,先不说浏览器支不支持,我想用CommJs或者Amd语法都是不行的(个人认为就应该语法统一,统一规范写EMS)
  • js中有句话说的好一切都是对象,那么可不可以说html, css一切都是js呢,我们都知道
    ast抽象语法树,万语皆可以翻译
  • 自己可能写了很多无用代码,但是编译的时候都被执行
  • 我想使用scss, less怎么办
  • 我的项目上线以后,我希望把css,js压缩,减小包的体积
  • 等等

于是呢就有了打包工具,市面上常用的有webpack, rollup, gulp 等。虽说打包工具好
但是也不得不说说缺点,如果一个应用体积很大,首次打包编译和构建操作时间特别长,然后你修改代码热更新也慢的慌。于是就用了vite的出现,虽说生态不够完善,但是少不了期待的眼神。vite与打包工具的区别:
vite

vite1

vite是一个基于浏览器原生 ES imports 的开发服务器。利用浏览器去解析 imports,在服务器端按需编译返回,完全跳过了打包这个概念,服务器随起随用。同时不仅有 Vue 文件支持,还搞定了热更新,而且热更新的速度不会随着模块增多而变慢。针对生产环境则可以把同一份代码用 Rollup 打包。

Vite 在开发环境下并没有打包和构建过程

开发者在代码中写到的 ESM 导入语法会直接发送给服务器,而服务器也直接将 ESM 模块内容运行处理后,下发给浏览器。接着,现代浏览器通过解析 script module,对每一个 import 到的模块进行 HTTP 请求,服务器继续对这些 HTTP 请求进行处理并响应。

其实本就应该这样,在开发环境中,代码只需要进行语法翻译不需要打包(根据入口和模块之间的依赖关系,组装成一个个包含多个模块的 Chunk,再把每个 Chunk 转换成一个单独的文件)。相应的模块变动的时候,就应该是重新请求响应模块的import请求即可。

Vite Server 所有逻辑基本都依赖中间件实现。这些中间件,拦截请求之后,完成了如下内容:

处理 ESM 语法,比如将业务代码中的 import 第三方依赖路径转为浏览器可识别的依赖路径(绝对路径就在npm包里面找,相对路径就在项目中找)

对 .ts、.vue 等文件进行即时编译;

对 Sass/Less 的需要预编译的模块进行编译;

和浏览器端建立 socket 连接,实现 HMR。

不过发展依旧没有停止,随着NodeJs的发展,前端工具链,工程化得以发展,前端
不再仅仅是csr(客户端渲染),这种页面完全靠js渲染是不利于seo的,而且初始化数据的时候如果数据多首次渲染会很慢,于是有了ssr技术的出现,通过NodeJs实现一个网关,模块代码同构,在将react渲染成html片段前进行数据的初始化和css的处理以及数据的注水操作。使得搜索引擎访问页面的请求结果不再是一个空的div,而是有内容的html文本。另外数据的初始化已经在网关层实现,所以页面在浏览器首次
渲染的时候不需要再重新加载数据然后初始化最后才执行render了。虽说ssr好,但是也加大了前端的学习成本。
目前就有了NSR(边缘渲染)的策略:利用了 CDN 能力。ESR会在 CDN 上缓存页面的静态部分,这样在用户访问页面时,可以快速返回给用户静态内容,同时在 CDN 节点上也发起动态部分内容请求,在动态内容获取之后,利用流的方式,继续返回给用户

文章作者: woyao
文章链接: https://chenwoyao.github.io/2021/05/22/前端笔记/打包系列/打包系列序章/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 woyao的博客