高频知识点
工程化-笔记
工程化笔记
2026-7-17
原始笔记链接:https://cloud.seatable.cn/dtable/external-links/59b453a8639945478de2/
0020 npm 模块安装机制是什么?npm install 原理
这个就是依赖树的问题
1 读取 package.json 文件,解析出 dependencies 和 devDependencies 中全部的依赖文件,这是一个列表
2 循环数组,下载对应的依赖包,然后遍历依赖的依赖,如果没有下载,那么下载并放在数组中
3 直到数组中的依赖被全部下载完成
如果有两个库依赖的第三方库版本不一致,可能造成冲突,例如一个依赖 react16 另一个依赖 React18 这样就会报错。解决办法是 force 或者改成一样的依赖版本
0026 模块化的发展历程 AMD CMD UMD
不同时期不同框架,推荐的模块化语法不同,主要有:
-
AMD 异步模块定义,规范在这里:https://github.com/amdjs/amdjs-api/wiki/AMD
-
CMD 通用模块定义,规范在这里:https://github.com/seajs/seajs/issues/242 是 RequireJS 在推广过程中对模块定义的规范化产出,CMD 是 SeaJS 在推广过程中对模块定义的规范化产出。
-
UMD是两种模块化语法的兼容
-
nodejs中自带的模块化是 common-js require,是 BravoJS 在推广过程中对模块定义的规范化产出
-
ES6当中新的语法主要是 esModules——import
这些模块化的规范不影响应用的开发,就是单纯的规范。webpack 打包的结果文件,选择满足什么规范,满足哪一种运行环境。
0070 Webpack热更新的原理是什么
webpack-dev-server 开启一个内置的开发服务器
web-socket 实现双向通信
hmr 实现热更新
当代码变化后,webpack 重新编译打包,然后通知 socket 更新到界面上。HMR 实现热更新(局部更新)
HMR (Hot Module Replacement)的工作流程大致可以分为以下几个步骤:
-
建立WebSocket连接:应用程序在初始化时与Webpack Dev Server建立WebSocket连接,以便实时接收更新通知。
-
监听文件变化:当开发过程中的文件发生变化时,Webpack Dev Server会监听到这些变化,并通过WebSocket通知应用程序。
-
获取模块更新清单:接到通知后,HMR Runtime会发起HTTP请求,获取模块更新清单(manifest)。这个清单包含了所有需要更新的模块信息。
-
下载并应用更新:一旦获取到更新清单,HMR Runtime会下载每一个更新模块,并在所有新模块下载完成后,准备就绪并进入应用阶段。在这一阶段,所有失效的模块会被释放并从模块系统中卸载掉,最后更新模块的hash并调用所有相关的accept事件处理函数。
-
处理模块更新:Webpack运行时触发变更模块的module.hot.accept回调,执行代码变更逻辑。这允许开发者在运行时替换、添加或删除模块,而无需进行全页刷新。
0107 Mvc、MVP、mvvm 有什么区别
这些都是软件设计架构
MVC 架构
model view controller
View 是视图层,可以把数据显示在界面,用户直接和视图层交互;Controller 是控制器,主要处理界面的业务逻辑(打开关闭组件等)。Model 是数据层,主要存储底层数据(文件内容,表格信息)。
MVC通信是单向流:View 中用户交互会触发 Controller 控制器,Controller 处理用户输入改变 Model 数据层,数据层改变后会重新渲染 View 视图层。
用户可以与视图层交互,也可以通过URL等直接操作Controller(这是backbone的交互逻辑)
mvc: model-view-controller 数据层,视图层,控制层。当用户交互时间发生,view 监听事件,将事件传递到 model,model 处理后更新 view 层。同时 View 也可以直接更改 Model 层,类似下面的架构。
总体的设计模式(组件设计)低耦合高内聚,不同功能组件避免耦合。数据层和展现层的分离(例如使用 redux 的设计方案,view 层触发 action,更改对应的 store,重新计算后更新界面,这样就做到数据和视图的分离)。
MVC架构的好处:model 是数据层,View 是视图层,Controller 是控制层。
在实际项目中,model 是界面中实际的数据,例如上传的图片和行的信息。view 是界面中显示的按钮和控件,以及控制这些控件的 react 状态。Controller 是接口和API。如果一个引用做到 MVC 完全分离,然后不同模块完全分离,如果需要改动某个模块,或者界面样式,或者数据层,都不会影响其他的部分。
例如,我们想把界面中的按钮改成输入框,那么直接更改 View 层即可,不需要改动 Model 层。如果项目的耦合性很强,可能数据划分不是很清楚。
MVP 架构
Presenter 展现层,处理大部分的业务逻辑。View 视图层不会部署业务逻辑(根据Presenter被动渲染)。
View 和 Presenter 是双向通信,Presenter 和 Modal 是双向通信。View 和 Modal 不会直接通信。
MVVM 架构
将 MVP 架构中的 Presenter 改成 ViewModal。
特点:View 和 ModalView 双向绑定,View 更改后直接体现在 ModalView 中。
MVVM 就是 model view view-model 三个,架构比上面好一点。这个数据层和 view-model 层进行通信数据交流,ViewModel 和 View 实现自动数据绑定,这个减少了组件代码的耦合。

这个最早在安卓端使用较多,还需要看实际的代码,可能一个很好的设计模式,对后续的扩展比较友好。如果一个模块设计的不合适,后续扩展,耦合性很大,就会有很多问题。
原始链接:http://www.ruanyifeng.com/blog/2015/02/mvcmvp_mvvm.html
0109 Webpack有常用的哪些 plugin 和 loader
loader 主要用于处理不同格式的文件转换
- css-loader (style-loader, css-loader, less-loader, scss-loader) 处理不同的样式,并编译成 css 然后进行打包;file-loader(把小文件打包成JS中);loader 执行的顺序是从右向左,例如匹配到 .less 文件就是这样执行的 postcss-loader
- resolve-url-loader 解析url()的相对路径
- thread-loader 多线程执行,这个用于多核CPU加速打包活过程
- url-loader: 和file-loader一样,但返回base64 data当文件大小小于某个值时
- babel-loader 把 ES6 代码编译成 ES5 代码等
plugin 处理特殊的功能和需求
- uglyfyJS 丑化代码,压缩代码
- html-webpack-plugin 生成页面
- happypack 也是加快编译效率
- transform-runtime 按需加载 antd-mobile 也是看版本,5以上配置就变化了
- mini-css-extract-plugin
注意:不同版本下 webpack 的配置不一样(从最早的3到5)
详情参考:https://www.npmjs.com/package/webpack
0913 webpack 懒编译是什么?
问题:有个早期的很大的项目,webpack 入口文件有40个,然后依赖的第三方库很多,每次运行 npm run dev 可能耗时超过2分钟。
原因:默认 webpack 在启动 devServer 时,一次性把所有入口、所有导入模块全部编译打包,项目越大启动越慢。
解决:开启懒编译,不提前编译全部代码,等到浏览器真正请求对应资源时,webpack 才现场编译该模块。相当于按需编译,极大减少初始打包工作量,大大加快开发速度。
配置:修改 webpack 配置(config/webpack.config.js ),增加下面的实验性参数,在开发环境中启用懒编译
|
|
优点:
-
大型项目前端启动速度成倍加快,几十个入口项目效果差距极大;
-
修改某一个组件热更新更快,只重编译当前改动模块,不需要编译其他模块;
-
内存占用更低,不用一次性加载全量模块依赖。
缺点:
-
这是实验性配置,不是正式配置,可能少数情况存在不稳定
-
对于小项目,优化前后不明显
-
加载页面时,会先白屏,然后 webpack 开始编译,再次刷新页面才能显示出来
0762 按需加载如何实现
按需加载,通常用在 ui 库中,例如 ant-design 库
2.x 版本
需要用户手动配置
https://2x.ant.design/docs/react/getting-started-cn#%E6%8C%89%E9%9C%80%E5%8A%A0%E8%BD%BD
方法1 直接引入需要的某个组件(加上路径)
|
|
方法2 使用 babel-plugin-import 来进行按需加载
|
|
代码中可以写成
|
|
babel 中增加插件
|
|
5.x 版本
不需要用户手动配置按需加载
antd 默认支持基于 ES modules 的 tree shaking,直接引入 import { Button } from 'antd'; 就会有按需加载的效果。
https://ant-design.antgroup.com/docs/react/getting-started-cn#%E6%8C%89%E9%9C%80%E5%8A%A0%E8%BD%BD
0763 babel-plugin-import
用于 antd-mobile 2 版本的按序加载
就是 esModule 进行的按序加载
0769 Monorepo 架构
Monorepo:单一仓库架构:利用单一仓库来管理多个 packages 的一种策略或手段
与其相对的是多仓库(Multirepo)架构
适应于大型多个相同依赖的项目,含有相同的依赖等,类似 lerna 项目管理
-
便于代码复用:多个仓库都会用到的组件、工具函数、类型声明、样式等,可以放到 common 子包中,需要的仓库直接 npm install 这个子包就行,就跟 npm install 一个 npm 包一样容易。 -
独立构建和部署:每个子包都是一个独立的项目,有自己的 package.json 文件,独立安装依赖、独立端口和本地启动、独立测试、独立构建和部署,互不影响。 -
降低切换成本:由于只有单一仓库,clone 代码、切换分支、安装依赖比较方便,不用在不同文件夹之间切换。 -
节约磁盘空间:pnpm 天然具备 monorepo 能力,支持全局依赖管理,所有子包之间共享依赖,节约磁盘空间。 -
方便提交PR:由于是单仓库,增加新组件或给组件增加新特性,只需要提交一个 MR、编写一次 MR 描述、关联一次需求/缺陷单。 -
方便代码检视:一个完整的特性只需要统一在一个 MR 中检视,不用在多个仓库/多个 MR 之间切换。 -
灵活便于扩展:后续增加新的工程只需要在 packages 下增加一个子包,不需要申请新的代码仓库,也降低后续仓库维护成本,比如:配置保护分支 / GitHub Actions / 仓库标签等。
https://article.juejin.cn/post/7404777192704868362
https://juejin.cn/post/7415776780076105779
例如个人的 react-demos 就是相同依赖的多个项目,可以使用这个架构提取公共的库,减少代码量。
例如个人的 novel 项目,就是不同依赖和功能的多个项目,分开维护比较方便。
如果是个人维护多个项目,那么用这个比较好。如果是多人维护多个项目,分开比较好,否则可能比较乱。
0770 module federation 架构
webpack5 内置的模块管理工具
https://juejin.cn/post/7048125682861703181?searchId=20241210183908A776F5DCCD3FF70873FF
Module Federation是一种通过Webpack插件实现的,应用间模块共享和动态加载的技术。
它允许多个独立构建的应用程序组成一个整体应用,这些构建之间没有相互依赖,因此可以独立开发和部署。这种技术通常被称为微前端。
Host 和 Remote 类型 在 Module Federation 中,容器分为两种类型:Host 和 Remote。Host 消费 Remote 提供的模块,并且可以提供模块给 Remote。
0771 微前端架构
微前端架构是一种将前端应用程序拆分为多个独立模块的方法,每个模块可以独立开发、部署和运行。
它借鉴了微服务的理念,旨在解决大型前端应用的复杂性。
主要特点
-
独立性:每个微前端模块可以独立开发和部署,使用不同的技术栈。
-
团队自治:不同团队可以负责不同的模块,增加了团队的灵活性和自主性。
-
技术多样性:各个模块可以使用不同的框架和库,如 React、Vue、Angular 等。
-
渐进式迁移:可以在现有应用中逐步引入微前端架构,而无需一次性重构整个应用。
架构组成
-
容器(Container):负责加载和渲染各个微前端模块的主应用。
-
微前端模块(Micro Frontends):独立的功能模块,可以是不同的前端应用。
优势
-
可扩展性:便于添加新功能和模块。
-
可维护性:代码分散,便于管理和维护。
-
快速迭代:各个模块可以独立更新,降低了整体发布的风险。
技术实现
-
Module Federation:Webpack 5 的特性,用于实现模块共享和动态加载。
-
微前端框架:如 Single-SPA、Qiankun 等,帮助管理微前端应用的生命周期和路由。
总结:微前端架构,通过将大型前端应用,拆分为小而独立的模块,提升了开发效率和灵活性,使得现代前端开发更具可维护性和可扩展性。
0692 前端如何 debug
chrome://inspect/
https://zhuanlan.zhihu.com/p/24353060
https://zhuanlan.zhihu.com/p/401550174
谷歌浏览器自带的调试工具,功能繁多,注意版本不同,实际上每一个功能都可以写成一个单独的知识点
用的时候可以专门学
0125 git 命名规范
commit 命名:每次commit,要标准和准确的描述做了什么,改了什么,删除了什么,新增了什么
分支命名:
version/1.2.3(大版本分支)
feature/login(新增特性分支简写feat)
person/michael/bugfix-editor(个人分支)
special/firefox-debug(特殊分支)前面是大类-后面是功能说明 hotfix(紧急修复分支)
tag 只能适用稳定的版本
0126 git 提交 PR 流程
s1:配置 用户名/邮箱/软件界面:
|
|
右键-options-looks 设置git外观和显示
s2:记录开发过程
初始化仓库——工作区——暂存区——持久区
S3 远程服务器交互
远程代码库(码云,github)
设置:注册
重要:SSH公钥-不同电脑设置不同的key
生成公钥:在bash中生成ssh公钥(具体命令网站上有)生成一个方框图案。将bash中产生的代码复制到码云中。
github 秘钥和公钥产生在我的文档下面.ssh文件夹中。
S4 忽略文件
.gitignore 文件不生效原因:git 中已经包含的文件存在缓存,需要删除这部分本地缓存文件。bash 清空缓存后,可以正常忽略文件。
|
|
0127 软件开发的几种方法
软件工程中开发的几种方式
| 名称 | 定义 | 优点 | 缺点 |
|---|---|---|---|
| BDD 行为驱动开发 | 确定功能后,直接编辑完成行为的代码 | 面向行为,项目整体的框架明确,MVC 层划分明确,适合大型项目,适合没有案例的项目(自上而下) | 可能代码有问题,没有对应的测试文件,后期需要补充测试,考虑边界情况等 |
| TDD 测试驱动开发 | 确定功能,编写测试用例,完成只能实现测试的代码,完善程序 | 代码健壮性强,针对性强(例如leetcode刷题,或者lodash工具库函数),适合模块化开发代码(自下而上) | 代码完成后,项目整体框架规范可能不一致,没有从顶层处理数据结构。编写测试耗时长。 |
| 瀑布流开发 | 类似BDD,有明确的开发流程:用户调研-产品需求-设计草图-编写代码-测试-上线-反馈与后续维护 | 适合大团队的明确分工,确定所有功能是否需要再动手,避免过程中由于产品需求变动,造成的代码返工等。 | 自上而下的开发,可能后续到测试阶段才发现不足,需要前期大量的会议论证等,需要前期明确的文档和需求 |
| 敏捷开发 | 直接面对用户,用户提出什么需求,就直接开发(二八定律,先不管代码的细节和极少数用户的情况) | 小步快跑,产品开发较快;适应于自驱力较强的开发者,程序员可以根据用户需求或者自己的体验直接开发功能 | 对于自驱力不强的程序员,没有明确的需求,就很难规范化开发。如果团队成员较多,开发效率并没有那么高。 |
实际上,一个公司可能使用多种开发方法;不同的开发团队(国外开放的理念,国内严格的等级),不同的项目需求,不同的时间限制等等,会采用不同的开发方法。
某一个项目,或者某个开发阶段,也可能有不同的开发方法。
总之:BDD和TDD可以对比,瀑布流开发和敏捷开发可以对比。人多或者情况复杂,需要规范明确,严格定义需要做什么。人员较少,时间紧张,那就优先开发出可视化的结果。
https://www.zhihu.com/question/19645396
敏捷开发:
https://baike.baidu.com/item/%E6%95%8F%E6%8D%B7%E8%BD%AF%E4%BB%B6%E5%BC%80%E5%8F%91/7108658
0128 软件设计的冗余和性能分析
数据结构的冗余:设计某个字段时,考虑可能扩容,例如单选改成多选,那么就需要从字符串改成数组字符串。如果早期设计中,就设计数组,就不需要考虑兼容早期的代码了。最终还是看需求:如果需求确定,不经常更改,那么就可以考虑性能为主。如果需求经常变化,那么需要考虑冗余。
服务器和硬件层面的冗余:如果主服务器或者主磁盘在某个情况下跑满或者故障,那么需要另一套服务器(或者另一个程序)目前开发的应用还不需要考虑多个系统处理冗余(因为 dev 挂了就修复,内存满了就重启线上服务器,不需要考虑完全不挂的情况)实际上大厂还是需要考虑的,不能线上环境突然挂了然后重启。
0183 如何提⾼webpack的打包速度
(1)优化 Loader
对于 Loader 来说,影响打包效率首当其冲必属 Babel 了。因为 Babel 会将代码转为字符串生成 AST,然后对 AST 继续进行转变最后再生成新的代码,项目越大,转换代码越多,效率就越低。当然了,这是可以优化的。
首先我们优化 Loader 的文件搜索范围
|
|
对于 Babel 来说,希望只作用在 JS 代码上的,然后 node_modules 中使用的代码都是编译过的,所以完全没有必要再去处理一遍。
当然这样做还不够,还可以将 Babel 编译过的文件缓存起来,下次只需要编译更改过的代码文件即可,这样可以大幅度加快打包时间
|
|
(2)HappyPack
受限于 Node 是单线程运行的,所以 Webpack 在打包的过程中也是单线程的,特别是在执行 Loader 的时候,长时间编译的任务很多,这样就会导致等待的情况。
HappyPack 可以将 Loader 的同步执行转换为并行的,这样就能充分利用系统资源来加快打包效率了
|
|
(3)DllPlugin
DllPlugin 可以将特定的类库提前打包然后引入。这种方式可以极大的减少打包类库的次数,只有当类库更新版本才有需要重新打包,并且也实现了将公共代码抽离成单独文件的优化方案。DllPlugin的使用方法如下:
|
|
然后需要执行这个配置文件生成依赖文件,接下来需要使用 DllReferencePlugin 将依赖文件引入项目中
|
|
(4)代码压缩
在 Webpack3 中,一般使用 UglifyJS 来压缩代码,但是这个是单线程运行的,为了加快效率,可以使用 webpack-parallel-uglify-plugin 来并行运行 UglifyJS,从而提高效率。
在 Webpack4 中,不需要以上这些操作了,只需要将 mode 设置为 production 就可以默认开启以上功能。代码压缩也是我们必做的性能优化方案,当然我们不止可以压缩 JS 代码,还可以压缩 HTML、CSS 代码,并且在压缩 JS 代码的过程中,我们还可以通过配置实现比如删除 console.log 这类代码的功能。
(5)其他
可以通过一些小的优化点来加快打包速度
-
resolve.extensions:用来表明文件后缀列表,默认查找顺序是['.js', '.json'],如果你的导入文件没有添加后缀就会按照这个顺序查找文件。我们应该尽可能减少后缀列表长度,然后将出现频率高的后缀排在前面 -
resolve.alias:可以通过别名的方式来映射一个路径,能让 Webpack 更快找到路径 -
module.noParse:如果你确定一个文件下没有其他依赖,就可以使用该属性让 Webpack 不扫描该文件,这种方式对于大型的类库很有帮助
https://juejin.cn/post/7197061916904898616#heading-3
0204 webpack 中 dev 和 production
在开发模式下,直接通过 import 可以导入 CSS 文件。
在生产环境下,会把相互的依赖关系分别打包,然后后端模板中需要插入对应的打包后的JS和CSS文件。这个本地开发测试不出来。
dev正常,build 后不正常的情况,可能是不同开发环境打包逻辑不一样。如果一个模块被引用多次(具体次数根据配置文件决定),那么可能被打包到common.js中,然后影响全局的样式
本地环境下面,只显示项目的CSS,可能在生产环境下,项目中的CSS可能和第三方库的CSS冲突(类名冲突)
0186 图片和多媒体存储优化
1、设计角度:合适的图片格式,jpg png 雪碧图,字体图标、css 取代图片
2、后端角度:压缩图片、图片缩略图(后端),点击后展开大图
3、前端 webpack 压缩 image-webpack-loader,图片懒加载,图片响应式加载(大屏大图片,小屏幕小图片)
4、网络角度:CDN
图像切片:超大图片几个G,可以切成几个小图片,然后分别进行加载,这个需要后端技术处理,用于 TIFF 等格式,遥感扫描图等
0221 polyfill 是什么
polyfill 英文翻译:垫片;计算机中指的是"补丁"
为什么使用:老版本浏览器需要较早的语法才能使用(IE11不能使用Object.assign)所以需要通过 babel 把高级语法转换成低级语法。我们可以设置需要支持的浏览器版本(例如使用babel 转换到 es3 还是 ES5 版本)。早期的版本需要更多代码,如果不想兼容 ie 678 那么可以节省不少代码。
垫片(补丁)分类
|
|
补丁使用方法:手动、半自动、全自动。
1、手动:根据需求,安装对应的第三方库 Object.assign = require('object-assign') 不利于维护。
2、半自动:根据 webpack 覆盖率:preset-env 根据预设的环境打补丁 https://github.com/browserslist/browserslist 在配置文件中设置 corejs 和 targets 版本,即可打包对应版本的代码。
3、自动:polyfill.io 这个库可以根据浏览器的 UA 自动判断不同版本的代码并处理 https://polyfill.io/v3/ chrome 会不处理,IE 会转换。
参考链接:https://zhuanlan.zhihu.com/p/71640183
0222 thread-loader 多进程多线程打包
webpack 编译打包时间较多,可以使用 thread-loader,可以减少 webpack 打包编译时间
https://github.com/webpack-contrib/thread-loader
先定量分析一下打包时间,在耗时较多的 loader 前,使用 thread-loader 处理,使用单独的进程进行打包
多CPU的情况下,可以节省时间(8核节省75%的时间)
如果只使用 babel 转换,不使用 webpack 打包,那么影响不大
|
|
0345 前端加密算法有哪些?
为什么进行前端加密
在 http 协议下,数据是明文传输,传输过程中网络嗅探,可直接获取其中的数据,如用户的密码和信用卡相关的资料,一旦被中间人获取,会给用户带来极大的安全隐患。另一方面在非加密的传输过程中,攻击者可更改数据或插入恶意的代码等。
前端加密的意义: 即在数据发送前将数据进行哈希或使用公钥加密。如果数据被中间人获取,拿到的则不再是明文。
当然还有其他一些优点,例如避免后端等打印日志直接暴露明文密码,还可以避免明文撞库等。
加密方法
- 常见对称加密有AES、DES、3DES等,常用AES实现。
- 常见非对称加密有RSA、ECC等,常用RSA实现(公钥私钥,例如 github 登录)。
案例
crypto-js 实现前端对称加密,后端收到消息后解密。
md5
sha256
数据库加密
数据库存储用户名的密码时,加盐操作
参考链接
https://zhuanlan.zhihu.com/p/480875682
https://blog.csdn.net/w418856/article/details/130964706
0351 rollup 是什么?
为什么 rollup 打包赘余代码比较少?
rollup 是个打包的库
解答:官方介绍:https://rollupjs.org/
1、支持打包成不同格式:cmd, umd, cjs 等,按照需要打包
2、支持摇树,可以把不在依赖树的节点去掉,避免打包多余代码
3、支持文件拆分,根据不同节点进行动态拆分
4、其他插件(支持复杂功能)
0375 你知道哪些项目架构
有多种用于构建 React 项目的架构解决方案和模式。一些受欢迎的包括:
- MVC(模型-视图-控制器) :MVC 是一种传统的架构模式,它将应用程序分为三个主要组件 - 模型、视图和控制器。React 可以在 View 层中使用来渲染 UI,而其他库或框架可以用于 Model 和 Controller 层。
- Flux:Flux是Facebook专门针对React应用程序推出的应用程序架构。它遵循单向数据流,其中数据沿单个方向流动,从而更容易理解和调试应用程序的状态更改。
- 原子设计:原子设计并不是 React 特有的,而是一种将 UI 划分为更小、可重用组件的设计方法。它鼓励构建小型、独立且可以组合以创建更复杂的 UI 的组件。
- 容器和组件模式:该模式将表示(组件)与逻辑和状态管理(容器)分开。组件负责渲染 UI,而容器则处理业务逻辑和状态管理。
- 功能切片设计:它是一种用于组织和构建 React 应用程序的现代架构方法。它旨在通过根据功能或模块划分应用程序代码库来解决可扩展性、可维护性和可重用性的挑战。
0376 什么是特征切片设计
它是一种用于组织和构建 React 应用程序的现代架构方法。它根据功能或模块,划分应用程序代码库,来解决可扩展性、可维护性和可重用性的挑战。
在功能切片设计中,应用程序的每个功能或模块,都组织到一个单独的目录中,其中包含所有必要的组件、操作、reducers 和其他相关文件。
这有助于保持代码库的模块化和隔离性,使其更易于开发、测试和维护。
功能切片设计促进了关注点的清晰分离,并将功能封装在各个功能中。
这允许不同的团队或开发人员独立地处理不同的功能,而不必担心冲突或依赖性。

0356 项目负责人的写法
一份优秀的简历,学历和经验达标的情况下。
最首要是项目经历,这也是后续面试官和你聊的主要内容。
其次是影响力,比如个人博客,比如开源社区贡献,比如自己的文章。
然后是个人技能,列名词沾边就行。
简历A
角色:项目负责人
带领xxx人。
在xxx系统完成xxx模块,xxx模块,等10个模块。
实现xxx,xxx,xxx等上百个页面。
实现图形编辑器,音频波形图,xxx表格,等50个组件。
覆盖pc、安卓、小程序三端。
运用vue,vue-router,ts等等技术。
按ddd和solid分层、模块化插件化。
有脚手架、开发模板、代码lint、自动化测试、cicd、灰度、监控告警等工程化。
也有devops,低代码,版本控制等基建。
还有一些复杂状态管理,数据转化管理等等。
输出xx文章,框架。
提高xx产出
github xxx项目 300star
个人博客 xxx
简历B
角色:项目负责人
带队:xxx人
系统规模:
1,10个模块50个组件100个页面
2,覆盖pc、安卓、小程序三端。
系统亮点:
1,架构整洁:满足solid原则,分层模块化+容器化+插件化架构。
2,工程化完备:脚手架、开发模板、代码lint、自动化测试、cicd、灰度、监控告警等
3,基建完备:devops,低代码系统,版本控制平台,监控平台等等
4,复杂功能:图形编辑器,音频波形图,分层状态机,多模式匹配渲染,数据桥接器,复杂联动表格表单组件等。
成果:
1,团队战斗力提高:输出n篇课程文章,为公司提供xxx框架,提升xxx效率,减少xxxbug。
2,系统品质提升:故障降低xxx,性能提升xxx,用户满意度提升xxx。
3,团队产出提升:用户量同比提升xxx,节约xxx成本。
4,优化产研sop:提高xxx效率。
简历C(不好)
角色:项目开发
xxx系统
根据设计规范实现UI。
跟后端协商接口。
使用vue-router实现路由。
使用vuex管理状态。
实现一个复杂表单。
0260 团队中不同项目,如何避免干扰
团队中的问题以及解决方法
一个子项目中,不同子项目互相干扰,冲突的解决办法
- 代码规范统一:制定统一的规范(接口规范,UI规范,commit 规范等)
- UI 的统一:不同的子项目使用不同的前缀(CSS,公共组件)
- 编程能力统一:不同的同事水平不一样,那么按照中等的水平作为整体的标准(react hook typescript 等技术,根据团队技术水平决定)项目设置成不同的模块,不同人完成不同的模块,只要求接口统一
- 增加自动监测模块(单元测试,集成测试)整体项目的水平的保证
0261 如何重构代码和组件
为什么要重构?
原因:一个组件功能低耦合高内聚。历史原因,如果一个组件功能繁杂,逻辑比较乱,代码量很大,不便于管理,那么应该进行重构。
重构步骤:
1、理解功能:把当前组件的代码读懂,并理清不同的功能和界面匹配
2、划分重构边界:根据功能确定划分的部分(功能分类,还是界面分类),然后把不同的核心代码分开
3、迁移核心代码到不同子组件,优先调试小组件,并测试核心代码和传参正确性(import部分直接全部复制)
4、迁移类型检验,删除无用代码
5、重新整理类名,函数名等;微调内部结构。
6、最后判断预期效果是否达成。如果没有达到预期效果,或者重构后仍然有问题,需要重新开始前面步骤。
具体思考
1、项目开始前,就应该约定各种组件的规范,后期更改很麻烦,还可能有未知的错误和问题
2、自己写公共组件一定注意细节,这里需要多看官方组件的源代码,看看别人怎么写的。
为什么要写自己的组件?能不能使用传参优化已有的组件,避免造轮子是最好的,也要有造轮子的能力
0266 鲁棒性是什么
Robust 鲁棒性 健壮性,表示代码或者服务在不良环境下的稳定性
如果某个上下游服务延迟,或者高并发,是否有配套方案解决这个问题?
例如支付宝接口的响应时间延迟,表现在线上就是淘宝支付的商品未付款。
如果判断网络情况不好,需要自动降级或者友好提示。
或者用户输入的不符合规范,或者网络情况较差等,代码能否满足基本功能。
0299 eslint-webpack-plugin 自动修复
作用:可以在编译时自动处理代码的 eslint 警告
环境:需要在 webpack 5 以上 + eslint 7 以上
|
|
然后在 webpack plugins 数组中增加这个插件和配置
|
|
其他参考文档:https://webpack.docschina.org/plugins/eslint-webpack-plugin/
0300 npm 配置代理服务
|
|
0315 webpack 基本概念?常用插件和 loader?
entry: 入口文件,支持单入口(字符串)和多入口(对象)
output:输入文件(filename, path)
loaders: 不同格式的文件(正则匹配),优先使用 loader 进行转码,例如 sass less 转换成 css,SVG 转换成 file。这里执行的顺序是从后向前的,例如
|
|
plugins: 插件,统一处理压缩打包过程(是否丑化,是否多线程执行,是否分析模块大小),常用插件如下
|
|
bundle:包,打包后的包
module:模块,原始模块化的多个模块
0325 peerDependencies 是什么?
我们进行项目开发时,通常会依赖很多第三方库,这些第三方会进一步依赖很多第三方库,由于依赖不同,最终依赖的底层的库的版本不同,造成打包后体积很大。
|
|
解决:在内层项目中,使用 PeerDependencies 处理某些公共的组件库,例如 react react-dom webpack 然后写一个通用的版本,然后在 devDependencies 中也安装公共的组件库。此时 npm publish 就不会把这部分依赖打包。
同版本依赖
|
|
然后外层项目执行 npm install 后,就会进行如下安装,避免了重复的底层库安装
|
|
参考:
https://nodejs.org/en/blog/npm/peer-dependencies/
https://juejin.cn/post/7005890056640528421
https://blog.csdn.net/yinxiangzhongqing/article/details/132104847
https://blog.csdn.net/zhangchao19890805/article/details/78988364
版本号管理:如果修复 bug 那么只改动最后一位小版本;如果发布新功能,那么改动中间版本;如果发布大型跨越式改动,再改动第一个版本号。
0389 内容安全策略是什么
内容安全策略(Content-Security-Policy)是一种安全机制,用于保护 Web 应用程序免受特定类型的攻击,如跨站脚本攻击(XSS)和数据注入攻击。CSP 通过定义策略规则,控制浏览器允许加载和执行的资源,从而减少恶意代码的执行和数据泄漏的风险。
某些服务器在CSP(Content-Security-Policy)中设置了img-src 规则,访问外部的图片受阻。
如果没有设置CSP,可以直接访问这些外部的图片。
这里设置的意思是:只能加载下面的图片
-
与当前页面相同来源(
'self')。 -
数据 URL(
data:)。 -
域名
mt0.google.com、maps.googleapis.com和maps.gstatic.com(可能是谷歌地图相关功能)
实际场景中遇到一次这个问题
0399 webpack-bundle-analyzer
统计第三方依赖占用的存储大小
https://github.com/webpack-contrib/webpack-bundle-analyzer
This module will help you:
-
Realize what’s really inside your bundle
-
Find out what modules make up the most of its size
-
Find modules that got there by mistake
-
Optimize it!
0423 vite 如何获取环境变量
vite 官方给定的环境变量
可以在 JS 中使用全局变量
import.meta.env
可以在不同的开发环境下,使用不同的逻辑:
|
|
-
import.meta.env.MODE: 当前构建模式,可以是"development"、“production"或"test"之一。
-
import.meta.env.BASE_URL: 当前项目的基准URL。
-
import.meta.env.PROD: 一个布尔值,表示当前是否处于生产模式。
-
import.meta.env.DEV: 一个布尔值,表示当前是否处于开发模式。
其他参考:https://blog.csdn.net/jieyucx/article/details/131503612
获取非 vite 官方环境变量的方法(第三方库 dotenv 实现)把配置放在 .env 文件中,这个库可以读出配置
https://www.npmjs.com/package/dotenv
通过这个也能说明,vite 并不是和 vue 深度绑定的,vite 就是一个工具也可以和 React 等很好的结合。
0447 服务器跨域问题
问题:本地开发时,网络请求错误,提示跨域错误。可能有下面几个情况:
情况1 某个服务器没有启动,请求显示跨域
解决过程:浏览器错误是跨域,服务器日志中显示编译错误
原因:因为在宿主机环境执行 npm install,服务在 docker 内部运行,某些第三方依赖库使用C语言编译,没有编译到 docker 内部(即使安装其他第三方库,也会影响已有的这个特殊的库)。所以造成 server 无法编译,服务不正常。nginx 反向代理服务器已经处理了跨域,但是已有服务没起来,所以界面显示的是跨域(找不到对应的服务)。
解决:在 docker 内部,删除 node_modules,重新 npm install 开启服务,正常使用。
总结:界面的报错不一定是真实的原因,需要查看日志,nginx 需要多了解。
情况2 后端处理跨域
使用 nginx 设置代理转发 proxy_pass,后端服务器开启在 7000,前端 webpack-dev-server 开启在 8080,然后统一转发到 22222 端口,这样就避免跨域了。
注:实际项目中,nginx 配置跨域后,node server 是上游服务器,upstream_server,也需要配置跨域。
|
|
参考:https://blog.csdn.net/weixin_36380516/article/details/130960035
情况3:前端处理跨域
本地浏览器支持跨域操作(后端服务和前端页面不在一个端口,但是需要请求登录):更改本地浏览器配置。可以设置 webpack 支持代理,但是设置后无效,可能和 webpack 版本有关,所以直接使用命令行打开浏览器(增加参数打开)
参考:https://blog.csdn.net/qq_41541368/article/details/104035074
把浏览器的同源策略关掉,然后进行调试
|
|
0448 本地多个前端项目联调问题
如果本地多个前端项目需要联调(不同包之间互相引用),目前使用两种方法
1、手动复制依赖包文件
如果本地调试两个前端项目,一个项目需要使用另一个项目打包后的文件,可以直接写一个脚本,然后复制这个打包后的文件到另一个文件夹下面(npm link 也可以实现,但是可能存在缓存问题等等),所以写了这个联调脚本。
本地联调测试脚本
|
|
2、发布测试版本
可以直接发布 npm publish 一个测试版本,然后其他项目使用测试版本即可
0484 主流的前端打包工具有哪些?
常用几个打包库对比
| 名称 | stars | 周下载量 | 链接 |
|---|---|---|---|
| parcel | 43K | 20万 | https://parceljs.org/ |
| rollup | 25K | 2241万 | https://www.npmjs.com/package/rollup |
| webpack | 64K | 2641万 | https://www.npmjs.com/package/webpack |
| rspack | 8k | 8w | https://github.com/web-infra-dev/rspack |
webpack
广泛使用,适合各种大型小型项目,各种插件很丰富。
rollup
适合小项目或者工具库,打包速度很快
parcel
很热,但是下载量一般,配置简单
rspack
字节内部推出的一个打包库,目前内部使用,外部应用不多
总之
一般情况使用 webpack。要求性能好打包快,配置简单,小型工具库,使用 rollup。
0661 常用 webpack 插件
这里常用插件,看一下是否过期
https://juejin.cn/post/6944940506862485511
https://juejin.cn/post/6844904193589772301
https://juejin.cn/post/6844903700226375687
一共30个插件,有的是 2018年使用,注意版本匹配,需要2小时以上
0693 早期 typora 免费使用方法
typora 是一个很好的 markdown 本地编辑器,使用如下
0761 craco 基于 cra 的配置更新
create-react-app 优点是方便快速配置文件,缺点是不能直接支持自定义配置文件。可以通过 npm run eject 实现配置,但是这个操作不可逆,后面需要处理很多的 webpack 细节问题等,也不方便后续的升级等。
为了快捷开发,craco 是一个覆盖 cra 脚手架配置的工具,可以不使用 npm run eject 命令,实现一部分配置自定义,尽量简化开发配置,支持一部分自定义的功能。
官方网站
7K stars 使用人数中等(基本使用没问题)
https://github.com/dilanx/craco
配置说明
https://craco.js.org/docs/category/configuration/
支持下面的自定义
Style
ESLint
Babel
TypeScript
Webpack
Jest
DevServer
CRACO Plugins(社区版本提供,可能和主版本存在不兼容问题,例如 ant-design 插件)
操作流程很简单,不赘述。
具体使用项目是小米有品PC前端项目,novel-reader-ts 项目进行改造后没问题。
0760 大佬谈编程
大佬谈编程思维
Most of my programming career has involved finding something neat, writing my own version to understand it & often throwing it away.
我编程生涯的大部分时间,都在寻找一些整洁的东西,编写自己的版本来理解它,经常把它扔掉。
总结:基本算法和逻辑很整洁(很多corner case 就说明不完善)然后放弃旧项目
Write lots of code. Clone existing things as exercises. Learn deeply. Alternate trying yourself and reading literature. Be obsessive
写很多代码。把现有的东西复制成练习。深入学习。交替尝试自己和阅读文学。强迫自己
总结:多写代码;深入学习
I program those “clones “like | read papers: change a core part; redesign it. Gain progress or understanding why it is what it is.
我给这些“克隆”编程,就像读论文:改变一个核心部分;重新设计它。获得进步,理解为什么它是什么。
抄写好代码;重新设计代码
0756 pnpm
速度快、节省磁盘空间
node_modules 中的所有文件均克隆或硬链接自单一存储位置(类似 yarn 的单一存储位置)
pnpm 创建的 node_modules 默认并非扁平结构,因此代码无法对任意软件包进行访问(但是不方便改源码调试)
0772 分析前端项目不同组件的依赖关系
使用VS Code插件:Dependency Cruiser Extension,安装后可以在文件右键菜单中点击“View Dependencies”查看基于该文件的依赖。
使用Webpack的stats对象:Webpack的stats对象包含了大量的编译时信息,可以通过它生成包含模块统计数据的JSON文件。这些统计数据可以帮助开发者分析应用的依赖图表,优化编译速度。
Webpack Bundle Analyzer:这是一个可视化工具,可以帮助开发者分析webpack打包后的文件大小和模块依赖关系。
Dependency Cruiser:这是一个命令行工具,用于生成依赖图,支持多种输出格式,包括SVG。
0882 npx depcheck 移除废弃依赖
项目中可能有多余的依赖,使用这个命令可以移除多余的依赖文件