|
| 1 | +# Prebuild Tasks |
| 2 | + |
| 3 | +There are two "prebuild" tasks, linting and type checking that need to be run before any kind of building takes place. |
| 4 | + |
| 5 | +The buildtools call both ESLint and `tsc` in parallel since they are not dependent on each others' outputs. |
| 6 | + |
| 7 | +## Running ESLint from the Command Line |
| 8 | +ESLint provides [documentation](https://eslint.org/docs/latest/integrate/nodejs-api) detailing how to use its Node API. Below is the code that does just that: |
| 9 | + |
| 10 | +<<< ../../../lib/buildtools/src/prebuild/lint.ts {ts:line-numbers} |
| 11 | + |
| 12 | +Because the configuration file for the repository is located at the root of the repository, we need to set the `cwd` to the path to the root of the repository when |
| 13 | +initializing the `ESLint` instance. This allows ESLint to resolve the configuration correctly. |
| 14 | + |
| 15 | +Linting warnings and errors come in two types, fixable and non-fixable. Fixable errors don't cause a non-zero exit code when ESLint is run with `--fix`, while non-fixable |
| 16 | +errors always cause a non-zero exit code. |
| 17 | + |
| 18 | +ESLint provides several [formatters](https://eslint.org/docs/latest/use/formatters/) for processing the results objects it returns. To produce the human readable output that is printed to the command line, the `stylish` formatter |
| 19 | +is loaded and used. |
| 20 | + |
| 21 | +## Calling Typescript from Node |
| 22 | + |
| 23 | +Most of the code for running Typescript functionality from Node was taken from [this](https://github.com/Microsoft/TypeScript/issues/6387) Github issue. |
| 24 | + |
| 25 | +<<< ../../../lib/buildtools/src/prebuild/tsc.ts {ts:line-numbers} |
| 26 | + |
| 27 | +The high level overview of this process is as follows: |
| 28 | +1. Read the raw text from the `tsconfig.json` |
| 29 | +2. Parse the `tsconfig.json` into a JSON object using `ts.parseConfigFileTextToJson` |
| 30 | +3. Parse the JSON object into actual compiler options using `ts.parseJsonConfigFileContent`. This also returns an array of file names for parsing. |
| 31 | +4. Use `ts.createProgram` to get the preliminary program for type checking only. |
| 32 | +5. Call `typecheckProgram.emit()` to produce the typechecking results. |
| 33 | +6. Combine the results with `ts.getPreEmitDiagonstics`. |
| 34 | +7. If there were no typechecking errors and the `tsconfig.json` did not specify <nobr><code>noEmit: true</code></nobr>, use `ts.createProgram` again with the typecheck program to perform compilation and declaration file emission excluding test files. |
| 35 | +8. Format the diagnostic objects using `ts.formatDiagnosticsWithColorAndContext` |
| 36 | + |
| 37 | +### Reading and Parsing `tsconfig.json` |
| 38 | +The first three steps in the process involve reading the raw text from the `tsconfig.json` and then parsing it. At the end of it, `ts.parseJsonConfigFileContent` resolves all the inherited options and produces the compiler options |
| 39 | +in use, as well as the file paths to the files that are to be processed. |
| 40 | + |
| 41 | +### Type Checking |
| 42 | +The first time `ts.createProgram` is called, it is called with every single file as returned from `ts.parseJsonConfigFileContent`. However, it is called with `noEmit: true`. This prevents any Javascript and Typescript declaration files from being written. |
| 43 | +This is important because we want test files to be type checked, but we don't want them to be compiled into Javascript and exported with the rest of the code. If they were included and the `tsconfig` was configured to produce outputs, the test files would end |
| 44 | +up being written to the `outDir`. `typecheckProgram.emit` is called to perform the type checking. |
| 45 | + |
| 46 | +If there are no errors and the `tsconfig` was configured to produce outputs, `ts.createProgram` is called again. This time, test files are filtered out. `ts.createProgram` has a parameter for passing in the previous program object, allowing it to reuse |
| 47 | +an existing program so it doesn't have to reinitialize the entire object again. `program.emit` is called to produce any compiled Javascript and Typescript declaration files. |
0 commit comments