原稿:语雀 · Web 综合 · 原目录:面向面经学习 › Web 综合

前端工程化

前端工程化是藉由工程化的模式、自动化的工具,以实现前端项目高效开发,有效协同,质量可控

设计阶段:

  • 需求分析
  • 组件化思想,一个软件项目可以拆分为哪些不同的子组件,子组件又能怎么拆分
  • 架构设计,如何选择技术栈、路由设计、项目结构设计

开发阶段:

  • 模块化开发:将所有文件都视为模块,通过不同模块之间的依赖构建成一个完备的项目,模块本身可以复用或者随时装卸
  • 开发过程规范化:代码规范、图片规范、文件规范、接口规范
  • 使用工具完成自动化测试

构建阶段:

  • 使用构建工具:使用 webpack 等工具进行编译打包,后者会根据依赖关系生成模块,期间可以通过不同的插件实现拆分合并、代码压缩等,优化最后的输出结果
  • 使用持续集成工具,完成自动化部署

运维阶段:通过自动监视代码,实现页面错误和性能的监视

Git 相关

新建

# 初始化当前项目
git init

# 新建一个目录,将其初始化为Git代码库
git init [project-name]

分支

# 查看所有本地分支
git branch

# 查看所有远程分支
git branch -r

# 查看所有本地分支和远程分支
git branch -a

# 新建一个分支,但依然停留在当前分支
git branch [branch-name]

# 创建并切换到新建分支
git checkout -b [branch-name]

# 从当前分支,切换到指定分支,并更新工作区
git checkout [branch-name]

# 合并指定分支到当前分支
git merge [branch-name]

版本回退

# 重置暂存区与工作区,与上一次commit保持一致
git reset --hard

# 重置当前分支的指针为指定commit,同时重置暂存区,但工作区不变
git reset [commit]

# 重置当前分支的HEAD为指定commit,同时重置暂存区和工作区,与指定commit一致
git reset --hard [commit]

# 重置当前HEAD为指定commit,但保持暂存区和工作区不变
git reset --keep [commit]

冲突解决

产生:当在 master 和 feature1 两个分支上都对同一个文件进行了修改提交后,现在要合并分支,这时 git 无法进行快速合并,可能会有冲突,可以使用 git status 查看也可以直接查看文件(git会自动标识)

解决办法:拉取远程分支,手动合并,暂存提交,最后推送

1.使用 git fetch origin master 将远程分支拉下来
2.使用 git merge origin master 手动合并冲突的内容
    以上两步可同时用 git pull 完成
3.使用 git add xxx和git commit -m "xxx" 将改动提交
4.使用 git push origin master 将改动提交到远程分支

错误监控

常见的两种方案:try catch 与 window.onerror

  • try catch:没有办法捕获全局错误,没有办法处理代码块外的错误
  • window.onerror:前端 js 错误监控主要是利用了 window.onerror 函数来实现,onerror 回调会在页面发生 js 错误时被调用
window.onerror = function(errorMessage, scriptURI, lineNumber,columnNumber,errorObj) {
  console.log("错误信息:" , errorMessage);
  console.log("出错文件:" , scriptURI);
  console.log("出错行号:" , lineNumber);
  console.log("出错列号:" , columnNumber);
  console.log("错误详情:" , errorObj);
  return true; // 返回 true 后不会报错 uncaught error
}

const a = 1;
a = 2;
image.png
<!-- index.html  --><script type="text/javascript" src="http://a.com/a.js" ></script><script type="text/javascript" src="http://b.com/b.js" ></script>
// a.jswindow.onerror = function (message, url, line, column, error) {  console.log('log---onerror::::',message, url, line, column, error);}
// b.js
throw new Error('this is the error happened in b.js');

注意,当 index.html 引入 A 域下的 a.js 和 B 域下的 b.js 时:

  • a.js 在设置 onerror 监听
  • b.js 抛出错误,此时只能看到打印 Script error, 0 0 null,这是由于同源策略,尽管 onerror 可以监测到跨域脚本的错误,但是没办法获取错误的具体内容

解决方案: 2. 给 b.js 加上 Access-Control-Allow-Origin:* 的 response header 4. 给 b.js 引入处加上 crossorigin 属性

<!-- index.html  -->
<script type="text/javascript" src="http://a.com/a.js" ></script>
<script type="text/javascript" src="http://b.com/b.js" crossorigin></script>

JS 面向对象与设计模式

  • 工厂模式:直接创建 object,在上面添加属性

缺陷:可以创建多个类似对象,但没有解决标识问题(即新创建的对象是什么类型)

  • 构造函数模式:通过 new 调用函数,构造对象实例

解决的问题:类的标识

缺陷:在构造函数内部通过 this 创建的函数无法复用,每个新实例都会创建一遍

  • 原型模式:每个非箭头函数都会创建一个 prototype 属性,该属性是一个对象,包含应该由特定引用类型的实例共享的属性和方法。当前函数作为构造函数创建的实例共享原型对象上的属性

基于原型模式,JS 中的继承主要有

  • 组合式继承:父类实例作为子类原型 + 借用构造函数
  • 寄生式组合继承:父类原型副本作为子类原型 + 借用构造函数
  • 原型式继承:基于已有对象作为原型创建一个对象,可使用 Object.create() 实现
  • 类继承:本质上是寄生式组合继承

设计模式在 Vue

  • 发布订阅模式:vue 响应式原理
  • 装饰器模式:vue 对于数组原型中的变更方法做了切面,在不修改原始数组原型的情况下使得数组变更方法实现了响应式
  • 单例模式:vuex 中使用 storeVm 实例进行全局状态管理,storeVm 就是一个“单例”