🐠 I’m scTaoFelix.
sctaofelix / blog Goto Github PK
View Code? Open in Web Editor NEWBLOG NOT PAGES
BLOG NOT PAGES
.git
的子目录,这个子目录含有你初始化的 Git
仓库中所有的必须文件,这些文件是 Git
仓库的骨干。 但是,在这个时候,我们仅仅是做了一个初始化的操作,你的项目里的文件还没有被跟踪。$ git init # 在当前目录新建一个 Git代码库
$ git init [project-name] # 新建一个目录,将其初始化为 Git代码库
Git
克隆的是该 Git
仓库服务器上的几乎所有数据,而不是仅仅复制完成你的工作所需要文件。 当你执行 git clone 命令的时候,默认配置下远程 Git 仓库中的每一个文件的每一个版本都将被拉取下来。$ git clone <url>
$ git clone <url> myRepoName # 克隆远程仓库 并自定义本地仓库的名字
Git的设置文件为.gitconfig ,它可以在用户主目录下(全局配置),也可以在项目目录下(项目配置)。
/etc/gitconfig
(/usr/local/etc/gitconfig
)文件: 包含系统上每一个用户及他们仓库的通用配置。 如果在执行 git config
时带上 --system
选项,那么它就会读写该文件中的配置变量。 (由于它是系统配置文件,因此你需要管理员或超级用户权限来修改它。)
~/.gitconfig
或 ~/.config/git/config
文件:只针对当前用户。 你可以传递 --global
选项让 Git
读写此文件,这会对你系统上 所有
的仓库生效。
当前使用仓库的 Git
目录中的 config
文件(即 .git/config
):针对该仓库。 你可以传递 --local
选项让 Git
强制读写此文件,虽然默认情况下用的就是它。。 (当然,你需要进入某个 Git
仓库中才能让该选项生效。)
$ git config --list # 显示当前的Git配置
$ git config --list --show-origin # 显示当前的Git配置及文件位置
$ git config -e [--global] # 编辑Git配置文件
# 配置 名称和邮箱
$ git config --global user.name "John Doe"
$ git config --global user.email [email protected]
e.g:
比如你有个公司的 gitLab
和你自己的 gitHub
你可以 把全局的设置为 公司的邮箱账号,而你自己的 gitHub 则用仓库中的 config。
你可以在你的仓库里运行以下命令:
# --local
$ git config user.name "John"
$ git config user.email "[email protected]"
首先我们要知道文件的状态只会有两种:已跟踪
或 未跟踪
未修改
、已修改
、已放入暂存区
git
记录, 使用 git add
添加到已跟踪文件$ git add <files> # 跟踪新文件
$ git add * # 添加当前目录的所有文件到暂存区(包含 .gitignore 过滤的文件) -f
$ git add . # 添加当前目录的所有文件到暂存区(不包含 .gitignore 过滤的文件)
$ git add -p # 对于同一个文件的多处变化,可以实现分次提交
作用:
git status 命令查看哪些文件处于什么状态
$ git status
$ git status -s / --short 精简
.gitignore:列出要忽略的文件的模式
# 查看 .gitignore 文件内容
$ cat .gitignore
*.a # 忽略所有的 .a 文件
*.[oa] # 忽略所有以 .o 或 .a 结尾的文件
*~ # 忽略所有名字以波浪符(~)结尾的文件
!lib.a # 跟踪所有的 lib.a,虽然上面忽略了 .a 文件
/TODO # 只忽略当前目录下的 TODO 文件
build/ # 忽略任何目录下名为 build 的文件夹
doc/*.txt # 只忽略 doc/notes.txt,但不忽略 doc/server/arch.txt
doc/**/*.pdf # 忽略 doc/ 目录及其所有子目录下的 .pdf 文件
gitignore 例子
文件 .gitignore 的格式规范如下:
glob 模式是指 shell 所使用的简化了的正则表达式。
在最简单的情况下,
一个仓库可能只根目录下有一个 .gitignore 文件,它递归地应用到整个仓库中。
子目录下也可以有额外的 .gitignore 文件。子目录中的 .gitignore 文件中的规则只作用于它所在的目录中。
$ git diff
$ git diff --staged (--cached) [file]
$ git diff HEAD
$ git diff [first-branch]...[second-branch]
$ git commit -v # 提交时显示所有 diff信息
$ git commit # 不加参数会掉起 Vim 的编辑方式
Vim 的编辑方式展示:
开头第一行是个空行,供你输入提交说明(我输入的是 init repo
)。
默认的提交消息放在注释行里,退出编辑器时,Git 会丢弃注释行,用你输入的提交说明生成一次提交。
$ git commit -m"将提交信息与命令放在同一行"
[master 2a4e415] init repo
1 file changed, 1 insertion(+)
提交后它会告诉你,当前是在哪个分支(master)提交的,本次提交的完整 SHA-1 校验和是什么(2a4e415),以及在本次提交中,有多少文件修订过,多少行添加和删改过。
$ git commit -a -m "跳过 git add 步骤"
# 等于
$ git add *
$ git commit -m "xxx"
此命令会将你工作区所有的更改都添加到提交中。
从暂存区移除 & 在工作目录删除
# 已提交的文件
$ git rm PROJECTS.md
# 工作区修改过或已经放到暂存区
$ git rm file.name -f (--force)
下一次提交时,该文件就不再纳入版本管理了。只需 git commit
提交(无需 git add
)。
从暂存区移除
$ git rm --cached file.name
# 使用 glob 模式: 删除 log/ 目录下扩展名为 .log 的所有文件。
$ git rm log/\*.log
# 直接保存到了暂存区
$ git mv file_from.md file_to.md
# 等于
$ mv file_from.md file_to.md
$ git rm file_from.md
$ git add file_to.md
# 或者
$ mv file_from.md file_to.md
$ git add *
$ git log
commit 2a4e4157641a858034dffab06b5c8f9a88b02c00 (HEAD -> master)
Author: sc <[email protected]>
Date: Sun Oct 10 15:30:55 2021 +0800
delete file
commit be2150139fad2740995d3ddccf7089fcc41fce2b
Author: sc <[email protected]>
Date: Sun Oct 10 15:27:24 2021 +0800
init repo
$ git log -p -2 (-2代表选项来只显示最近的两次提交)
# 每次提交的简略统计信息
$ git log --stat -2
#(short,full 和 fuller)
$ git log --pretty=oneline
a16782d70db6c254004aed029433c2636a697aa7 (HEAD -> master) 最后的提交
85075a97cc9a0b8fa358df5c5fc29e9da1f0a057 log
来看一个实际的例子,如果要在 Git 源码库中查看 scTaoFelix 在 2020-10-01 到 2021-10-01其间, 除了合并提交之外的提交,可以使用下面的命令:
$ git log --pretty="%h - %s" --author='scTaoFelix <[email protected]>' --since="2020-10-01" --before="2021-10-01" --no-merges
选项 | 说明 |
---|---|
-p |
按补丁格式显示每个提交引入的差异。 |
--stat |
显示每次提交的文件修改统计信息。 |
--shortstat |
只显示 --stat 中最后的行数修改添加移除统计。 |
--name-only |
仅在提交信息后显示已修改的文件清单。 |
--name-status |
显示新增、修改、删除的文件清单。 |
--abbrev-commit |
仅显示 SHA-1 校验和所有 40 个字符中的前几个字符。 |
--relative-date |
使用较短的相对时间而不是完整格式显示日期(比如“2 weeks ago”)。 |
--graph |
在日志旁以 ASCII 图形显示分支与合并历史。 |
--pretty |
使用其他格式显示历史提交信息。可用的选项包括 oneline、short、full、fuller 和 format(用来定义自己的格式)。 |
--oneline |
--pretty=oneline --abbrev-commit 合用的简写。 |
$ git log --pretty=format:"%h - %an, %ar : %s"
a16782d - sc, 11 分钟前 : 最后的提交
85075a9 - sc, 12 分钟前 : git log
--pretty=format
$ git log --pretty=format:"%h %s" --graph
选项 | 说明 |
---|---|
%H |
提交的完整哈希值 |
%h |
提交的简写哈希值 |
%T |
树的完整哈希值 |
%t |
树的简写哈希值 |
%P |
父提交的完整哈希值 |
%p |
父提交的简写哈希值 |
%an |
作者名字 |
%ae |
作者的电子邮件地址 |
%ad |
作者修订日期(可以用 --date=选项 来定制格式) |
%ar |
作者修订日期,按多久以前的方式显示 |
%cn |
提交者的名字 |
%ce |
提交者的电子邮件地址 |
%cd |
提交日期 |
%cr |
提交日期(距今多长时间) |
%s |
提交说明 |
--since,--after
- 仅显示指定时间之后的提交(不包含当前日期)
--until,--before
- 仅显示指定时间之前的提交(包含当前日期)
# 查看从 2021-09-18 之后到 3周前的提交
$ git log --pretty="%h - %s" --before={3,weeks,ago} --after={2021-09-18}
$ git log --since=2.weeks
选项 | 说明 |
---|---|
-<n> |
仅显示最近的 n 条提交。 |
--since, --after |
仅显示指定时间之后的提交。 |
--until, --before |
仅显示指定时间之前的提交。 |
--author |
仅显示作者匹配指定字符串的提交。 |
--committer |
仅显示提交者匹配指定字符串的提交。 |
--grep |
仅显示提交说明中包含指定字符串的提交。 |
-S |
仅显示添加或删除内容匹配指定字符串的提交。 |
重置 commit
$ git commit --amend
有时候我们提交完了才发现漏掉了几个文件没有添加,或者提交信息写错了
# 最终你只会有一个提交——第二次提交将代替第一次提交的结果。
$ git commit -m 'initial commit'
$ git add forgotten_file
$ git commit --amend
最终你只会有一个提交——第二次提交将代替第一次提交的结果。
取消暂存的文件
git restore --staged <file>...
将文件从暂存区撤出,但不会撤销文件的更改(git reset HEAD <file>...
)撤消对文件的修改
git resore <file>...
将不在暂存区的文件撤销更改, git checkout -- readme.md
也有相同的作用在 Git 中任何 已提交
的东西几乎总是可以恢复的。 甚至那些被删除的分支中的提交或使用 --amend 选项覆盖的提交也可以恢复。 然而任何你未提交的东西丢失后很可能再也找不到了。
$ git remote
origin
# 列出所有的远程仓库
$ git remote -v
origin xxx (fetch)
origin xxx (push)
git remote add <shortname> <url>
$ git fetch <remote>
$ git push origin master
$ git remote show origin
$ git remote rename old_name new_name
$ git remote remove origin 或 git remote rm origin
git tag (可带上可选的 -l 选项 --list):
$ git tag # 列出所有tag
v1.0
v2.0
$ git tag -l "v1.8.5*"
匹配标签名的通配模式
Git 支持两种标签:轻量标签(lightweight)与附注标签(annotated)。
附注标签
$ git tag -a v1.4 -m "my version 1.4"
$ git tag
v0.1
v1.3
v1.4
通过使用 git show 命令可以看到标签信息和与之对应的提交信息:
git show v1.4
轻量标签
轻量标签本质上是将提交校验和存储到一个文件中——没有保存任何其他信息。 创建轻量标签,不需要使用 -a、-s 或 -m 选项,只需要提供标签名字:
$ git tag v1.4-lw
$ git tag
v0.1
v1.3
v1.4
v1.4-lw
v1.5
$ git tag -a v1.2 commitID
$ git checkout -b [branch] [tag]
默认情况下,git push 命令并不会传送标签到远程仓库服务器上。 在创建完标签后你必须显式地推送标签到共享服务器上。 这个过程就像共享远程分支一样——你可以运行 git push origin 。
$ git push <remote> --tags # 推送所有tag
$ git push [remote] [tag] # 推送某个tag
# git push origin v1.5
要删除掉你本地仓库上的标签,可以使用命令
git tag -d <tagname> # 删除本地tag
git push <remote> :refs/tags/<tagname> # 删除远程tag
# git push origin :refs/tags/v1.4-lw
git push origin --delete v1.0
# 删除远程标签,git push origin :v1.0
# git push origin :refs/tags/v1.0
$ git config --global alias.co checkout
$ git config --global alias.br branch
$ git config --global alias.ci commit
$ git config --global alias.st status
随着硬件性能、前端自身快速发展等因素,前端应用程序的体量与复杂度直线上升。
在大型应用的开发过程中,随着开发人员数量的增加、代码体量的增长、业务场景复杂度的上升,文档及单元测试的不完整等情况的出现。
使得 JavaScript 动态语言与弱类型的语言特性暴露了以下问题:
并且在一个项目开发中,随着需求的变化和代码体量的增长,我们的项目不可避免地会趋于复杂,最终造成了项目中后期进度缓慢的情形 。如何对项目复杂度及其增长速率进行有效控制,便成为一个日益突出的问题。而 Typescript 正是在这种情况下,应运而生的。
Typescript 的维基百科词条
静态类型检查、面向对象
静态类型检查
rollbar 是一个异常监控平台,rollbar 于 2018 年统计了前端项目中Top10 的错误类型:
其中有 7 个是类型错误(TypeError):
怎么解决,举一个例子:
假如你写了一个 utils 方法 sayName:
function sayName(dog) {
return dog.sayName()
}
作为调用方调用:
// 在javascript中调用报错
// Uncaught TypeError: dog.sayName is not a function
sayName("dog")
看过前面的函数定义,我们知道以上代码不出意外会报错,因为 dog 字符串没有 sayName 方法。
实际情况中,函数定义对于调用者而言是一个黑盒,错误的调用成为了大概率事件,可怕的是开发阶段你完全觉察不到错误的存在。
为了解决这个问题,我们用 typescript 为 dog 参数提供了类型描述 dogType.
// DogType 描述了一个包含 sayName 方法的类型
type DogType = {
sayName: ()=> void;
};
function sayName(dog: DogType) {
return dog.sayName()
}
// 以下代码在 typescript 中调用报错(vscode)
// 类型“string”的参数不能赋给类型“DogType”的参数。ts(2345)
sayName('dog')
面向对象
封装、继承、多态。
// 继承:子类继承父类,子类除了拥有父类的所有特性外,还有一些更具体的特性
// 多态:由继承而产生了相关的不同的类,对同一个方法可以有不同的响应
class Animal {
speak(word: string): string {
return 'Animal: ' + word
}
}
class Cat extends Animal {
speak(word: string): string {
return 'Cat: ' + word
}
}
class Dog extends Animal {
speak(word: string): string {
return 'Dog: ' + word
}
}
let cat = new Cat()
console.log(cat.speak('hello'))
let dog = new Dog()
console.log(dog.speak('hello'))
还有一个 typeof class 的注意点:
typeof class 和直接用 class 作为类型有什么区别,改写一下 Animale:
class Animal {
static message = ' world'
speak(word: string): string {
return 'Animal: ' + word + Animal.message
}
}
// 获取的是实例的类型,该类型可以获取实例对象上的属性/方法
let animal1: Animal = new Animal()
console.log(animal1.speak('hello')) // 'Animal: hello world'
// 获取的是类的类型,该类型可以获取类上面的静态属性/方法
let animalTwo: typeof Animal = Animal
animalTwo.message = ' humen'
let animal2: Animal = new animalTwo()
console.log(animal2.speak('hello')) // 'Animal: hello humen'
Typescript是如何解决上述问题的?
优点:
缺点:
5.如何减少业务侧 升级到 ts 成本:
1.首先 升级到 ts 是一个渐进的过程
所以如果我们想使用TS 应该从 共存策略 开始,
共存策略: 即 JS 和 TS 共存,存在的 JS 文件,我们还可以配置 checkJs 决定对 js 文件是否进行类型检查。
{
"compilerOptions": {
"allowJs": true
// "checkJs": true,
}
}
宽松策略: 没有 JS 文件,但类型检查使用最宽松的模式。
{
"compilerOptions": {
"allowJs": fase,
"checkJs": false,
"strict": false
}
}
严格策略: 没有 JS 文件且 strict 为 true。
{
"compilerOptions": {
"strict": true
}
}
升级过程中的问题: 依赖也需要升级
如果你的依赖 是 JS 库,默认 TS 也不会报错。因为没有声明文件的 JS 模块会隐式的获得any类型,除非 tsconfig.json 中配置了 noImplicitAny: true ,指明了如有隐式转换为 any 类型就报错,才会报错。
6.社区发展:
前端在经过 Flow、Typescript、CoffeeScript 等短暂的类型检查之争后。Typescript 在开发速度、协作成本、维护成本上的出色表现,实践过 Typescript 构建大型应用的团队,几乎是一边倒的从JS转向了 TS。具有代表性的:Ant-design、Angular、Vue-next 从最初的 JS 版本切换到了 TS 版本。包括
看一下最近一年 typescript 的npm 包下载量。更多:npm-stat
2020-11-10 到 2021-11-10 的下载量:
package | downloads |
---|---|
typescript | 984,454,322 |
刚开始使用时,遇到的这些问题,都算是成本,但是解决之后,就变成我们的收益。
// 不能将类型“Timeout”分配给类型“number”。ts(2322)
let timer = 0
timer = setTimeout(() => {
console.log(10)
})
跳转到定义 发现setTimeout使用的是 Node.js 下的接口定义
// @types/node timer.d.ts
function setTimeout<TArgs extends any[]>(callback: (...args: TArgs) => void, ms?: number, ...args: TArgs): NodeJS.Timeout;
而在 typescript 中,window 下的 setTimeout 返回的是 number:
interface WindowOrWorkerGlobalScope {
...
clearInterval(handle?: number): void;
clearTimeout(handle?: number): void;
setInterval(handler: TimerHandler, timeout?: number, ...arguments: any[]): number;
setTimeout(handler: TimerHandler, timeout?: number, ...arguments: any[]): number;
}
所以我们要改成
timer = window.setTimeout(() => {
console.log(10)
})
// strictNullChecks:false
type final = fn extends Function ? 1 : 2 // 1 因为 undefined 可以赋值给 Function 类型。
// strictNullChecks:true
type final = fn extends Function ? 1 : 2 // 2
#### 4.指定 target 为 es6 时,tsc 就会默认使用 ["classic" 模块解析策略](https://www.typescriptlang.org/docs/handbook/module-resolution.html),这个策略对于非相对路径的导入,不能正确解析。
```js
import { dbridge, IDBridge } from '@didi/driver-bridge'
// 找不到模块“@didi/driver-bridge”。你的意思是要将 "moduleResolution" 选项设置为 "node",还是要将别名添加到 "paths" 选项中?ts(2792)
// 我们可以 在 tsconfig.ts 里配置一下
{
"compilerOptions": {
"target": "es6",
"moduleResolution": "node"
}
}
5.引入JSON文件的配置:resolveJsonModule
// tsconfig.ts { "compilerOptions": { "resolveJsonModule": true } }
{
"compilerOptions": {
"resolveJsonModule": true
}
}
这样就可以引入 json 文件了
因为TypeScript的性能太差了。
首先TypeScript需要类型检查,而类型检查就需要先把所有的源代码都下载完毕之后才能进行,毕竟编译器也不知道你引用的库究竟在什么文件中,甚至还要下载毫无用处的 d.ts 文件,这个只是纯粹的类型声明文件,对于程序的正常运行毫无帮助,额外的增加了流量支出。
1.interface 和 type 关键字
interface 的特点如下:
与 interface 相比,type 的特点如下:
一般只有这几种场景需要使用类型转换:自动推断不准;TS 报错,想不出更好的类型编写方法;临时使用;
类型转换的语法为 < 类型名> xxx 或 xxx as 类型名。
推荐始终用 as 语法,因为第一种语法无法在 tsx 文件使用,而且容易和泛型混淆。
3.类型体操
type-challenges
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.