Skip to content

Languages and extensions

Language idExtensions
php.php .phtml
typescript.ts .mts .cts .tsx .jsx .js .mjs .cjs
vue.vue

Never scanned, whatever the extension: .d.ts, .d.mts, .d.cts, .min.js, .min.mjs, .min.cjs.

The language id is what --lang, --over LANG=N and a [section] in the config take, so typescript covers every JavaScript and TypeScript file however it is parsed. An id that is not one of these is an error, not a silent no-op.

A declaration file and a minified one are both skipped outright, for opposite reasons: the first holds only signatures so every unit scores zero, and the second is generated output whose whole body rolls up into one unit nobody will refactor. The skipped names are whole suffixes, so app.mini.js, jasmine.js and a file simply called min.js are all still scanned.

.js is parsed with the TypeScript grammar, which accepts a superset of JavaScript. Flow annotations are the one thing this misparses.

A .vue file scores its <script> and <script setup> blocks, with lang="ts" choosing the TypeScript grammar and anything else (including no lang) choosing the JSX-capable one, which is the grammar .js already uses. Each block is parsed on its own, and their file-level code is added together into the one <toplevel> a component reports. Reported lines are lines in the .vue file, so editing a template moves a finding without changing its baseline key.

Construct Scored
<script> and <script setup>, any lang yes, as vue
a render() function written in a script block yes, as vue
JSX inside <script lang="tsx"> yes, as vue
<template>: v-if, v-for, {{ }}, @click="a && b()" no
<style>, and custom blocks such as <docs> or <i18n> no
<script src="./logic.ts"> no, but logic.ts is scanned on its own, as typescript

Two consequences are worth knowing:

  • The template is deliberately not scored. A v-if chain is real branching, but the specification was not written against templates and counting them would make a component incomparable with the same logic written in TypeScript. A render() function is scored, because it is ordinary script code, so moving logic out of a template and into render() makes it visible, and a component that never had a template was never hidden.
  • A src= block belongs to the file it points at. That file is scored as typescript, so a [vue] threshold does not reach it.