Web开发基础
核心概念
-
HTML、CSS和JavaScript:Web开发的三大基石,分别负责结构、样式和行为。
-
代码管理:随着项目规模扩大,需要将代码拆分成小块,便于维护。
-
作用域污染:早期所有代码共享全局作用域,容易导致变量和函数名冲突。
细化解释
在Web开发的初期,开发者通常将HTML、CSS和JavaScript写在一个文件(如index.html)中。这种方式简单,但当代码量增加时,文件变得臃肿,维护困难。为了解决这个问题,开发者开始将JavaScript拆分成多个文件,通过<script>标签引入。然而,所有代码仍共享全局作用域,如果多个文件中定义了同名变量或函数,就会相互覆盖,导致"作用域污染"。
模块化与打包工具
核心概念
-
模块化:将代码拆分为独立模块,每个模块有自己的作用域,避免全局污染。
-
打包工具:如Webpack,将多个模块整合成一个或多个文件,便于部署。
-
Webpack:主流打包工具,支持前端和后端代码的统一处理。
细化解释
模块化开发通过将功能封装到独立的模块中,避免了全局作用域的冲突。每个模块可以导出功能(如函数或变量),其他模块通过导入使用这些功能。Webpack作为打包工具,能够分析模块间的依赖关系,将所有模块打包成一个bundle.js文件,浏览器可以直接加载运行。
后端引入方式与AMD/CMD协议
核心概念
-
require:Node.js中同步加载模块的方式。
-
AMD(异步模块定义):浏览器端异步加载模块的标准。
-
CMD(通用模块定义):在AMD基础上改进,提供更灵活的加载方式。
细化解释
在Node.js中,require同步加载模块,适合服务器端,但在浏览器端由于网络延迟,同步加载效率低下。AMD通过define定义模块,支持异步加载依赖,适用于前端。CMD在AMD基础上优化,允许按需加载依赖,并通过缓存减少重复请求。
Webpack的统一打包功能
核心概念
-
统一打包:支持不同模块标准(如CommonJS、ES Modules)的代码整合。
-
入口文件:从指定入口开始,构建依赖图并打包。
细化解释
Webpack能够处理使用require(CommonJS)或import(ES Modules)的代码,将其统一打包为一个文件。开发者无需担心模块标准的差异,只需指定入口文件,Webpack会自动解析依赖并生成bundle.js。
单页面应用和多页面应用
核心概念
-
网页加载:浏览器通过URL向服务器请求资源。
-
缓存机制:存储静态资源,减少重复请求。
-
单页面应用(SPA):一个HTML文件,通过JavaScript动态渲染。
-
多页面应用(MPA):多个独立HTML文件,适合SEO。
细化解释
传统MPA中,每个页面对应一个HTML文件,导航时重新请求。SPA只有一个HTML,通过JavaScript动态更新内容,提升用户体验。缓存机制通过存储JS、CSS等静态文件,加速后续加载。
单页面应用框架
React、Angular、Vue
-
React、Angular、Vue:主流SPA框架,提供组件化开发。
-
与Webpack结合:优化代码打包和资源管理。
细化解释
这些框架通过组件化方式组织代码,与Webpack结合实现模块化开发和高效打包。React以声明式UI著称,Vue易上手,Angular功能全面。
组件化的概念
-
单页面应用采用的方式都是构建一个大组件,然后再把这个大组件挂载到一个名叫 div#app 下面去
- 这里几乎是所有初中级前端迈不过去的概念了,他们不知道可以多创建一个 div,然后通过改写 main.js 将多个 Vue 组件挂载到多个 div 下,因为一般情况下完全不需要这样做,但是在谷歌插件开发,需要增强一个网页功能时,恰巧需要这个概念,若没有这个概念,就很难搞了,如下图红框里面这些小图标

- 将单页面的打包理解为一个大 Vue 组件的 js 代码用 Webpack 打包的过程,才能更好的理解谷歌插件开发,否则很难对谷歌插件知识进行分层,最终将插件知识和 Webpack + Vue 打包知识混合在一起,那就让你脑袋大了。
谷歌插件开发基础
popup.html,option.html,background.js,content script,inject script
-
谷歌插件:实现多页面间数据通信。
-
结构:
-
background:后台脚本,处理持久数据。
-
popup:弹出界面。
-
content script:注入网页,监听消息。
-
inject script:处理业务逻辑。
-
细化解释
谷歌插件通过多个组件协作实现功能。background脚本常驻后台,popup提供用户交互,content script访问网页DOM,inject script执行具体逻辑。多端通信涉及1:n关系(如插件到多个tab)。
background.js 特殊存在,为何谷歌称它 serviceworker.js
-
background.js 最早期 MV2 版本时,它就是一个独立 page 和其他页面没啥区别,也即意味着原来谷歌浏览器需要给 background.html 提供 V8 运行环境,提供一些毫无用处的 DOM 全局变量的概念,但是 background.js 是个不可见的纯提供服务的概念,追加 window 和 DOM 以及其他 html5 API 都没有任何实质意义,还增加了性能开销,这东西需要常驻以便为其他页面提供服务;
-
那为何不把 background.html 做成一个简单的 worker.js 呢?用的时候加载进来,不用的时候卸载掉?不就不存在性能损耗了吗?不就可以让谷歌浏览器同时支持上百个插件在运行了吗?既然如此那必须干!于是 background.html 变成了 background.js,成为其他页面通信中转和数据增删改查的服务;
谷歌插件的知识分层
-
知道谷歌插件由 popup.html,option.html,background.js,content script,inject script 5 个部分构成,其中 popup.html,option.html 是单页面,content script 和 inject script 是组件化打包之后挂载到网页的某个 div 上实现具体功能的存在,而 background.js 是负责通信中转和数据增删改查的概念,但以上概念,均可以通过 webpack 进行打包,且 target:"web",因为这 5 个概念都没有偏离 web 下运行的范畴;
-
你要掌握的谷歌插件知识只有
-
5 个部分如何通信?
-
content script 和 inject script 不共用一个作用域
-
inject script 是与网页共享一个 window 作用域
-
content script 在复杂开发中,只充当通信中转器,因为网页环境无法直接跟某个插件直接通信,因为网页和插件是 1:n 的概念,window.postmessage 到底发给哪个插件,浏览器不得而知,你必须有个 content script 接收这个消息才能保证网页和插件的对应。
-
所有的数据持久化,必须通过 background.js,因为其他那 4 个都不能保证稳定性和对应性,例如 inject script 只能存到 localstorage 里面,是针对某个网页的,与插件的存储范围不一样。
-
了解 chrome.storage 所有增删改查的使用方法;
-
-
至于 vuex,vue-router,vue 脚手架的使用压根跟谷歌插件开发没有关系,但若你一开始就从一个谷歌插件脚手架开始,迷惑也很正常;
Electron桌面应用开发
主进程 Main 和渲染进程 renderer
-
主进程:管理操作系统功能,类似于 background.js
-
渲染进程:类似于 popup.html option.html
-
webview 渲染进程:类似于网页+inject script
-
渲染进程的 preload.js:类似于网页+content script
-
-
归根结底,你只需要了解两个概念,主进程和渲染进程,其他都是进一步的细化
细化解释
Electron结合Node.js(主进程)和Chromium(渲染进程),支持跨平台开发。主进程处理文件操作等,渲染进程负责界面展示,二者通过IPC通信。
主进程 Main
-
node.js 环境下的运行脚本,electron.exe main.js 进行启动
-
相当于 electron.js 程序运行到一定步骤后,使用 eval 函数,将 main.js 加载后执行
渲染进程 Renderer
-
main.js 启动 V8 环境构建出来的网页环境,这个环境可以直接执行里面的 html 和 js,那说明 web 打包那一套又可以直接拿来用了,比如 vue 脚手架打包一个单页面,直接丢进来就能用了
-
特殊的渲染进程 webview,会对具体的网页进行渲染,通过将 Vue 打包成组件挂载到网页的具体 div 上面,实现网页功能的增强
进程间通信
核心概念
-
进程间通信(IPC):主进程与渲染进程间的消息传递。
-
服务间通信:主进程与外部服务的交互。
-
通信方式:监听、发送消息、第三方中转。
细化解释
在Electron中,IPC通过ipcMain和ipcRenderer实现进程间通信。服务间通信可能涉及HTTP或WebSocket,复杂场景可借助消息队列。
服务间通信
-
如果将所有的逻辑都放在 main.js 中,比如数据库的增删改查操作,就会让主进程变得特别冗杂,冗杂就会导致出错率增大,针对渲染进程和 webview 进程闪退,都会自动重启,而主进程因为异常而闪退,则没有任何机会重启,因此降低主进程的代码复杂量,非常必要。
-
但是将逻辑抽离出来,单独形成 http 本地服务实现数据库增删改查,但随之而来的问题,是主进程和 http 本地服务就无法通信了,此时可以将主进程和 http 本地服务都理解为独立的服务,两个服务之间可通过订阅一个独立的服务消息,实现消息的实时通信,例如 Redis 或者 zeroMQ
总结
看似非常复杂的大前端开发,最终无非就是在解决两个问题:
-
解决不同层级下的通信问题
-
同页面下的通信,例如 vue 的父子通信,或者 vuex
-
不同页面下的通信,例如谷歌插件不同页面的 chrome.runtime.sendMessage
-
不同进程下的通信,例如 electron 的 ipcRenderer.invoke
-
不同服务下的通信,例如 electron 的 main.js 和本地 http.exe
-
-
解决数据的存储问题
-
同页面下的数据存储,例如 vuex 和 localStorage
-
不同页面下的数据存储,例如 chrome.storage
-
不同进程下的数据存储,例如 config.json 和 sqlite
-
其他东西都是这两大问题的具体细化过程,以及 web 方面的开发知识,如果你觉得很难,那基本是 web 本身的基础就不牢靠,学得似是而非。