SonarQube-Scanner fails to analyze Vue files - Failed to parse file [.vue]

Hi,

i’m currently reviewing SonarQube for my employer and i’m struggling to get the analysis working correctly.
Because i’m entirely new to SonarQube i’m completely open to any improvement because i’m not sure at all if i’m using the the scanner correctly or if i need any more config in the project.

Which versions are you using (SonarQube, Scanner, Plugin, and any relevant extension)
SonarQube Community Edition Version 7.9.1 (build 27448)
SonarQube Scanner 4.2.0.1873

What are you trying to achieve
I’m trying to analyze my VueJS project with sonarqube-scanner for linux and publish the report to the SonarQube server. The project uses typescript and vue single file components.
According to this ticket it should be working i think.

Here is an example for a single file component .vue file:

    <template>
      <div class="v-code__description">{{ msg }}</div>
    </template>
    <script lang="ts">
    import { Component, Vue, Prop } from "vue-property-decorator";

    @Component({})
    export default class LongDescription extends Vue {
      @Prop() msg!: string;
    }
    </script>

What have you tried so far to achieve this
I set up SonarQube in a docker environment. I know that it is working because i can analyze java projects with the gradle plugin without any problems.
For the vue-project i installed the SonarJS plugin (as far as i know typescript is now handled in this plugin).
When i try to scan my vue-project with the sonarqube-scanner it will eventually fail to scan the .vue files (.ts-files work perfectly fine). The error message is:

ERROR: Failed to parse file [src/App.vue] at line 12: ‘import’ and ‘export’ may appear only with ‘sourceType: module’

After researching that i found out you need to define the sourceType in the .eslinttrc.js.
After defining the sourceType sonar-scanner is still failing with the same error.
But when i run eslint everything seems to work fine.

I know SonarJS isn’t per se using eslint. Is there maybe another place to define this?
If not does anybody know why sonar-scanner isn’t picking up the sourceType from the .eslinttrc.js?
Or is there maybe any other hint or example for vue/typescript someone could give to me?

P.S. For better reproduction you could use this project. It uses pretty much the same plugins and functionality we are aiming for.

Steps for reproduction:

  1. git clone https://github.com/Armour/vue-typescript-admin-template.git
  2. (sudo apt-get install g++ build-essential) => maybe optional, up to your os and setup
  3. yarn install
  4. (yarn serve) => only for testing
  5. create sonar-project.properties (structure like in my personal project only different key, login, etc.)
  6. sonar-scanner

Thanks, Florian

.eslinttrc.js

    module.exports = {
      root: true,
      env: {
        node: true
      },
            extends: ["plugin:vue/essential", "@vue/prettier", "@vue/typescript"],
      rules: {
        "no-console": process.env.NODE_ENV === "production" ? "error" : "off",
        "no-debugger": process.env.NODE_ENV === "production" ? "error" : "off"
      },
      parserOptions: {
        sourceType: "module",
        parser: "@typescript-eslint/parser"
      },
      overrides: [
        {
          files: [
            "**/__tests__/*.{j,t}s?(x)",
            "**/tests/unit/**/*.spec.{j,t}s?(x)"
          ],
          env: {
            jest: true
          }
        }
      ]
    };

sonar-project.properties

sonar.projectKey=mytestlivedemo[spoiler]
sonar.sources=src/
sonar.login=c7fc39b7c7321d27c9078145fb739cb981398a57
sonar.analysis.mode=publish
sonar.eslint.reportPaths=report.json

Output from running sonar-scanner:

    INFO: Scanner configuration file: /home/fsaller/Downloads/sonar-scanner-4.2.0.1873-linux/conf/sonar-scanner.properties
    INFO: Project root configuration file: /home/fsaller/Documents/mytestlivedemo/sonar-project.properties
    INFO: SonarQube Scanner 4.2.0.1873
    INFO: Java 11.0.3 AdoptOpenJDK (64-bit)
    INFO: Linux 5.0.0-37-generic amd64
    INFO: User cache: /home/fsaller/.sonar/cache
    INFO: SonarQube server 7.9.1
    INFO: Default locale: "en_US", source code encoding: "UTF-8" (analysis is platform dependent)
    INFO: Load global settings
    INFO: Load global settings (done) | time=88ms
    INFO: Server id: 7C17DABA-AW7Hooawdl-6TFerV4pv
    INFO: User cache: /home/fsaller/.sonar/cache
    INFO: Load/download plugins
    INFO: Load plugins index
    INFO: Load plugins index (done) | time=51ms
    INFO: Load/download plugins (done) | time=94ms
    INFO: Process project properties
    INFO: Project key: god
    INFO: Base dir: /home/fsaller/Documents/mytestlivedemo
    INFO: Working dir: /home/fsaller/Documents/mytestlivedemo/.scannerwork
    INFO: Load project settings for component key: 'god'
    INFO: Load project settings for component key: 'god' (done) | time=56ms
    INFO: Load project branches
    INFO: Load project branches (done) | time=56ms
    INFO: Load project pull requests
    INFO: Load project pull requests (done) | time=26ms
    INFO: Load branch configuration
    INFO: Load branch configuration (done) | time=1ms
    INFO: Load quality profiles
    INFO: Load quality profiles (done) | time=51ms
    INFO: Load active rules
    INFO: Load active rules (done) | time=478ms
    WARN: SCM provider autodetection failed. Please use "sonar.scm.provider" to define SCM of your project, or disable the SCM Sensor in the project settings.
    INFO: Indexing files...
    INFO: Project configuration:
    INFO: 66 files indexed
    INFO: Quality profile for js: Sonar way
    INFO: Quality profile for ts: Sonar way
    INFO: ------------- Run sensors on module god
    INFO: Load metrics repository
    INFO: Load metrics repository (done) | time=40ms
    WARNING: An illegal reflective access operation has occurred
    WARNING: Illegal reflective access by net.sf.cglib.core.ReflectUtils$1 (file:/home/fsaller/.sonar/cache/a2b6a8802525720c8af2ca4fa85a2513/sonar-javascript-plugin.jar) to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain)
    WARNING: Please consider reporting this to the maintainers of net.sf.cglib.core.ReflectUtils$1
    WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
    WARNING: All illegal access operations will be denied in a future release
    INFO: Sensor JavaXmlSensor [java]
    INFO: Sensor JavaXmlSensor [java] (done) | time=5ms
    INFO: Sensor HTML [web]
    INFO: Load project repositories
    INFO: Load project repositories (done) | time=38ms
    INFO: Sensor HTML [web] (done) | time=175ms
    INFO: Sensor JaCoCo XML Report Importer [jacoco]
    INFO: Sensor JaCoCo XML Report Importer [jacoco] (done) | time=4ms
    INFO: Sensor SonarTS [typescript]
    INFO: Since SonarTS v2.0, TypeScript analysis is performed by SonarJS analyzer v6.0 or later. No TypeScript analysis is performed by SonarTS.
    INFO: Sensor SonarTS [typescript] (done) | time=1ms
    INFO: Sensor JavaScript analysis [javascript]
    INFO: Using TypeScript at: '/home/fsaller/Documents/mytestlivedemo/node_modules'
    INFO: 14 source files to be analyzed
    ERROR: Failed to parse file [src/App.vue] at line 12: 'import' and 'export' may appear only with 'sourceType: module'
    ERROR: Failed to parse file [src/components/FormInput.vue] at line 15: 'import' and 'export' may appear only with 'sourceType: module'
    ERROR: Failed to parse file [src/components/LongDescription.vue] at line 5: 'import' and 'export' may appear only with 'sourceType: module'
    ERROR: Failed to parse file [src/components/MainComponent.vue] at line 13: 'import' and 'export' may appear only with 'sourceType: module'
    ERROR: Failed to parse file [src/components/MainContainer.vue] at line 12: 'import' and 'export' may appear only with 'sourceType: module'
    ERROR: Failed to parse file [src/components/MainHeader.vue] at line 7: 'import' and 'export' may appear only with 'sourceType: module'
    ERROR: Failed to parse file [src/components/Search.vue] at line 21: 'import' and 'export' may appear only with 'sourceType: module'
    ERROR: Failed to parse file [src/components/ShortDescription.vue] at line 5: 'import' and 'export' may appear only with 'sourceType: module'
    ERROR: Failed to parse file [src/components/Sidebar.vue] at line 16: 'import' and 'export' may appear only with 'sourceType: module'
    ERROR: Failed to parse file [src/components/SidebarItem.vue] at line 7: 'import' and 'export' may appear only with 'sourceType: module'
    ERROR: Failed to parse file [src/components/SubComponent.vue] at line 39: 'import' and 'export' may appear only with 'sourceType: module'
    ERROR: Failed to parse file [src/components/Testing.vue] at line 5: 'import' and 'export' may appear only with 'sourceType: module'
    ERROR: Failed to parse file [src/components/VueCode.vue] at line 39: 'import' and 'export' may appear only with 'sourceType: module'
    INFO: 14/14 source files have been analyzed
    INFO: Sensor SonarJS [javascript]
    INFO: 14 source files to be analyzed
    INFO: Sensor SonarJS [javascript] (done) | time=194ms
    INFO: 14/14 source files have been analyzed
    INFO: Sensor JavaScript analysis [javascript] (done) | time=3521ms
    INFO: Sensor TypeScript analysis [javascript]
    INFO: Found 1 tsconfig.json file(s): [/home/fsaller/Documents/mytestlivedemo/tsconfig.json]
    INFO: 27 source files to be analyzed
    INFO: Analyzing 27 files using tsconfig: /home/fsaller/Documents/mytestlivedemo/tsconfig.json
    INFO: 27/27 source files have been analyzed
    INFO: Sensor TypeScript analysis [javascript] (done) | time=4509ms
    INFO: ------------- Run sensors on project
    INFO: Sensor Zero Coverage Sensor
    INFO: Sensor Zero Coverage Sensor (done) | time=11ms
    INFO: No SCM system was detected. You can use the 'sonar.scm.provider' property to explicitly specify it.
    INFO: 18 files had no CPD blocks
    INFO: Calculating CPD for 10 files
    INFO: CPD calculation finished
    INFO: Analysis report generated in 75ms, dir size=95 KB
    INFO: Analysis report compressed in 70ms, zip size=51 KB
    INFO: Analysis report uploaded in 82ms
    INFO: ANALYSIS SUCCESSFUL, you can browse http://localhost:9000/dashboard?id=god
    INFO: Note that you will be able to access the updated dashboard once the server has processed the submitted analysis report
    INFO: More about the report processing at http://localhost:9000/api/ce/task?id=AW76DrnU44gq2Cbo4yoj
    INFO: Analysis total time: 10.890 s
    INFO: ------------------------------------------------------------------------
    INFO: EXECUTION SUCCESS
    INFO: ------------------------------------------------------------------------
    INFO: Total time: 12.049s
    INFO: Final Memory: 9M/37M
    INFO: ------------------------------------------------------------------------
1 Like

Hi,

We don’t yet support .vue files with typescript, but we certainly plan to add its support some time soon. You can follow this activity here https://jira.sonarsource.com/browse/MMF-1441.

I agree, that current experience is not great, we should not fail with parsing error as lang="ts" explicitly specifies the language. I will see if we can improve it.

Yet our assumption for the future is that when you use TS for VueJS, you should specify .vue extension for TypeScript language and remove it from JavaScript as SonarQube does not allow same extension for 2 languages.

2 Likes

This issue is affecting my projects too. I’ve added my vote to the issue on Jira.

I’m using the Sonar Cloud github action for scanning.

Is there any work around? All our .vue files are typescript.

1 Like

Hi,

Unfortunately there is no workaround. Let’s hope we will manage to add this feature soon.

1 Like

I created an awful hack for this. Posting it here in case anyone else cannot wait for this bug to be fixed and finds it useful as a (hopefully) short term work around!

1 Like

Hi Lena,

Is there a release date on support .vue with lang=ts? I am looking at the issue tracker but there is not much to go on.

Many thanks

1 Like

Sorry, no release date yet :frowning: But we are aware that this is a feature a lot desired by the users so we will try to fit it in the roadmap.