我在 gitlab 中有一个带有角度前端和 nestjs 后端的 monorepo。我每个人都有 package.json ,根中有 1 个。我的管道由多个阶段组成,如下所示:
stages:
- build
- verify
- test
- deploy
Run Code Online (Sandbox Code Playgroud)
我在.pre安装依赖项的阶段有一份工作。我想在作业之间和分支之间缓存那些,如果有任何package-lock.json更改,但如果node_modules当前没有缓存。我有一份看起来像这样的工作:
prepare:
stage: .pre
script:
- npm run ci-deps # runs npm ci in each folder
cache:
key: $CI_PROJECT_ID
paths:
- node_modules/
- frontend/node_modules/
- backend/node_modules/
only:
changes:
- '**/package-lock.json'
Run Code Online (Sandbox Code Playgroud)
现在的问题是,如果缓存以某种方式被清除,或者如果我没有package-lock.json在第一次推送时引入更改,我将根本不会运行此作业,因此其他一切都会失败,因为它需要node_modules. 如果我changes:从那里删除,那么它会为每个管道运行作业。当然,我仍然可以在作业之间共享它,但是如果我再次提交并推送它需要近 2 分钟来安装所有依赖项,即使我没有更改任何关于应该存在的内容......我错过了什么吗?如何以某种方式缓存它,以便仅在缓存过时或不存在时才重新安装依赖项?
想象一下我们有界面
interface Foo {
bar: number | undefined;
}
Run Code Online (Sandbox Code Playgroud)
如果我们尝试创建Foo类型的对象,例如
const foo: Foo = {};
Run Code Online (Sandbox Code Playgroud)
由于缺少属性栏,因此无法编译。但是我们说它可以是未定义的,如果我们将它显式设置为undefined,它将起作用,但是,如果我们根本不将其设置为完全相同。它不应该与以下内容完全相同吗?
interface Foo {
bar?: number;
}
Run Code Online (Sandbox Code Playgroud)
对我来说,这是一个问题,因为如果考虑更复杂的示例,则我们具有与字段的接口,该字段可以通过泛型类型选择。像这样,如果未指定泛型类型,则字段应该是未定义的;如果已指定,则字段只能是该类型的。例如
interface Foo<T = undefined> {
bar: T;
title: string;
}
const foo1: Foo = {
title: 'TITLE'
};
const foo2: Foo<number> = {
title: 'title',
bar: 12
};
Run Code Online (Sandbox Code Playgroud)
foo1会因为缺少属性而无法编译,但是无论如何它都必须是未定义的,如果我们明确指定它,它将可以工作,但这是完全相同的。我最终通过继承解决了这个问题,在继承中基类没有任何泛型参数,而子代已对其进行了严格指定。但是我只是好奇是否有人知道用这种方式处理未定义类型的具体原因。因为我自己找不到任何信息。