]> git.proxmox.com Git - pve-eslint.git/blob - eslint/docs/developer-guide/architecture.md
6531c28391f8940ae374cb7647290c1dadc2da56
[pve-eslint.git] / eslint / docs / developer-guide / architecture.md
1 # Architecture
2
3 <center><img alt="dependency graph" src="./architecture/dependency.svg"></center>
4
5 At a high level, there are a few key parts to ESLint:
6
7 * `bin/eslint.js` - this is the file that actually gets executed with the command line utility. It's a dumb wrapper that does nothing more than bootstrap ESLint, passing the command line arguments to `cli`. This is intentionally small so as not to require heavy testing.
8 * `lib/api.js` - this is the entry point of `require("eslint")`. This file exposes an object that contains public classes `Linter`, `ESLint`, `RuleTester`, and `SourceCode`.
9 * `lib/cli.js` - this is the heart of the ESLint CLI. It takes an array of arguments and then uses `eslint` to execute the commands. By keeping this as a separate utility, it allows others to effectively call ESLint from within another Node.js program as if it were done on the command line. The main call is `cli.execute()`. This is also the part that does all the file reading, directory traversing, input, and output.
10 * `lib/init/` - this module contains `--init` functionality that set up a configuration file for end users.
11 * `lib/cli-engine/` - this module is `CLIEngine` class that finds source code files and configuration files then does code verifying with the `Linter` class. This includes the loading logic of configuration files, parsers, plugins, and formatters.
12 * `lib/linter/` - this module is the core `Linter` class that does code verifying based on configuration options. This file does no file I/O and does not interact with the `console` at all. For other Node.js programs that have JavaScript text to verify, they would be able to use this interface directly.
13 * `lib/rule-tester/` - this module is `RuleTester` class that is a wrapper around Mocha so that rules can be unit tested. This class lets us write consistently formatted tests for each rule that is implemented and be confident that each of the rules work. The RuleTester interface was modeled after Mocha and works with Mocha's global testing methods. RuleTester can also be modified to work with other testing frameworks.
14 * `lib/source-code/` - this module is `SourceCode` class that is used to represent the parsed source code. It takes in source code and the Program node of the AST representing the code.
15 * `lib/rules/` - this contains built-in rules that verify source code.
16
17 ## The `cli` object
18
19 The `cli` object is the API for the command line interface. Literally, the `bin/eslint.js` file simply passes arguments to the `cli` object and then sets `process.exitCode` to the returned exit code.
20
21 The main method is `cli.execute()`, which accepts an array of strings that represent the command line options (as if `process.argv` were passed without the first two arguments). If you want to run ESLint from inside of another program and have it act like the CLI, then `cli` is the object to use.
22
23 This object's responsibilities include:
24
25 * Interpreting command line arguments
26 * Reading from the file system
27 * Outputting to the console
28 * Outputting to the filesystem
29 * Use a formatter
30 * Returning the correct exit code
31
32 This object may not:
33
34 * Call `process.exit()` directly
35 * Perform any asynchronous operations
36
37 ## The `CLIEngine` object
38
39 The `CLIEngine` type represents the core functionality of the CLI except that it reads nothing from the command line and doesn't output anything by default. Instead, it accepts many (but not all) of the arguments that are passed into the CLI. It reads both configuration and source files as well as managing the environment that is passed into the `Linter` object.
40
41 The main method of the `CLIEngine` is `executeOnFiles()`, which accepts an array of file and directory names to run the linter on.
42
43 This object's responsibilities include:
44
45 * Managing the execution environment for `Linter`
46 * Reading from the file system
47 * Reading configuration information from config files (including `.eslintrc` and `package.json`)
48
49 This object may not:
50
51 * Call `process.exit()` directly
52 * Perform any asynchronous operations
53 * Output to the console
54 * Use formatters
55
56 ## The `Linter` object
57
58 The main method of the `Linter` object is `verify()` and accepts two arguments: the source text to verify and a configuration object (the baked configuration of the given configuration file plus command line options). The method first parses the given text with `espree` (or whatever the configured parser is) and retrieves the AST. The AST is produced with both line/column and range locations which are useful for reporting location of issues and retrieving the source text related to an AST node, respectively.
59
60 Once the AST is available, `estraverse` is used to traverse the AST from top to bottom. At each node, the `Linter` object emits an event that has the same name as the node type (i.e., "Identifier", "WithStatement", etc.). On the way back up the subtree, an event is emitted with the AST type name and suffixed with ":exit", such as "Identifier:exit" - this allows rules to take action both on the way down and on the way up in the traversal. Each event is emitted with the appropriate AST node available.
61
62 This object's responsibilities include:
63
64 * Inspecting JavaScript code strings
65 * Creating an AST for the code
66 * Executing rules on the AST
67 * Reporting back the results of the execution
68
69 This object may not:
70
71 * Call `process.exit()` directly
72 * Perform any asynchronous operations
73 * Use Node.js-specific features
74 * Access the file system
75 * Call `console.log()` or any other similar method
76
77 ## Rules
78
79 Individual rules are the most specialized part of the ESLint architecture. Rules can do very little, they are simply a set of instructions executed against an AST that is provided. They do get some context information passed in, but the primary responsibility of a rule is to inspect the AST and report warnings.
80
81 These objects' responsibilities are:
82
83 * Inspect the AST for specific patterns
84 * Reporting warnings when certain patterns are found
85
86 These objects may not:
87
88 * Call `process.exit()` directly
89 * Perform any asynchronous operations
90 * Use Node.js-specific features
91 * Access the file system
92 * Call `console.log()` or any other similar method