版本控制

什么是版本控制 版本控制是一种系统性的方法,用于管理和跟踪软件开发项目中的代码、文件和资源。它的核心目标是在不同时间点的开发中保持代码的一致性、可追溯性和可维护性。 为什么要做版本控制 这个问题可以从定义中的关键词可以看出端倪:不同时间点下的代码一致性、可追溯性、可维护性。这里额外补充一点:当今的互联网开发早已步入敏捷迭代,各种动态化方案层出不穷都有着顺应时代潮流的意思,因此软件开发一定会越来越多地涉及到团队开发,团队之间的协作也一定需要这样一个机制去保障稳定性。 代码一致性 版本控制系统允许开发人员有效地管理和组织项目中的代码。它跟踪每个文件的历史记录,记录了每个版本的变更,包括谁做了什么修改、何时以及为什么。 可追溯性 版本控制系统允许为重要的里程碑或发布创建标签(tag),以便轻松识别和回滚到特定版本。 并且当某个版本的代码出现问题,版本控制系统允许开发人员轻松地回滚到之前的稳定版本,并在不破坏其余代码的情况下进行修复。 可维护性 开发人员可以创建分支(branch),这是一个独立的代码副本,用于开发新功能、修复错误或进行实验性工作。然后,这些分支可以与主代码库合并,以实现功能集成。 团队协作 在多人协作的环境中,不同开发者可能同时修改代码。版本控制系统确保不同的修改不会互相冲突,以及如何解决冲突。 版本控制系统促进了团队之间的协作,可以通过代码审查工具进行代码审查,以确保代码质量和一致性。 版本控制工具Git Git的安装 WIndows 访问 Git官网,选择对应的操作系统下载即可。 这里下载独立安装包即可 点install就行,会自动安装一个git GUI工具,但通常不会直接用它 下载完成安装即可,输入以下命令验证安装是否成功 git version 图形化工具 安装 这里推荐TortoiseGit这个工具,非常方便。但我觉得Git本身学习成本并不高,GUI工具更多是为了提升效率,基本的Git知识点还是需要掌握的。 下载本体 然后是语言包 安装时一路next即可,安装完本体后再安装语言包。 配置好Github的账户、邮箱、秘钥等,注意配置好了密钥也不会在下述部分显示,可以打开编辑全局进行查看 使用 在使用之前先提前补充一个点(后续会详细介绍),Git有本地仓库和远端仓库的概念,通常支持HTTPS和SSH两种协议进行关联,两种方式优缺点也十分明显: HTTPS:无需额外配置,但是在每次连接远端仓库时需要输入账号密码进行校验。 SSH:生成一组密钥对,需要本地进行配置,好处是配置好后每次连接远端仓库时会自动比较密钥对,无需额外校验。关于SSH详细可以参考这篇文章ssh-远程登录协议 为了一劳永逸,我们这里配置下SSH,首先打开Git bash # 输入下列命令,最后一个参数是您的邮箱 $ ssh-keygen -t rsa -C yourEmail.com 可以看到密钥对已经生成了 进入上述目录,注意.ssh文件夹默认是隐藏的,直接访问路径就行 以Github为例,配置公钥 创建一个Demo项目,平时学习的话就创建公有项目就行 复制一下我们的项目链接 选取一个你喜欢的目录作为本地工作区,然后按鼠标右键 ...

August 7, 2025

代码规范工程化

规范化是前端工程化的一个重要部分。现在,有许多工具能够辅助我们实行代码的规范化,比如你一定知道的 ESLint 和 Prettier。 今天,来聊聊这些工具的工作原理和基本使用,了解它们是如何发挥作用的,以及如何更好地利用这些工具去规范项目的代码。 1. ESlint - 检查你的 JavaScript 代码 让我们先从知名度最高的 ESLint 开始。 1.1. ESLint 及其作用 Lint 是一类专门用于检查代码的工具软件, 也称 linter。ESLint ,即 JavaScript (ECMAScript)代码的检查工具。 正如官网的介绍 —— “Find and fix problems in your JavaScript code”,ESLint 能够辅助查找出你的 JavaScript 代码中的问题,包括: 代码风格问题(styles)。比如,运算符两边的空格、语句末尾的分号。 不好的写法。比如,使用 == 进行比较而不是 ===。 可能存在逻辑问题的代码模式。比如,定义了一个变量,但没有使用到它。 此外,ESLint 还能够帮你自动修复一些简单的问题。 我们将在下一小结学习如何使用 ESLint 检查我们的 JavaScript 代码,并修复其中的一些问题。 1.2. ESLint 快速上手 为了在项目中使用 ESLint,需要先安装它。 # 初始化一个 npm 项目 mkdir eslint-test cd eslint-test npm init -y # 安装 eslint npm init @eslint/config 回答一系列问题后,你可以看目录中的配置文件 .eslintrc.js,这个配置文件告诉 ESLint 如何去解析项目,这个项目采用了哪些规范和规则。 ...

August 7, 2025

前端任务自动化(npm scripts实现)

在前端开发中,我们经常需要执行各种重复性任务,比如编译代码、启动本地服务器、监听文件变化、运行测试、部署代码等。虽然可以使用不同的工具来完成这些任务,但npm本身提供了一个强大的功能:npm scripts。通过npm scripts,我们可以将这些任务脚本化并集中管理,从而提高开发效率。 本文将专注于如何使用npm scripts自动化前端开发任务,以及它在项目管理中的作用。 什么是npm scripts? npm scripts是npm提供的一种机制,允许我们在项目的package.json文件中定义一组命令,方便执行各种任务。在package.json文件中,scripts字段可以包含多个脚本,每个脚本都是一个键值对,其中键是脚本的名称,值是实际要执行的命令。例如: { "scripts": { "build": "webpack --config webpack.config.js", "test": "jest" } } 在上面的示例中,定义了两个脚本:build 和 test。可以通过以下方式在命令行中运行这些脚本: npm run build npm run test npm会执行对应的命令,自动帮我们完成编译和测试任务。 为什么使用npm scripts? 在现代前端开发流程中,自动化任务是不可或缺的,而npm scripts的使用有以下几大优势: 减少对全局依赖的需求:在传统项目中,开发者通常需要全局安装各种命令行工具,如webpack、eslint、babel等。而npm scripts可以直接调用项目的本地依赖,无需全局安装。这确保了不同开发环境中的工具版本一致,减少了版本冲突和兼容性问题。 集中管理任务:npm scripts将所有任务定义集中在package.json文件中,项目中的所有开发人员都可以直观地看到可用的任务列表,无需了解每个工具的详细使用方法。只需运行npm run <task>,便可一键完成常见任务。 支持跨平台执行:npm scripts中的命令可以跨平台使用,在Windows、macOS和Linux系统上表现一致,尤其适合团队协作。 便于组合和链式执行:npm允许通过逻辑操作符来组合脚本,实现复杂任务的自动化执行。例如可以通过&&和||来串联多个任务,使得多个步骤一次完成。 如何定义和使用npm scripts? 让我们通过具体的示例来看看npm scripts如何自动化前端开发任务。 1. 设置基本的开发任务 假设我们正在开发一个React项目,我们可以在package.json中定义以下基本任务: { "scripts": { "start": "webpack serve --mode development", "build": "webpack --mode production", "test": "jest", "lint": "eslint src/**/*.js" } } 这里的脚本分别执行以下任务: ...

August 7, 2025

前端构建工具详解

谈到构建工具,大家首先想到的肯定就是 Webpack 以及现在最🔥的 Vite。 Webpack,功能强大,生态丰富,从面世到今天,一直是很受大家欢迎;Vite 采用 unbundle 构建模式,带来了极致的开发体验,给开发人员以新的选择。 在这两个构建工具之外,还有其他的构建工具,如和 Webpack、Vite 类似的 Rollup、Parcel、Esbuild,自动化构建工具 grunt、gulp,以及更加久远的 YUI Tool。 这些工具的存在,构成了前端构建工具的发展史。 YUI Tool + Ant YUI tool 是 07 年左右出现的一个构建工具,功能比较简单,用于压缩混淆 css 和 js 代码,需要配合 java 的 Ant 使用。 当时 web 应用开发主要采用 JSP,还不像现在这样前后端分离,通常是由 java 开发人员来编写 js、css 代码,前端代码都是和后端 java 代码放在一起的。因此前端代码的压缩混淆也就基于 java 实现了。 Grunt / Gulp Grunt / Gulp 都是运行在 node 环境上的自动化工具。 在开发过程中,我们可以将一些常见操作如解析 html、es6 代码转换为 es5、less / sass 代码转换为 css 代码、代码检查、代码压缩、代码混淆配置成一系列任务,然后通过 Grunt / Gulp 自动执行这些任务。 Grunt 和 Gulp 的不同点: ...

August 7, 2025

任务自动化

在前端开发中,我们经常需要执行各种重复性任务,比如编译代码、启动本地服务器、监听文件变化、运行测试、部署代码等。虽然可以使用不同的工具来完成这些任务,但npm本身提供了一个强大的功能:npm scripts。通过npm scripts,我们可以将这些任务脚本化并集中管理,从而提高开发效率。本文将专注于如何使用npm scripts自动化前端开发任务,以及它在项目管理中的作用。 什么是npm scripts? npm scripts是npm提供的一种机制,允许我们在项目的package.json文件中定义一组命令,方便执行各种任务。在package.json文件中,scripts字段可以包含多个脚本,每个脚本都是一个键值对,其中键是脚本的名称,值是实际要执行的命令。例如: { "scripts": { "build": "webpack --config webpack.config.js", "test": "jest" } } 在上面的示例中,定义了两个脚本:build 和 test。可以通过以下方式在命令行中运行这些脚本: npm run build npm run test npm会执行对应的命令,自动帮我们完成编译和测试任务。 为什么使用npm scripts? 在现代前端开发流程中,自动化任务是不可或缺的,而npm scripts的使用有以下几大优势: 减少对全局依赖的需求:在传统项目中,开发者通常需要全局安装各种命令行工具,如webpack、eslint、babel等。而npm scripts可以直接调用项目的本地依赖,无需全局安装。这确保了不同开发环境中的工具版本一致,减少了版本冲突和兼容性问题。 集中管理任务:npm scripts将所有任务定义集中在package.json文件中,项目中的所有开发人员都可以直观地看到可用的任务列表,无需了解每个工具的详细使用方法。只需运行npm run <task>,便可一键完成常见任务。 支持跨平台执行:npm scripts中的命令可以跨平台使用,在Windows、macOS和Linux系统上表现一致,尤其适合团队协作。 便于组合和链式执行:npm允许通过逻辑操作符来组合脚本,实现复杂任务的自动化执行。例如可以通过&&和||来串联多个任务,使得多个步骤一次完成。 如何定义和使用npm scripts? 让我们通过具体的示例来看看npm scripts如何自动化前端开发任务。 1. 设置基本的开发任务 假设我们正在开发一个React项目,我们可以在package.json中定义以下基本任务: { "scripts": { "start": "webpack serve --mode development", "build": "webpack --mode production", "test": "jest", "lint": "eslint src/**/*.js" } } 这里的脚本分别执行以下任务: ...

October 5, 2024

Webpack与Vite

前言 vite比webpack快? vite比webpack简单? 今天我们就来分析一下,到底有什么不一样的地方! 定位 对比之前,我们先要搞懂,vite与webpack的定位以及关系才可以。 那前端社区中常谈到的这些工具webpack、rollup、parcel、esbuild、vite、vue-cli、create-react-app、umi他们之间的关系是怎样的。 webpack、rollup、parcel、esbuild都是打包工具,代码写好之后,我们需要对代码进行压缩、合并、转换、分割、打包等操作,这些工作需要打包工具去完成。 vue-cli、create-react-app、umi 是基于webpack的上层封装,通过简单的配置就可以快速创建出一个项目,把更多的时间放在业务开发上。 vite开发环境依赖esbuild进行预构建,生产环境则依赖rollup进行打包,并且充分利用了现代浏览器的特性,比如http2、ES module,vite是站在众多巨人肩膀上的一个产物, 类似webpack + webpack-dev-server的结合体,是一个非常棒的前端项目的构建工具。 运行原理 首先,我们从运行原理上分析一下,vite为什么比webpack快。 webpack运行原理 当我们使用webpack启动项目时,webpack会根据我们配置文件(webpack.config.js) 中的入口文件(entry),分析出项目项目所有依赖关系,然后打包成一个文件(bundle.js),交给浏览器去加载渲染。 这样就会带来一个问题,项目越大,需要打包的东西越多,启动时间越长。 关于ES module 在讲vite运行原理之前,我们先说一下ES module 目前,绝大多数现代浏览器都已经支持ES module了, 我们只需要在<script>标签中添加type="module",就可以使用ES module了。 下面这段代码是可以直接在浏览器中运行的。 // test.js export default function hello() { console.log('hello world'); } // index.html <script type="module"> import hello from './test.js'; hello(); // hello world </scirpt> vite运行原理 在<script type="module">中,浏览器遇到内部的import引用时,会自动发起http请求,去加载对应的模块。 vite也正是利用了ES module这个特性,使用vite运行项目时,首先会用esbuild进行预构建,将所有模块转换为es module,不需要对我们整个项目进行编译打包,而是在浏览器需要加载某个模块时,拦截浏览器发出的请求,根据请求进行按需编译,然后返回给浏览器。 这样一来,首次启动项目(冷启动)时,自然也就比webpack快很多了,并且项目大小对vite启动速度的影响也很小。 构建方式 我们再来看一下,vite与webpack在项目构建上有哪些区别。 webpack webpack是基于nodejs运行的,但js只能单线程运行,无法利用多核CPU的优势,当项目越来越大时,构建速度也就越来越慢了。 vite vite预构建与按需编译的过程,都是使用esbuild完成的。 esbuild是用go语言编写的,可以充分利用多核CPU的优势,所以vite开发环境下的预构建与按需编译速度,都是非常快的。 http2 vite充分利用了http2可以并发请求的优势,这也是速度快的一个主要原因。 接下来,我们了解一下http2的来龙去脉。 在之前http1的时候,浏览器对同一个域名的请求,是有并发限制的,一般为6个,如果并发请求6个以上,就会造成阻塞问题,所以在http1的时代,我们要减少打包产物的文件数量,减少并发请求,来提高项目的加载速度。 2015年以后,http2出现了,他可以并发发送多个请求,不会出现http1的并发限制。这时候,将打包产物分成多个小模块,并行去加载,反而会更快。 vite也充分利用了这一优势,对项目资源进行了合理的拆分,访问项目时,同时加载多个模块,来提升项目访问速度。 热更新 vite速度快的另一个原因是与webpack不同的热更新机制。 ...

October 5, 2024

前端模块化

一、模块化的理解 1.什么是模块? 将一个复杂的程序依据一定的规则(规范)封装成几个块(文件), 并进行组合在一起 块的内部数据与实现是私有的, 只是向外部暴露一些接口(方法)与外部其它模块通信 2.模块化的进化过程 全局function模式 : 将不同的功能封装成不同的全局函数 编码: 将不同的功能封装成不同的全局函数 问题: 污染全局命名空间, 容易引起命名冲突或数据不安全,而且模块成员之间看不出直接关系 function m1(){ //... } function m2(){ //... } namespace模式 : 简单对象封装 作用: 减少了全局变量,解决命名冲突 问题: 数据不安全(外部可以直接修改模块内部的数据) let myModule = { data: 'www.baidu.com', foo() { console.log(`foo() ${this.data}`) }, bar() { console.log(`bar() ${this.data}`) } } myModule.data = 'other data' //能直接修改模块内部的数据 myModule.foo() // foo() other data 这样的写法会暴露所有模块成员,内部状态可以被外部改写。 IIFE模式:匿名函数自调用(闭包) 作用: 数据是私有的, 外部只能通过暴露的方法操作 编码: 将数据和行为封装到一个函数内部, 通过给window添加属性来向外暴露接口 问题: 如果当前这个模块依赖另一个模块怎么办? // index.html文件 <script type="text/javascript" src="module.js"></script> <script type="text/javascript"> myModule.foo() myModule.bar() console.log(myModule.data) //undefined 不能访问模块内部数据 myModule.data = 'xxxx' //不是修改的模块内部的data myModule.foo() //没有改变 </script> // module.js文件 (function(window) { let data = 'www.baidu.com' //操作数据的函数 function foo() { //用于暴露有函数 console.log(`foo() ${data}`) } function bar() { //用于暴露有函数 console.log(`bar() ${data}`) otherFun() //内部调用 } function otherFun() { //内部私有的函数 console.log('otherFun()') } //暴露行为 window.myModule = { foo, bar } //ES6写法 })(window) 最后得到的结果: ...

October 5, 2024

工程化 面试题

共 87 道 工程化 面试题。答案默认折叠,便于先自行作答。 1. webpack 中的 Loader ,链式调用顺序会影响编译结果吗? 难度:2 · 类型:QA 题目要点 Webpack Loader 是一个按流水线执行的源码转换系统,Loader 的链式顺序直接决定源码被处理的阶段;配置顺序为从左到右,但执行顺序为从右到左,每个 Loader 都处理前一个 Loader 的输出,因此顺序错误会导致语义阶段错乱甚至编译失败;通常应遵循“靠近源码的 Loader 放右侧,靠近运行时的 Loader 放左侧”的原则,同时 Loader 还存在 pitch 与 normal 两阶段执行机制,使顺序对最终编译结果具有决定性影响。 参考答案 会,而且这是 Webpack Loader 机制中非常关键且经常被误解的一点: Loader 的链式调用顺序不仅会影响编译结果,而且很多语法是否能正确工作,完全取决于 Loader 的执行顺序。 理解这个问题的关键在于:Loader 本质是一个“源码转换流水线(transform pipeline)”。 一、Loader 本质:源码的逐步转换 在 Webpack 中 hookup 的 Loader,并不是同时运行的,它们会对模块源码进行一层一层的转换: 原始源码 → loaderA → loaderB → loaderC → 最终 JS 模块 每个 Loader: 接收上一个 Loader 的输出 返回新的源码字符串(或 AST 转换结果) 交给下一个 Loader 因此: ...