> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Extends Reuse Configuration NodeJS Jobs

> Learn to reuse configuration in GitLab CI/CD pipelines using the extends keyword to eliminate duplication and streamline job definitions.

Learn how to eliminate duplication in your GitLab CI/CD pipelines by reusing configuration with the `extends` keyword. This guide covers three primary strategies:

| Method                 | Description                                       | Example                                     |
| ---------------------- | ------------------------------------------------- | ------------------------------------------- |
| `extends`              | Inherit settings from hidden jobs (templates)     | `.rspec` → `rspec 1`                        |
| YAML anchors & aliases | Reuse blocks of config (scripts, variables, etc.) | `&default_scripts` / `*default_scripts`     |
| Reference tags         | Share tags or other fields across multiple jobs   | `tags: &common_tags` / `tags: *common_tags` |

<Callout icon="lightbulb" color="#1CB2FE">
  You can combine `include` with `extends` to pull in templates from external files and inherit from them in one step.
</Callout>

## 1. Anchors & Aliases

Use YAML anchors to define reusable snippets:

```yaml theme={null}
.default_scripts: &default_scripts
  - ./default-script1.sh
  - ./default-script2.sh

job1:
  script:
    <<: *default_scripts
```

## 2. Using `extends`

Define hidden jobs (prefixed with a dot) as templates, then inherit from them:

```yaml theme={null}
.tests:
  rules:
    - if: $CI_PIPELINE_SOURCE == "push"

.rspec:
  extends: .tests
  script:
    - rake rspec

rspec 1:
  extends: .rspec
  variables:
    RSPEC_SUITE: '1'

rspec 2:
  extends: .rspec
  variables:
    RSPEC_SUITE: '2'
```

GitLab supports up to 11 inheritance levels, but keeping it under three levels is recommended:

<Callout icon="triangle-alert" color="#FF6B6B">
  Deep inheritance trees can become hard to maintain. Aim for 2–3 levels only.
</Callout>

### Multi-template Inheritance

You can merge multiple hidden jobs:

```yaml theme={null}
.only-important:
  variables:
    URL: "http://my-url.internal"
    IMPORTANT_VAR: "details"
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
    - if: $CI_COMMIT_BRANCH == "stable"
  tags:
    - production
  script:
    - echo "Hello world!"

.in-docker:
  image: alpine
  variables:
    URL: "http://docker-url.internal"
  tags:
    - docker

rspec:
  extends:
    - .only-important
    - .in-docker
  variables:
    GITLAB: "is-awesome"
  script:
    - rake rspec
```

## 3. Refactoring NodeJS Test Jobs

Imagine a pipeline where the **test** stage contains two nearly identical NodeJS jobs: `unit_testing` and `code_coverage`. To speed up feedback, other stages are commented out.

<Frame>
  ![The image shows a GitLab pipeline editor with a visual representation of a CI/CD pipeline, including stages like testing, containerization, and deployment.](https://kodekloud.com/kk-media/image/upload/v1752877367/notes-assets/images/GitLab-CICD-Architecting-Deploying-and-Optimizing-Pipelines-Extends-Reuse-Configuration-NodeJS-Jobs/gitlab-pipeline-ci-cd-editor.jpg)
</Frame>

Both jobs share the following configuration:

```yaml theme={null}
stage: test
image: node:17-alpine3.14
services:
  - name: siddharth67/mongo-db:non-prod
    alias: mongo
    pull_policy: always
variables:
  MONGO_URI: 'mongodb://mongo:27017/superData'
  MONGO_USERNAME: non-prod-user
  MONGO_PASSWORD: non-prod-password
cache:
  key:
    files:
      - package-lock.json
    prefix: node_modules
  policy: pull-push
  when: on_success
  paths:
    - node_modules
before_script:
  - npm install
```

### 3.1 Create a Hidden Template

Extract the shared configuration into a single hidden job:

```yaml theme={null}
.prepare_nodejs_environment:
  image: node:17-alpine3.14
  services:
    - name: siddharth67/mongo-db:non-prod
      alias: mongo
      pull_policy: always
  variables:
    MONGO_URI: 'mongodb://mongo:27017/superData'
    MONGO_USERNAME: non-prod-user
    MONGO_PASSWORD: non-prod-password
  cache:
    policy: pull-push
    when: on_success
    paths:
      - node_modules
    key:
      files:
        - package-lock.json
      prefix: node_modules
  before_script:
    - npm install
```

### 3.2 Refactor Job Definitions

Have both jobs inherit from the `.prepare_nodejs_environment` template:

```yaml theme={null}
unit_testing:
  stage: test
  extends: .prepare_nodejs_environment
  script:
    - npm test
  artifacts:
    when: always
    expire_in: 3 days
    name: Moca-Test-Results
    paths:
      - test-results.xml
    reports:
      junit: test-results.xml

code_coverage:
  stage: test
  extends: .prepare_nodejs_environment
  script:
    - npm run coverage
  artifacts:
    name: Code-Coverage-Report
    when: always
    expire_in: 3 days
    reports:
      coverage_report:
        coverage_format: cobertura
        path: coverage/cobertura-coverage.xml
  coverage: /All files[^|]*\|[^|]*\s+(\d+\.\d+)/
  allow_failure: true
```

## 4. Inspecting the Merged Configuration

GitLab’s **CI Lint** or **Full configuration** view will show the merged result for `unit_testing`:

```yaml theme={null}
unit_testing:
  image: node:17-alpine3.14
  services:
    - name: siddharth67/mongo-db:non-prod
      alias: mongo
      pull_policy: always
  variables:
    MONGO_URI: mongodb://mongo:27017/superData
    MONGO_USERNAME: non-prod-user
    MONGO_PASSWORD: non-prod-password
  cache:
    policy: pull-push
    when: on_success
    paths:
      - node_modules
    key:
      files:
        - package-lock.json
      prefix: node_modules
  before_script:
    - npm install
  script:
    - npm test
  artifacts:
    paths:
      - test-results.xml
```

## 5. Pipeline Execution

When you commit these changes, both `unit_testing` and `code_coverage` run in parallel with the shared setup:

```bash theme={null}
$ npm install
$ npm test
# …
Job succeeded
```

This approach centralizes maintenance: updating `.prepare_nodejs_environment` applies to all linked jobs.

***

For more on merging hidden jobs or combining `include` with `extends`, see the [GitLab CI/CD documentation on `extends`](https://docs.gitlab.com/ee/ci/yaml/#extends).

## Links and References

* [Optimizing GitLab CI/CD configuration](https://docs.gitlab.com/ee/ci/yaml/#extends)
* [GitLab CI/CD YAML Reference](https://docs.gitlab.com/ee/ci/yaml/)
* [GitLab Includes](https://docs.gitlab.com/ee/ci/yaml/includes.html)

<CardGroup>
  <Card title="Watch Video" icon="video" cta="Learn more" href="https://learn.kodekloud.com/user/courses/gitlab-ci-cd-architecting-deploying-and-optimizing-pipelines/module/1573bc2e-563a-424a-a558-2081416601b3/lesson/e2b230b7-2726-4bf3-8769-ba01843b5272" />
</CardGroup>
