Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-10-24 21:11:45 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-10-24 21:11:45 +0300
commit4bb797f25563205cf495f4dd5366e037e88831ab (patch)
treea345ddbd0e2464067323d3c6fd34960607ef4f44 /doc/development
parent40a4f37126bb1a1dd6b6f4b3c0ebb414a3e3908a (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'doc/development')
-rw-r--r--doc/development/fe_guide/style/typescript.md109
-rw-r--r--doc/development/internal_analytics/internal_event_instrumentation/local_setup_and_debugging.md53
2 files changed, 141 insertions, 21 deletions
diff --git a/doc/development/fe_guide/style/typescript.md b/doc/development/fe_guide/style/typescript.md
index 9497a0742e7..529459097b4 100644
--- a/doc/development/fe_guide/style/typescript.md
+++ b/doc/development/fe_guide/style/typescript.md
@@ -1,6 +1,7 @@
---
-stage: Create
-group: Editor Extensions
+type: reference, dev
+stage: none
+group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
---
@@ -28,27 +29,79 @@ The following GitLab projects use TypeScript:
- [`gitlab-language-server-for-code-suggestions`](https://gitlab.com/gitlab-org/editor-extensions/gitlab-language-server-for-code-suggestions)
- [`gitlab-org/cluster-integration/javascript-client`](https://gitlab.com/gitlab-org/cluster-integration/javascript-client)
-## Recommended configurations
+## Recommendations
-The [GitLab Workflow Extension](https://gitlab.com/gitlab-org/gitlab-vscode-extension/-/blob/main) project is a good model
-for a project's TypeScript configuration. Consider copying the `.tsconfig` and `.eslintrc.json` from there.
+### Setup ESLint and TypeScript configuration
-- In `.tsconfig`, make sure [`"strict": true`](https://www.typescriptlang.org/tsconfig#strict) is set.
-- In `.eslintrc.json`, make sure that TypeScript-specific parsing and linting is placed in an `overrides` for `**/*.ts` files.
+When setting up a new TypeScript project, configure strict type-safety rules for
+ESLint and TypeScript. This ensures that the project remains as type-safe as possible.
-## Future plans
+The [GitLab Workflow Extension](https://gitlab.com/gitlab-org/gitlab-vscode-extension/)
+project is a good model for a TypeScript project's boilerplate and configuration.
+Consider copying the `tsconfig.json` and `.eslintrc.json` from there.
-- Shared ESLint configuration to reuse across TypeScript projects.
+For `tsconfig.json`:
+
+- Use [`"strict": true`](https://www.typescriptlang.org/tsconfig#strict).
+ This enforces the strongest type-checking capabilities in the project and
+ prohibits overriding type-safety.
+- Use [`"skipLibCheck": true`](https://www.typescriptlang.org/tsconfig#skipLibCheck).
+ This improves compile time by only checking references `.d.ts`
+ files as opposed to all `.d.ts` files in `node_modules`.
+
+For `.eslintrc.json` (or `.eslintrc.js`):
+
+- Make sure that TypeScript-specific parsing and linting are placed in an `overrides`
+ for `**/*.ts` files. This way, linting regular `.js` files
+ remains unaffected by the TypeScript-specific rules.
+- Extend from [`plugin:@typescript-eslint/recommended`](https://typescript-eslint.io/rules?supported-rules=recommended)
+ which has some very sensible defaults, such as:
+ - [`"@typescript-eslint/no-explicit-any": "error"`](https://typescript-eslint.io/rules/no-explicit-any/)
+ - [`"@typescript-eslint/no-unsafe-assignment": "error"`](https://typescript-eslint.io/rules/no-unsafe-assignment/)
+ - [`"@typescript-eslint/no-unsafe-return": "error"`](https://typescript-eslint.io/rules/no-unsafe-return)
+
+### Avoid `any`
+
+Avoid `any` at all costs. This should already be configured in the project's linter,
+but it's worth calling out here.
+
+Developers commonly resort to `any` when dealing with data structures that cross
+domain boundaries, such as handling HTTP responses or interacting with untyped
+libraries. This appears convenient at first. However, opting for a well-defined type (or using
+`unknown` and employing type narrowing through predicates) carries substantial benefits.
+
+```typescript
+// Bad :(
+function handleMessage(data: any) {
+ console.log("We don't know what data is. This could blow up!", data.special.stuff);
+}
+
+// Good :)
+function handleMessage(data: unknown) {
+ console.log("Sometimes it's okay that it remains unknown.", JSON.stringify(data));
+}
+
+// Also good :)
+function isFooMessage(data: unknown): data is { foo: string } {
+ return typeof data === 'object' && data && 'foo' in data;
+}
-## Recommended patterns
+function handleMessage(data: unknown) {
+ if (isFooMessage(data)) {
+ console.log("We know it's a foo now. This is safe!", data.foo);
+ }
+}
+```
### Avoid casting with `<>` or `as`
-Avoid casting with `<>` or `as` as much as possible. This circumvents Type safety. Consider using
+Avoid casting with `<>` or `as` as much as possible.
+
+Type casting explicitly circumvents type-safety. Consider using
[type predicates](https://www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates).
```typescript
-// Bad
+// Bad :(
function handler(data: unknown) {
console.log((data as StuffContainer).stuff);
}
@@ -72,22 +125,34 @@ function handler(data: unknown) {
```
-### Prefer `interface` over `type` for new interfaces
+There's some rare cases this might be acceptable (consider
+[this test utility](https://gitlab.com/gitlab-org/gitlab-web-ide/-/blob/3ea8191ed066811caa4fb108713e7538b8d8def1/packages/vscode-extension-web-ide/test-utils/createFakePartial.ts#L1)). However, 99% of the
+time, there's a better way.
+
+### Prefer `interface` over `type` for new structures
-Prefer interface over type declaration when describing structures.
+Prefer declaring a new `interface` over declaring a new `type` alias when defining new structures.
+
+Interfaces and type aliases have a lot of cross-over, but only interfaces can be used
+with the `implements` keyword. A class is not able to `implement` a `type` (only an `interface`),
+so using `type` would restrict the usability of the structure.
```typescript
-// Bad
+// Bad :(
type Fooer = {
foo: () => string;
}
-// Good
+// Good :)
interface Fooer {
foo: () => string;
}
```
+From the [TypeScript guide](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#differences-between-type-aliases-and-interfaces):
+
+> If you would like a heuristic, use `interface` until you need to use features from `type`.
+
### Use `type` to define aliases for existing types
Use type to define aliases for existing types, classes or interfaces. Use
@@ -101,21 +166,21 @@ interface Config = {
isBad: boolean;
}
-// Bad
+// Bad :(
type PartialConfig = {
foo?: string;
isBad?: boolean;
}
-// Good
+// Good :)
type PartialConfig = Partial<Config>;
```
### Use union types to improve inference
```typescript
-// Bad
+// Bad :(
interface Foo { type: string }
interface FooBar extends Foo { bar: string }
interface FooZed extends Foo { zed: string }
@@ -128,7 +193,7 @@ const doThing = (foo: Foo) => {
}
// Good :)
-interface FooBar { type: 'bar', bar: string };
+interface FooBar { type: 'bar', bar: string }
interface FooZed { type: 'zed', zed: string }
type Foo = FooBar | FooZed;
@@ -140,6 +205,10 @@ const doThing = (foo: Foo) => {
}
```
+## Future plans
+
+- Shared ESLint configuration to reuse across TypeScript projects.
+
## Related topics
- [TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/intro.html)
diff --git a/doc/development/internal_analytics/internal_event_instrumentation/local_setup_and_debugging.md b/doc/development/internal_analytics/internal_event_instrumentation/local_setup_and_debugging.md
index d68e5565775..d9f45a2d93e 100644
--- a/doc/development/internal_analytics/internal_event_instrumentation/local_setup_and_debugging.md
+++ b/doc/development/internal_analytics/internal_event_instrumentation/local_setup_and_debugging.md
@@ -14,7 +14,7 @@ Internal events are using a tool called Snowplow under the hood. To develop and
| Snowplow Micro | Yes | Yes | Yes | No | No |
For local development you will have to either [setup a local event collector](#setup-local-event-collector) or [configure a remote event collector](#configure-a-remote-event-collector).
-We recommend the local setup when actively developing new events.
+We recommend using the local setup together with the [internal events monitor](#internal-events-monitor) when actively developing new events.
## Setup local event collector
@@ -68,6 +68,57 @@ You can configure your self-managed GitLab instance to use a custom Snowplow col
1. Select **Save changes**.
+## Internal Events Monitor
+
+<div class="video-fallback">
+ Watch the demo video about the <a href="https://www.youtube.com/watch?v=R7vT-VEzZOI">Internal Events Tracking Monitor</a>
+</div>
+<figure class="video_container">
+ <iframe src="https://www.youtube-nocookie.com/embed/R7vT-VEzZOI" frameborder="0" allowfullscreen="true"> </iframe>
+</figure>
+
+To understand how events are triggered and metrics are updated while you use the Rails app locally or `rails console`,
+you can use the monitor.
+
+Start the monitor and list one or more events that you would like to monitor. In this example we would like to monitor `i_code_review_user_create_mr`.
+
+```shell
+rails runner scripts/internal_events/monitor.rb i_code_review_user_create_mr
+```
+
+The monitor shows two tables. The top table lists all the metrics that are defined on the `i_code_review_user_create_mr` event.
+The second right-most column shows the value of each metric when the monitor was started and the right most column shows the current value of each metric.
+The bottom table has a list selected properties of all Snowplow events that matches the event name.
+
+If a new `i_code_review_user_create_mr` event is fired, the metrics values will get updated and a new event will appear in the `SNOWPLOW EVENTS` table.
+
+The monitor looks like below.
+
+```plaintext
+Updated at 2023-10-11 10:17:59 UTC
+Monitored events: i_code_review_user_create_mr
+
++--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| RELEVANT METRICS |
++-----------------------------------------------------------------------------+------------------------------+-----------------------+---------------+---------------+
+| Key Path | Monitored Events | Instrumentation Class | Initial Value | Current Value |
++-----------------------------------------------------------------------------+------------------------------+-----------------------+---------------+---------------+
+| counts_monthly.aggregated_metrics.code_review_category_monthly_active_users | i_code_review_user_create_mr | AggregatedMetric | 13 | 14 |
+| counts_monthly.aggregated_metrics.code_review_group_monthly_active_users | i_code_review_user_create_mr | AggregatedMetric | 13 | 14 |
+| counts_weekly.aggregated_metrics.code_review_category_monthly_active_users | i_code_review_user_create_mr | AggregatedMetric | 0 | 1 |
+| counts_weekly.aggregated_metrics.code_review_group_monthly_active_users | i_code_review_user_create_mr | AggregatedMetric | 0 | 1 |
+| redis_hll_counters.code_review.i_code_review_user_create_mr_monthly | i_code_review_user_create_mr | RedisHLLMetric | 8 | 9 |
+| redis_hll_counters.code_review.i_code_review_user_create_mr_weekly | i_code_review_user_create_mr | RedisHLLMetric | 0 | 1 |
++-----------------------------------------------------------------------------+------------------------------+-----------------------+---------------+---------------+
++---------------------------------------------------------------------------------------------------------+
+| SNOWPLOW EVENTS |
++------------------------------+--------------------------+---------+--------------+------------+---------+
+| Event Name | Collector Timestamp | user_id | namespace_id | project_id | plan |
++------------------------------+--------------------------+---------+--------------+------------+---------+
+| i_code_review_user_create_mr | 2023-10-11T10:17:15.504Z | 29 | 93 | | default |
++------------------------------+--------------------------+---------+--------------+------------+---------+
+```
+
## Snowplow Analytics Debugger Chrome Extension
[Snowplow Analytics Debugger](https://chrome.google.com/webstore/detail/snowplow-analytics-debugg/jbnlcgeengmijcghameodeaenefieedm) is a browser extension for testing frontend events.