Either remove this import or add it as a dependency. S4328

Must-share information (formatted with Markdown):

  • SonarQube version: Community Build v24.12.0.100206
  • Scanner/deployment method: Configuration through Docker pipeline
  • What I’m trying to achieve: Resolve TypeScript path alias @/ in my Vite project so that SonarQube does not raise false-positive dependency errors
  • What I’ve tried so far:
    • Configured my pipeline to add node: image: node:20.17.0
    • Added a tsconfig.app.json with the correct alias setup
    • Set sonar.typescript.tsconfigPaths=tsconfig.app.json in sonar-project.properties
    • Verified that the pipeline log shows SonarQube detects and reads this file
    • I tried many different baseUrl and paths combinations if that was causing the error.

Despite this, SonarQube fails to resolve the @/ alias, and I keep getting the following error on all such imports:

Either remove this import or add it as a dependency. [S4328]

The relevant tsconfig.app.json looks like this:

{
  "extends": "@vue/tsconfig/tsconfig.dom.json",
  "compilerOptions": {
    "composite": true,
    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
    "baseUrl": "./src",
    "paths": {
      "@/*": ["*"]
    },
    "verbatimModuleSyntax": false
  }
}

Is there anything I might be missing in the configuration to make SonarQube resolve the alias properly?

Thank you!

Hi,

The only supported version of Community Build is the latest release. I doubt it will have an impact, but could you help me dot the i’s by taking the upgrade and trying again?

 
Thx,
Ann

Thanks for the quick reply.

Unfortunately, I’m not able to perform the upgrade myself, as I’m working within a larger project where upgrades are managed centrally. I initially assumed others might be facing the same issue, but that doesn’t appear to be the case.

At this point, I’m at a bit of a dead end in figuring out what’s causing the problem, despite trying several configurations. Any suggestions for further debugging would be greatly appreciated.

Hi @RonWk ,

are dependencies installed during analysis? As that tsconfig is extending another one from node_modules, it needs to be present. Can you please confirm you are running npm ci before analysis?

Cheers

Thank you,

Yes i’m running ‘yarn’. In my pipeline it confirms the installation:

+ yarn
yarn install v1.22.22
[1/4] Resolving packages...
success Already up-to-date.
Done in 0.71s.

Thanks

Hi @RonWk,

can you please share the full debug logs of the analysis?

The full log in my pipeline:

yarn
<1s
+ yarn
yarn install v1.22.22
[1/4] Resolving packages...
warning Resolution field "strip-ansi@6.0.1" is incompatible with requested version "strip-ansi@^7.0.1"
warning Resolution field "strip-ansi@6.0.1" is incompatible with requested version "strip-ansi@^7.0.1"
warning Resolution field "strip-ansi@6.0.1" is incompatible with requested version "strip-ansi@^7.0.1"
success Already up-to-date.
Done in 0.71s.
export SONAR_SCANNER_OPTS="-Dsonar.verbose=true"
<1s
+ export SONAR_SCANNER_OPTS="-Dsonar.verbose=true"
pipe: sonarsource/sonarqube-scan:3.0.2
1m 28s
+ docker container run \
   --volume=/opt/atlassian/pipelines/agent/build:/opt/atlassian/pipelines/agent/build \
   --volume=/opt/atlassian/pipelines/agent/ssh:/opt/atlassian/pipelines/agent/ssh:ro \
   --volume=/opt/atlassian/pipelines/bin/docker:/usr/local/bin/docker:ro \
   --volume=/opt/atlassian/pipelines/agent/build/.bitbucket/pipelines/generated/pipeline/pipes:/opt/atlassian/pipelines/agent/build/.bitbucket/pipelines/generated/pipeline/pipes \
   --volume=/opt/atlassian/pipelines/agent/build/.bitbucket/pipelines/generated/pipeline/pipes/sonarsource/sonarqube-scan:/opt/atlassian/pipelines/agent/build/.bitbucket/pipelines/generated/pipeline/pipes/sonarsource/sonarqube-scan \
   --workdir=$(pwd) \
   --label=org.bitbucket.pipelines.system=true \
   --env=BITBUCKET_STEP_TRIGGERER_UUID="$BITBUCKET_STEP_TRIGGERER_UUID" \
   --env=BITBUCKET_REPO_FULL_NAME="$BITBUCKET_REPO_FULL_NAME" \
   --env=BITBUCKET_GIT_HTTP_ORIGIN="$BITBUCKET_GIT_HTTP_ORIGIN" \
   --env=BITBUCKET_PROJECT_UUID="$BITBUCKET_PROJECT_UUID" \
   --env=BITBUCKET_REPO_IS_PRIVATE="$BITBUCKET_REPO_IS_PRIVATE" \
   --env=BITBUCKET_WORKSPACE="$BITBUCKET_WORKSPACE" \
   --env=BITBUCKET_SSH_KEY_FILE="$BITBUCKET_SSH_KEY_FILE" \
   --env=BITBUCKET_REPO_OWNER_UUID="$BITBUCKET_REPO_OWNER_UUID" \
   --env=BITBUCKET_BRANCH="$BITBUCKET_BRANCH" \
   --env=BITBUCKET_REPO_UUID="$BITBUCKET_REPO_UUID" \
   --env=BITBUCKET_PROJECT_KEY="$BITBUCKET_PROJECT_KEY" \
   --env=BITBUCKET_REPO_SLUG="$BITBUCKET_REPO_SLUG" \
   --env=CI="$CI" \
   --env=BITBUCKET_REPO_OWNER="$BITBUCKET_REPO_OWNER" \
   --env=BITBUCKET_STEP_RUN_NUMBER="$BITBUCKET_STEP_RUN_NUMBER" \
   --env=BITBUCKET_BUILD_NUMBER="$BITBUCKET_BUILD_NUMBER" \
   --env=BITBUCKET_GIT_SSH_ORIGIN="$BITBUCKET_GIT_SSH_ORIGIN" \
   --env=BITBUCKET_PIPELINE_UUID="$BITBUCKET_PIPELINE_UUID" \
   --env=BITBUCKET_PIPELINES_VARIABLES_PATH="$BITBUCKET_PIPELINES_VARIABLES_PATH" \
   --env=BITBUCKET_COMMIT="$BITBUCKET_COMMIT" \
   --env=BITBUCKET_CLONE_DIR="$BITBUCKET_CLONE_DIR" \
   --env=PIPELINES_JWT_TOKEN="$PIPELINES_JWT_TOKEN" \
   --env=BITBUCKET_STEP_UUID="$BITBUCKET_STEP_UUID" \
   --env=BITBUCKET_DOCKER_HOST_INTERNAL="$BITBUCKET_DOCKER_HOST_INTERNAL" \
   --env=DOCKER_HOST="tcp://host.docker.internal:2375" \
   --env=BITBUCKET_PIPE_SHARED_STORAGE_DIR="/opt/atlassian/pipelines/agent/build/.bitbucket/pipelines/generated/pipeline/pipes" \
   --env=BITBUCKET_PIPE_STORAGE_DIR="/opt/atlassian/pipelines/agent/build/.bitbucket/pipelines/generated/pipeline/pipes/sonarsource/sonarqube-scan" \
   --env=SONAR_HOST_URL="${SONAR_HOST_URL}" \
   --env=SONAR_TOKEN="${SONAR_TOKEN}" \
   --add-host="host.docker.internal:$BITBUCKET_DOCKER_HOST_INTERNAL" \
   sonarsource/sonarqube-scan:3.0.2
Unable to find image 'sonarsource/sonarqube-scan:3.0.2' locally
3.0.2: Pulling from sonarsource/sonarqube-scan
9a0f8ca95549: Pulling fs layer
f6c81cf32813: Pulling fs layer
ef33d0945dc7: Pulling fs layer
30102dc55d4b: Pulling fs layer
4a7c91ac5b9c: Pulling fs layer
4f4fb700ef54: Pulling fs layer
b60206180702: Pulling fs layer
210ef10c39ca: Pulling fs layer
4a7c91ac5b9c: Waiting
4f4fb700ef54: Waiting
b60206180702: Waiting
210ef10c39ca: Waiting
30102dc55d4b: Waiting
ef33d0945dc7: Verifying Checksum
ef33d0945dc7: Download complete
9a0f8ca95549: Verifying Checksum
9a0f8ca95549: Download complete
4a7c91ac5b9c: Verifying Checksum
4a7c91ac5b9c: Download complete
4f4fb700ef54: Verifying Checksum
4f4fb700ef54: Download complete
b60206180702: Verifying Checksum
b60206180702: Download complete
210ef10c39ca: Verifying Checksum
210ef10c39ca: Download complete
f6c81cf32813: Verifying Checksum
f6c81cf32813: Download complete
30102dc55d4b: Verifying Checksum
30102dc55d4b: Download complete
9a0f8ca95549: Pull complete
f6c81cf32813: Pull complete
ef33d0945dc7: Pull complete
30102dc55d4b: Pull complete
4a7c91ac5b9c: Pull complete
4f4fb700ef54: Pull complete
b60206180702: Pull complete
210ef10c39ca: Pull complete
Digest: sha256:4ad1c6ebb590502133e68c4dbb7972e3655dddb426faa7b476cb3ac22a2467de
Status: Downloaded newer image for sonarsource/sonarqube-scan:3.0.2
14:45:29.639 INFO  Scanner configuration file: /opt/sonar-scanner/conf/sonar-scanner.properties
14:45:29.645 INFO  Project root configuration file: /opt/atlassian/pipelines/agent/build/sonar-project.properties
14:45:29.674 INFO  SonarScanner CLI 6.2.1.4610
14:45:29.678 INFO  Java 17.0.12 Amazon.com Inc. (64-bit)
14:45:29.680 INFO  Linux 6.1.79 amd64
14:45:29.730 INFO  User cache: /opt/sonar-scanner/.sonar/cache
14:45:31.694 INFO  JRE provisioning: os[linux], arch[x86_64]
14:45:37.526 INFO  Communicating with SonarQube Server 24.12.0.100206
14:45:38.110 INFO  Starting SonarScanner Engine...
14:45:38.114 INFO  Java 17.0.11 Eclipse Adoptium (64-bit)
14:45:40.146 INFO  Load global settings
14:45:40.870 INFO  Load global settings (done) | time=724ms
14:45:40.881 INFO  Server id: BC418598-AVkCZ6MhebAXY9k0By15
14:45:40.915 INFO  Loading required plugins
14:45:40.917 INFO  Load plugins index
14:45:41.022 INFO  Load plugins index (done) | time=105ms
14:45:41.025 INFO  Load/download plugins
14:45:47.518 INFO  Load/download plugins (done) | time=6493ms
14:45:48.805 INFO  Process project properties
14:45:48.821 INFO  Process project properties (done) | time=16ms
14:45:48.839 INFO  Project key: **-frontend
14:45:48.843 INFO  Base dir: /opt/atlassian/pipelines/agent/build
14:45:48.846 INFO  Working dir: /opt/atlassian/pipelines/agent/build/.scannerwork
14:45:48.872 INFO  Load project settings for component key: '**-frontend'
14:45:48.961 INFO  Load project settings for component key: '**-frontend' (done) | time=88ms
14:45:49.124 INFO  Load project branches
14:45:49.215 INFO  Load project branches (done) | time=91ms
14:45:49.218 INFO  Load branch configuration
14:45:49.230 INFO  Auto detected BRANCH configuration with source ORANGE-785 using com.github.mc1arke.sonarqube.plugin.scanner.autoconfiguration.BitbucketPipelinesAutoConfigurer
14:45:49.231 INFO  Load branch configuration (done) | time=12ms
14:45:49.279 INFO  Load quality profiles
14:45:49.446 INFO  Load quality profiles (done) | time=167ms
14:45:49.474 INFO  Auto-configuring with CI 'Bitbucket Pipelines'
14:45:49.568 INFO  Load active rules
14:45:53.500 INFO  Load active rules (done) | time=3936ms
14:45:53.520 INFO  Load analysis cache
14:45:53.640 INFO  Load analysis cache | time=120ms
14:45:53.828 INFO  Branch name: ORANGE-785
14:45:53.881 INFO  Preprocessing files...
14:45:54.365 INFO  2 languages detected in 158 preprocessed files
14:45:54.366 INFO  0 files ignored because of inclusion/exclusion patterns
14:45:54.368 INFO  0 files ignored because of scm ignore settings
14:45:54.377 INFO  Loading plugins for detected languages
14:45:54.379 INFO  Load/download plugins
14:45:58.114 INFO  Load/download plugins (done) | time=3735ms
14:45:58.548 INFO  Load project repositories
14:45:58.652 INFO  Load project repositories (done) | time=104ms
14:45:58.721 INFO  Indexing files...
14:45:58.724 INFO  Project configuration:
14:45:58.726 INFO    Excluded sources: **/AssemblyInfo.cs
14:45:59.250 INFO  158 files indexed
14:45:59.254 INFO  Quality profile for js: Sonar way Recommended (deprecated)
14:45:59.259 INFO  Quality profile for ts: Sonar way Recommended (deprecated)
14:45:59.261 INFO  ------------- Run sensors on module **-frontend
14:45:59.402 INFO  Load metrics repository
14:45:59.495 INFO  Load metrics repository (done) | time=93ms
14:46:00.408 INFO  Sensor JaCoCo XML Report Importer [jacoco]
14:46:00.413 INFO  'sonar.coverage.jacoco.xmlReportPaths' is not defined. Using default locations: target/site/jacoco/jacoco.xml,target/site/jacoco-it/jacoco.xml,build/reports/jacoco/test/jacocoTestReport.xml
14:46:00.417 INFO  No report imported, no coverage information will be imported by JaCoCo XML Report Importer
14:46:00.421 INFO  Sensor JaCoCo XML Report Importer [jacoco] (done) | time=13ms
14:46:00.422 INFO  Sensor Java Config Sensor [iac]
14:46:00.467 INFO  0 source files to be analyzed
14:46:00.483 INFO  0/0 source files have been analyzed
14:46:00.489 INFO  Sensor Java Config Sensor [iac] (done) | time=65ms
14:46:00.490 INFO  Sensor JavaScript/TypeScript analysis [javascript]
14:46:00.789 INFO  Detected os: Linux arch: amd64 alpine: false. Platform: LINUX_X64
14:46:00.793 INFO  Deploy location /opt/sonar-scanner/.sonar/js/node-runtime, tagetRuntime: /opt/sonar-scanner/.sonar/js/node-runtime/node,  version: /opt/sonar-scanner/.sonar/js/node-runtime/version.txt
14:46:06.052 INFO  Using embedded Node.js runtime.
14:46:06.053 INFO  Using Node.js executable: '/opt/sonar-scanner/.sonar/js/node-runtime/node'.
14:46:08.956 INFO  Memory configuration: OS (6096 MB), Node.js (2096 MB).
14:46:11.956 INFO  Resolving TSConfig files using 'tsconfig.app.json' from property sonar.typescript.tsconfigPaths
14:46:11.958 INFO  Found 1 TSConfig file(s): [/opt/atlassian/pipelines/agent/build/tsconfig.app.json]
14:46:11.963 INFO  Creating TypeScript program
14:46:11.965 INFO  TypeScript configuration file /opt/atlassian/pipelines/agent/build/tsconfig.app.json
14:46:11.971 INFO  143 source files to be analyzed
14:46:15.665 INFO  Starting analysis with current program
14:46:21.975 INFO  60/143 files analyzed, current file: src/router/index.ts
14:46:27.710 INFO  Analyzed 143 file(s) with current program
14:46:27.722 INFO  143/143 source files have been analyzed
14:46:27.732 INFO  Hit the cache for 0 out of 143
14:46:27.745 INFO  Miss the cache for 143 out of 143: ANALYSIS_MODE_INELIGIBLE [143/143]
14:46:27.747 INFO  Sensor JavaScript/TypeScript analysis [javascript] (done) | time=27260ms
14:46:27.749 INFO  Sensor CSS Rules [javascript]
14:46:27.780 INFO  64 source files to be analyzed
14:46:28.641 INFO  64/64 source files have been analyzed
14:46:28.642 INFO  Hit the cache for 0 out of 0
14:46:28.643 INFO  Miss the cache for 0 out of 0
14:46:28.643 INFO  Sensor CSS Rules [javascript] (done) | time=893ms
14:46:28.644 INFO  Sensor HTML [web]
14:46:29.273 INFO  Sensor HTML [web] (done) | time=631ms
14:46:29.274 INFO  Sensor com.github.mc1arke.sonarqube.plugin.scanner.ScannerPullRequestPropertySensor
14:46:29.276 INFO  Sensor com.github.mc1arke.sonarqube.plugin.scanner.ScannerPullRequestPropertySensor (done) | time=2ms
14:46:29.276 INFO  Sensor IaC Docker Sensor [iac]
14:46:30.120 INFO  0 source files to be analyzed
14:46:30.121 INFO  0/0 source files have been analyzed
14:46:30.123 INFO  Sensor IaC Docker Sensor [iac] (done) | time=845ms
14:46:30.128 INFO  Sensor TextAndSecretsSensor [text]
14:46:30.129 INFO  Available processors: 2
14:46:30.130 INFO  Using 2 threads for analysis.
14:46:31.399 INFO  The property "sonar.tests" is not set. To improve the analysis accuracy, we categorize a file as a test file if any of the following is true:
  * The filename starts with "test"
  * The filename contains "test." or "tests."
  * Any directory in the file path is named: "doc", "docs", "test" or "tests"
  * Any directory in the file path has a name ending in "test" or "tests"
14:46:31.439 INFO  Using git CLI to retrieve untracked files
14:46:31.445 WARN  Analyzing only language associated files, make sure to run the analysis inside a git repository to make use of inclusions specified via "sonar.text.inclusions"
14:46:31.499 INFO  143 source files to be analyzed
14:46:32.029 INFO  143/143 source files have been analyzed
14:46:32.030 INFO  Sensor TextAndSecretsSensor [text] (done) | time=1909ms
14:46:32.105 INFO  ------------- Run sensors on project
14:46:32.377 INFO  Sensor Zero Coverage Sensor
14:46:32.426 INFO  Sensor Zero Coverage Sensor (done) | time=48ms
14:46:32.489 INFO  CPD Executor 45 files had no CPD blocks
14:46:32.490 INFO  CPD Executor Calculating CPD for 98 files
14:46:32.571 INFO  CPD Executor CPD calculation finished (done) | time=78ms
14:46:32.580 INFO  SCM revision ID 'c35fe02b20cec591604ba99d782ae8f18b064078'
14:46:32.945 INFO  Load New Code definition
14:46:33.225 INFO  Load New Code definition (done) | time=280ms
14:46:33.251 INFO  Analysis report generated in 654ms, dir size=957.7 kB
14:46:33.845 INFO  Analysis report compressed in 593ms, zip size=568.6 kB
14:46:34.555 INFO  Analysis report uploaded in 709ms
14:46:34.559 INFO  ANALYSIS SUCCESSFUL, you can find the results at: 
14:46:34.560 INFO  Note that you will be able to access the updated dashboard once the server has processed the submitted analysis report
14:46:34.560 INFO  More about the report processing at
14:46:34.733 INFO  Analysis total time: 46.610 s
14:46:34.738 INFO  SonarScanner Engine completed successfully
14:46:35.097 INFO  EXECUTION SUCCESS
14:46:35.103 INFO  Total time: 1:05.465s

Hi @RonWk,

thank you for the logs, seem the tsconfig.app.json file has no issues and is properly used for the analysis. Would it be possible for you to provide a minimum reproducer where you still get the issue raised when it should not. I’m not able to reproduce it locally.

Cheers,
Victor

One example of an error in sonarqube, resulting into Dependencies should be explicit[typescript:S4328]:

import { Event } from '@/services/tracking/event';
Either remove this import or add it as a dependency.

The project structure looks like src/services/tracking/event, so the @ should be replaced by src.

I’m part of a large project. Maybe we have some custom integration?

Hello @RonWk,

here is how I’m trying to reproduce:

src/services/tracking/event/index.ts contents:

export class Event {
  
}

src/file.ts contents:

import { Event } from '@/services/tracking/event';

/tsconfig.json contents:

{
  "compilerOptions": {
    "composite": true,
    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
    "baseUrl": "./src",
    "paths": {
      "@/*": ["*"]
    },
    "verbatimModuleSyntax": false
  },
  "include": ["./"]
}

Nothing is raised. If I change the import in file.ts to something like

import { Event } from '@/nonexistent/tracking/event';

then the rule raises an issue as expected.

The only difference between my test and your codebase is the extension of vue tsconfig.json. So I’m really not sure what or where is the problem.

This rule S4328 is also included in our ESLint plugin. Are you using ESLint locally to test the rule directly? Note that the rule is not part of the recommended profile and you would need to enable it explicitly using some custom config like

import sonarjs from 'eslint-plugin-sonarjs';
export default [
  {
    plugins: { sonarjs },
    rules: {
      'sonarjs/no-implicit-dependencies': 'error',
    },
  },
];

My scenario is little bit different:

Could you add an event.ts file to your tracking folder. And inside this folder

export class Event{}

I tried the exact same config as you have, still results in same error.

Hi @RonWk,

did you try with our ESLint plugin enabling the rule see if you still have the same behavior?

Thanks again for your quick reply!
I’m sorry to ask, but do I have to enable this plugin inside SonarQube? Or should I add some more configuration to my sonar-project.properties, or install it as dependency in my project?

Hi @RonWk,

ESLint is a linter used by the community for which we provide rules. It’s not related to the SonarQube analysis. If you are not using ESLint, you can ignore my previous question.

Can you instead create a new tsconfig.sonar.json with the same contents as your but removing this line?

  "extends": "@vue/tsconfig/tsconfig.dom.json",

Then use the property sonar.typescript.tsconfigPaths=tsconfig.sonar.json

I just want to make sure Vue defaults are not affecting our resolution.

I’m sorry, I think i was not clear in my previous answer. But I did the same config as you. I already removed this line "extends": "@vue/tsconfig/tsconfig.dom.json" resulting in same error…

You don’t get any errors if you work with event.ts exporting an Event class?

Correct, I get no raised issues with this file structure neither:

Can you try copying my very minimal reproducer and see if it also raises? Possible there is some other resolution being done by TypeScript with your other files.

Do you see the issue in SonarQube for IDE (if you are using it)?

I did a few more tests, one with the empty project which resolved everything as it should be.

Attached some screenshots of my existing project with both imports which are resolving, and returning the typescript:S4328 error.

export class Event<T> {}

export enum NotificationType {
}

export interface NotificationMessage {
}

export const useNotificationStore: StoreDefinition = defineStore('notification', () => {})

Hello @RonWk,

We will need a minimum reproducer to see where the rule is failing. There seems to be something in your project which is making the rule raise an FP, but if we cannot reproduce it we cannot investigate what is the problem.

Please let us know if you can provide such a reproducer.

Thanks!

I found a minimum reproducer, I didn’t thought about the specific file extensions…

Please add a test.vue file to your project with following contents and run again:

<script setup lang="ts">
import { Event } from '@/services/tracking/event';
</script>

<template>
    <p>Hello world</p>
</template>

This vue file will probably return my S4328 error.

1 Like

Hello @RonWk,

thank you very much for reducing the scope. Now it’s clear to us why this is happening: We don’t use the TypeScript resolution for Vue files due to performance issues. You can see in the rule implementation that we will not raise an issue if Typescript is able to resolve the import, but that condition will not be checked in Vue files.

Please report as FP in the UI. We created a ticket to handle this.

Thanks again!
Victor