Make sure to also read the full documentation of all available modules.
Install Wotan as a local dependency:
npm install --save-dev @fimbul/wotan# oryarn add -D @fimbul/wotan
.wotanrc.yaml file to the root of your project with the following content:
Now you can run the linter with one of the following commands depending on your use case:
wotan -p <path/to/tsconfig.json> # lint the whole projectwotan 'src/**/*.ts' -e '**/*.d.ts' # lint all typescript files excluding declaration fileswotan --fix # lint the whole project and fix all fixable errorswotan -p tsconfig.json -r # lint the specified project and all projects in its 'references'
For a list of available rules, see the documentation of the
Wotan is configured with a YAML, JSON5 or JSON file named
.wotanrc.json. By default the configuration file from the closest parent folder is used to lint each file.
You can use different configurations for different directories. Consider the following setup:
.wotanrc.yaml describes the rules that apply to every file and subdirectory (unless they contain a cofiguration file themselves):
---extends: wotan:recommended # use all recommended rules
test/.wotanrc.json extends the base configuration and disables some rules that are not needed for tests:
Note: this describes the default configuration file name and content. Plugin modules are able to override this behavior to read files with different name or content.
If you are more into having a single place for configuration, here's an alternative solution for the example above. The
.wotanrc.yaml could look like this:
---extends: wotan:recommended # use all recommended rules, could be an array to extend multiple configsrules: # could override some rules for all files hereoverrides:- files: "test/**" # override the following rules for all files in the `test` folderrules:no-useless-assertion: offawait-only-promise: warn- files: "*.spec.ts" # override the following rules for all *.spec.ts files in all directoriesrules:no-debugger: off
Overrides are processed in order and applied in order. The latter one overrides all prior overrides.
Note that in the example above
*.spec.ts matches in all directories. Normally patterns are matched relative to the configuration file they are specified in. Patterns without any slash are treated special. They will only be matched against the basename of every file in every directory.
If you want to limit the pattern to the current directory, you can prefix it with
./ resulting in
* also matches the leading do if present, so you don't need a second glob pattern for dotfiles. That means
.some.spec.ts as well as
Rules can have one of 4 different severities:
error is reported and causes the process to end with an exit code of 2. This is the default if not specified.
warning is reported but doesn't cause a non-zero exit code.
suggestion treated like
warning but displayed differently.
off turns the rule off, of course.
Configurable rules get their options through an object. The content of the
"options" property varies based on the rule.
"rules":"some-rule":"severity": "error""options":"some-option": "some-option-value"
options are both optional. That allows you to extend a configuration and only change the severity of a rule without altering the options. Or you can change the rule's options without changing the severity inherited by the base config.
If the linter behaves somehow unexpected, it's probably because you configured it that way. You're lucky because there's a builtin command to diagnose this, so you don't need to know how the configuration file lookup and the handling of overrides, excludes and aliases works in detail.
wotan show <filename> to display the configuration file and the exact rule config used to lint this file. If there is no file found or the file is excluded, you will see that too.
Enable or disable rules with comments
Sometimes you need to enable or disable a specific rule or all rules for a section of a file. This can be done using comments. It doesn't matter if you use
/* */. Multiple rule names are separated by comma.
It's not possible to enable a rule with a comment if that rule is not already enabled in the configuration for that file. That means comments can only enable rules that were previously disabled by a comment.
// wotan-disabledisables all rules from the start of the comment until the end of the file (or until it is enabled again)
// wotan-enableenables all rules from the start of the comment until the end of the file. Enable comments have the same mechanics as disable comments.
// wotan-disable-linedisables all rules in the current line (also works with enable)
// wotan-disable-next-linedisables all rules in the next line (also works with enable)
// wotan-disable-next-line bar, local/bazdisables the rules
local/bazin the next line
// wotan-enable-line fooenables the rule
fooin the current line
// wotan-enable-next-line bar, local/bazenables the rules
local/bazin the next line
This is the default behavior which can be overridden by plugin modules.
To detect unused or redundant comments you can use the
--report-useless-directives CLI option.
-c --config <name>specifies the configuration to use for all files instead of looking for configuration files in parent directories. This can either be a file name, the name of a node module containing a shareable config, or the name of a builtin config like
-e --exclude <glob>excludes all files that match the given glob pattern from linting. This option can be used multiple times to specify multiple patterns. For example
-e '**/*.js' -e '**/*.d.ts'. It is recommended to wrap the glob patterns in single quotes to prevent the shell from expanding them.
--fix [true|false|number]automatically fixes all fixable findings in your code and writes the result back to disk. Given a number it will at most use the specified number of iterations for fixing before returning the result. There are some precautions to prevent overlapping fixes from destroying you code. You should however commit your changes before using this feature. Files containing syntax errors are never fixed. If applying fixes would cause syntax errors, the fixes will not be applied.
-f --formatter <name>the name or path of a formatter. This can either be a file name, the name of a node module contianing a formatter, or the name of a builtin formatter. Currently available builtin formatters are
-m --module <name>specifies one or more packages with DI modules to load before starting the actual linter. These modules can be used to override the default behavior.
-p --project <name>specifies the path to the
tsconfig.jsonfile to use. This option is used to find all files contained in your project. It also enables rules that require type information. This option can be used multiple times to specify multiple projects to lint.
-r --references [true|false]enables project references. Starting from the project specified with
-p --projector the
tsconfig.jsonin the current directory it will recursively follow all
"references"and lint those projects.
// wotan-enablecomments that are redundant (i.e. rules are already disabled) or unused (there are no findings for the specified rules). Useless directives are reported as lint findings with the specified severity (
trueis converted to
error). Those findings cannot be disabled by a disable comment. The findings are fixable which allow autofixing when used with the
[...FILES]specifies the files to lint. You can specify paths and glob patterns here.
Note that all file paths are relative to the current working directory. Therefore
**/*.ts doesn't match
The following examples are intended to be used as npm scripts. If you want to execute it directly on the command line, you need to use
./node_modules/.bin/wotan instead of just
wotan # search the closest tsconfig.json and lint the whole project with type informationwotan -c wotan:recommended # same as above, but uses the specified configuration for all files in the projectwotan -c wotan:recommended --fix # same as above with automatic fixingwotan '**/*.ts' -e '**/*.d.ts' -e 'node_modules/**' # lint all typescript files excluding declaration files, also excludes node_modules just to be surewotan -p . # lint the whole project configured by ./tsconfig.json, with type information, excludes node_modules by defaultwotan -p . 'src/**' # lint all files in src directory that are included in the project with type informationwotan -p src -p test # lint all files in project 'src' and all files in project 'test'wotan -p . -r # lint the whole project configured by ./tsconfig.json all all of its project referenceswotan -m @fimbul/heimdall # enables TSLint rules and formatters to be used. for more information, see @fimbul/heimdall
Adding CLI defaults to
If you find yourself using Wotan with the same CLI arguments over and over again, you can simply save them as defaults to a file called
.fimbullinter.yaml. By default Wotan uses this file for CLI defaults if it's present in your current working directory.
There's a subcommand to create and update this file, so you don't need to know any implementation details to guess the file structure.
Let's assume you always use the following CLI arguments:
wotan -p tsconfig.build.json -c config/.wotanrc.yaml -e '**/*.d.ts'
To save these as defaults, simply use the
wotan save -p tsconfig.build.json -c config/.wotanrc.yaml -e '**/*.d.ts'
You just created a
.fimbullinter.yaml file with the following contents:
config: config/.wotanrc.yamlexclude:- "**/*.d.ts"project: tsconfig.build.json
The next time you execute
wotan in that directory, this default configuration is automatically picked up.
Defaults can be overridden or cleared by explicitly specifying them as CLI arguments, for example:
wotan -p tsconfig.json -e '' # overrides 'project' and clears 'exclude'wotan save -c '' # clear 'config' option and update .fimbullinter.yaml
.fimbullinter.yaml can also be used to store configuration for plugin modules. See the documentation of the plugins you use if this applies to you. In that case you need to edit the file manually. Using
wotan save will not alter third party configuration.
Linting with Type Information
When linting a project (
--project CLI option) rules are able to use type information using TypeScript's API. Some rules report more findings with type information, some other rules require type information for each of their checks.
If a rule cannot work properly without type information, you will see a warning like
Rule 'foo' requires type information.
"allowJs": true, "checkJs": true in your
tsconfig.json or by adding a
// @ts-check comment on top of your JS files.
// @ts-nocheck comment excludes a file from type checking.
Wotan respects these flags, too. That means it will not provide type information to rules executed on unchecked JS files. This ensures you won't get surprising lint findings caused by funky type inference in those files. You will still get reports for purely syntactic findings, i.e. rules that don't require type information.
If type information is available Wotan excludes all files you haven't written yourself. The following files are always excluded so you cannot explicitly include them:
- any files of dependencies in
node_modules(unless imported using a relative path, e.g.
- declaration files from
typeRootsdeclared in your
- declaration files included by TypeScript, e.g.
- declaration files of project references (
This is the default behavior which can be overridden by plugin modules.
If you lint individual files without type information using the file's path or a glob pattern, you are responsible for excluding all files you don't want to lint.
Catching bugs by just looking at an exception is hard. That's why Wotan produces debug output for certain events. You only need to enable it via environment variable
DEBUG=wotan:* and run the previous command again.
See the detailed documentation on how to use the wildcards.
Apache-2.0 © Klaus Meinhardt