WdBly Blog

懂事、有趣、保持理智

WdBly Blog

懂事、有趣、保持理智

周维 | Jim

603927378@qq.com

前端构建流程

从用户输入url 到 服务端 推送消息 分析前端页面的展示过程,包括dev环境,prod环境,ssr

使用webpack+react+router+redux+koa+laravel等技术进行分析

本地开发环境

1:新建一个react单页项目

2:配置好package.json中的script命令,可以同过设置变量来区分不同的项目环境

"scripts": { "test": "echo \"Error: no test specified\" && exit 1", "dev": "cross-env NODE_ENV=development node server", "build": "cross-env NODE_ENV=production webpack --env=prod && webpack --env=server", "clean": "rimraf ./dist/client/app/* && rimraf ./dist/server/* && rimraf ./views/prod/*", "start": "cross-env NODE_ENV=production node server", "deploy": "pm2 reload mobile_react", "run": "cross-env NODE_ENV=production PORT=3000 pm2 start server --name mobile_react", "server-build": "cross-env NODE_ENV=production webpack --env=server" },

3:运行npm run dev(或者其他) 命令,开启一个node服务,这个过程主要干了几件事情

 1:导入依赖:执行server.js(服务端的入口)(fs,koa,webpack,router等)
 2:模块挂载:有顺序的将模块挂载到koa实例上,如:
 const app = new Koa();
 app.use(module);
 module可以是导入的模块,也可是自定义的函数,如:
 app.use(async(ctx,next)=> await next()) 别忘了将路由挂载到实例上
 挂载的模块并不会立即执行,会在用户访问时触发依次执行。
 3:页面编译:页面编译可以通过webpack进行的,通过导入的webpack配置文件,
 在启动服务时完成前端页面的编译工作,将生成的依赖文件放置在内存中(dev环境),提高编译速度。
 可以通过webpack启动一个热更新的插件,方便dev环境的调试,具体实现时通过服务端的sse来实现的。
 4:开放并监听一个端口,用于接收用户的访问。
 app.listen(config.port, () => {
     log.info("success");
 });
 5:服务器已经准备好了,包括监听端口,和单页应用的入口index.html文件,等待浏览器的连接。

4:打开localhost:config.port/app/home (或者127.0.0.1,本机IP),连接服务器,服务器做出响应,返回项目入口文件index.html给浏览器。

关于访问localhost 127.0.0.1 本机IP的区别。
127.0.0.1:本地环回地址,是主机用于向自身发送通信的一个特殊地址,浏 
览器发送了一个请求,经过应用层(http请求),传输层(Tcp握手),
然后到达网路层后不会离开主机到达外部网络接口。也就是不会经过主机的网 
卡(有线或无线)调用网卡驱动继续封装数据。
loaclhost:这是一个域名,通过hosts文件进行配置,在我们的开发工作中会经常用到,特别是当我们需要同时开启多个项目服务时。默认是指向127.0.0.1
这里有个注意的地方,localohost和127.0.0.1是存在跨域问题的
本机IP:数据包到达网卡后(IP层)会通过网卡驱动封装传输到外部网络接口,最后通过转发回到主机。可供本机和外部访问。

5:浏览器获取到html文件,开始从头开始解析,包括文档头部的文档类型等,并且下载资源,下载过程同上,浏览器可同步发送多个请求下载资源。

6:如果有路由懒加载,index.html 通常来说会下载库文件,vendor.js,初始化文件 app.js等。

image.png

7:执行初始化文件,文件中包含了基础路由,解析当前路由,在匹配项中找到对应文件,下载文件,下载过程同第四步,下载完成后执行。

image.png

8:这个时候就通过前端的各种技术生成页面渲染到浏览器了,比如babel转义,模板渲染,虚拟dom,双向绑定等等,这个时候我们就能看到生成的页面了。

9:热更新,在服务端,我们的文件被放置在内存中,webpack会监听源文件的修改,并重新生成打包模块替换内存中的老的模块,服务端通过初始时与客户端建立的SSE(Server-Sent Events)链接发送更新消息给客户端,webpack启动的SSE连接名默认名是 __webpack_hmr,服务端发送更新消息是定时+触发式的。

image.png

通过事件流的方式服务端可以定时向客户端发送更新消息,当文件更新时,客户端接收到更新的message后会向服务端请求更新的文件,这里哪个文件更新了用hash字符串来实现。

image.png

包括更新的json文件(更新后的 manifest,包括新的编译 hash 和所有的待更新 chunk 目录)和最终更新的js文件。这时同上执行 4,8步。