Skip to content

Commit a430979

Browse files
authored
feat: add context option for typescript reporter (#430)
Add `context` option to support usage of external tsconfig.json files. ✅ Closes: #297
1 parent 503a948 commit a430979

26 files changed

+407
-150
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
lib
66

77
# Package archive used by e2e tests
8-
fork-ts-checker-webpack-plugin.tgz
8+
fork-ts-checker-webpack-plugin-0.0.0-semantic-release.tgz
99

1010
# Coverage directory used by tools like istanbul
1111
coverage

README.md

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -153,16 +153,17 @@ Options passed to the plugin constructor will overwrite options from the cosmico
153153

154154
Options for the TypeScript checker (`typescript` option object).
155155

156-
| Name | Type | Default value | Description |
157-
| -------------------- | --------------------- | ------------------------------------------------------------------------- | ----------- |
158-
| `enabled` | `boolean` | `true` | If `true`, it enables TypeScript checker. |
159-
| `memoryLimit` | `number` | `2048` | Memory limit for the checker process in MB. If the process exits with the allocation failed error, try to increase this number. |
160-
| `tsconfig` | `string` | `'tsconfig.json'` | Path to the `tsconfig.json` file (path relative to the `compiler.options.context` or absolute path) |
161-
| `build` | `boolean` | `false` | If truthy, it's the equivalent of the `--build` flag for the `tsc` command. |
162-
| `mode` | `'readonly'` or `'write-tsbuildinfo'` or `'write-references'` | `'readonly'` | If you use the `babel-loader`, it's recommended to use `write-references` mode to improve initial compilation time. If you use `ts-loader`, it's recommended to use `readonly` mode to not overwrite filed emitted by `ts-loader`. |
163-
| `compilerOptions` | `object` | `{ skipLibCheck: true, skipDefaultLibCheck: true }` | These options will overwrite compiler options from the `tsconfig.json` file. |
164-
| `diagnosticsOptions` | `object` | `{ syntactic: false, semantic: true, declaration: false, global: false }` | Settings to select which diagnostics do we want to perform. |
165-
| `extensions` | `object` | `{}` | See [TypeScript extensions options](#typescript-extensions-options). |
156+
| Name | Type | Default value | Description |
157+
| -------------------- | --------- | ------------------------------------------------------------------------- | ----------- |
158+
| `enabled` | `boolean` | `true` | If `true`, it enables TypeScript checker. |
159+
| `memoryLimit` | `number` | `2048` | Memory limit for the checker process in MB. If the process exits with the allocation failed error, try to increase this number. |
160+
| `tsconfig` | `string` | `'tsconfig.json'` | Path to the `tsconfig.json` file (path relative to the `compiler.options.context` or absolute path) |
161+
| `context` | `string` | `dirname(configuration.tsconfig)` | The base path for finding files specified in the `tsconfig.json`. Same as the `context` option from the [ts-loader](https://github.com/TypeStrong/ts-loader#context). Useful if you want to keep your `tsconfig.json` in an external package. Keep in mind that **not** having a `tsconfig.json` in your project root can cause different behaviour between `fork-ts-checker-webpack-plugin` and `tsc`. When using editors like `VS Code` it is advised to add a `tsconfig.json` file to the root of the project and extend the config file referenced in option `tsconfig`. |
162+
| `build` | `boolean` | `false` | The equivalent of the `--build` flag for the `tsc` command. To enable `incremental` mode, set it in the `tsconfig.json` file. |
163+
| `mode` | `'readonly'` or `'write-tsbuildinfo'` or `'write-references'` | `'readonly'` | If you use the `babel-loader`, it's recommended to use `write-references` mode to improve initial compilation time. If you use `ts-loader`, it's recommended to use `readonly` mode to not overwrite filed emitted by `ts-loader`. |
164+
| `compilerOptions` | `object` | `{ skipLibCheck: true, skipDefaultLibCheck: true }` | These options will overwrite compiler options from the `tsconfig.json` file. |
165+
| `diagnosticsOptions` | `object` | `{ syntactic: false, semantic: true, declaration: false, global: false }` | Settings to select which diagnostics do we want to perform. |
166+
| `extensions` | `object` | `{}` | See [TypeScript extensions options](#typescript-extensions-options). |
166167

167168
#### TypeScript extensions options
168169

examples/eslint/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"name": "fork-ts-checker-webpack-plugin-ts-loader-example",
2+
"name": "fork-ts-checker-webpack-plugin-eslint-example",
33
"version": "0.0.0",
44
"main": "dist/index.js",
55
"license": "MIT",

package.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,7 @@
3535
"lint": "cross-env eslint ./src ./test --ext .ts",
3636
"test": "yarn build && yarn test:unit && yarn test:e2e",
3737
"test:unit": "cross-env jest unit",
38-
"test:pack": "yarn pack --filename fork-ts-checker-webpack-plugin.tgz",
39-
"test:e2e": "yarn test:pack && cross-env jest e2e --ci --runInBand --bail --verbose",
38+
"test:e2e": "npm pack && cross-env jest e2e --ci --runInBand --bail --verbose",
4039
"precommit": "cross-env lint-staged && yarn build && yarn test:unit",
4140
"commit": "cross-env git-cz",
4241
"semantic-release": "semantic-release"
@@ -112,7 +111,6 @@
112111
"tree-kill": "^1.2.2",
113112
"ts-jest": "^25.3.1",
114113
"typescript": "^3.8.3",
115-
"unixify": "^1.0.0",
116114
"webpack": "^4.42.1"
117115
},
118116
"engines": {

src/ForkTsCheckerWebpackPlugin.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { createEsLintReporterRpcClient } from './eslint-reporter/reporter/EsLint
1414
import { tapStartToConnectAndRunReporter } from './hooks/tapStartToConnectAndRunReporter';
1515
import { tapStopToDisconnectReporter } from './hooks/tapStopToDisconnectReporter';
1616
import { tapDoneToCollectRemoved } from './hooks/tapDoneToCollectRemoved';
17+
import { tapAfterCompileToAddDependencies } from './hooks/tapAfterCompileToAddDependencies';
1718
import { tapErrorToLogMessage } from './hooks/tapErrorToLogMessage';
1819
import { getForkTsCheckerWebpackPluginHooks } from './hooks/pluginHooks';
1920

@@ -59,6 +60,7 @@ class ForkTsCheckerWebpackPlugin implements webpack.Plugin {
5960

6061
tapStartToConnectAndRunReporter(compiler, reporter, configuration, state);
6162
tapDoneToCollectRemoved(compiler, configuration, state);
63+
tapAfterCompileToAddDependencies(compiler, configuration);
6264
tapStopToDisconnectReporter(compiler, reporter, state);
6365
tapErrorToLogMessage(compiler, configuration);
6466
} else {

src/ForkTsCheckerWebpackPluginOptions.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,10 @@
117117
"type": "string",
118118
"description": "Path to tsconfig.json. By default plugin uses context or process.cwd() to localize tsconfig.json file."
119119
},
120+
"context": {
121+
"type": "string",
122+
"description": "The base path for finding files specified in the tsconfig.json. Same as context option from the ts-loader."
123+
},
120124
"build": {
121125
"type": "boolean",
122126
"description": "The equivalent of the `--build` flag from the `tsc`."
@@ -126,10 +130,6 @@
126130
"enum": ["readonly", "write-tsbuildinfo", "write-references"],
127131
"description": "`readonly` keeps all emitted files in memory, `write-tsbuildinfo` which writes only .tsbuildinfo files and `write-references` which writes both .tsbuildinfo and referenced projects output"
128132
},
129-
"incremental": {
130-
"type": "boolean",
131-
"description": "The equivalent of the `--incremental` flag from the `tsc`."
132-
},
133133
"compilerOptions": {
134134
"type": "object",
135135
"description": "Custom compilerOptions to be passed to the TypeScript compiler.",

src/formatter/WebpackFormatter.ts

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,27 @@
11
import os from 'os';
22
import chalk from 'chalk';
3-
import { relative } from 'path';
3+
import path from 'path';
44
import { Formatter } from './Formatter';
55
import { formatIssueLocation } from '../issue';
6-
import normalizeSlash from '../utils/path/normalizeSlash';
6+
import forwardSlash from '../utils/path/forwardSlash';
77

88
function createWebpackFormatter(formatter: Formatter, context: string): Formatter {
9+
// mimics webpack error formatter
910
return function webpackFormatter(issue) {
11+
const color = issue.severity === 'warning' ? chalk.yellow.bold : chalk.red.bold;
12+
1013
const severity = issue.severity.toUpperCase();
11-
const file = issue.file ? normalizeSlash(relative(context, issue.file)) : undefined;
12-
const location = issue.location ? formatIssueLocation(issue.location) : undefined;
13-
const color = issue.severity === 'warning' ? chalk.yellow : chalk.red;
14-
const header = [severity, 'in', file].concat(location ? [location] : []).join(' ');
1514

16-
return [color.bold(header), formatter(issue), ''].join(os.EOL);
15+
if (issue.file) {
16+
let location = forwardSlash(path.relative(context, issue.file));
17+
if (issue.location) {
18+
location += ` ${formatIssueLocation(issue.location)}`;
19+
}
20+
21+
return [color(`${severity} in ${location}`), formatter(issue), ''].join(os.EOL);
22+
} else {
23+
return [color(`${severity} in `) + formatter(issue), ''].join(os.EOL);
24+
}
1725
};
1826
}
1927

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import webpack from 'webpack';
2+
import path from 'path';
3+
import { ForkTsCheckerWebpackPluginConfiguration } from '../ForkTsCheckerWebpackPluginConfiguration';
4+
5+
function tapAfterCompileToAddDependencies(
6+
compiler: webpack.Compiler,
7+
configuration: ForkTsCheckerWebpackPluginConfiguration
8+
) {
9+
compiler.hooks.afterCompile.tap('ForkTsCheckerWebpackPlugin', (compilation) => {
10+
if (configuration.typescript.enabled) {
11+
// watch tsconfig.json file
12+
compilation.fileDependencies.add(path.normalize(configuration.typescript.tsconfig));
13+
}
14+
});
15+
}
16+
17+
export { tapAfterCompileToAddDependencies };

src/issue/IssueMatch.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { Issue } from './index';
22
import { IssuePredicate } from './IssuePredicate';
33
import minimatch from 'minimatch';
44
import path from 'path';
5-
import normalizeSlash from '../utils/path/normalizeSlash';
5+
import forwardSlash from '../utils/path/forwardSlash';
66

77
type IssueMatch = Partial<Pick<Issue, 'origin' | 'severity' | 'code' | 'file'>>;
88

@@ -14,7 +14,7 @@ function createIssuePredicateFromIssueMatch(context: string, match: IssueMatch):
1414
const matchesFile =
1515
!issue.file ||
1616
(!!issue.file &&
17-
(!match.file || minimatch(normalizeSlash(path.relative(context, issue.file)), match.file)));
17+
(!match.file || minimatch(forwardSlash(path.relative(context, issue.file)), match.file)));
1818

1919
return matchesOrigin && matchesSeverity && matchesCode && matchesFile;
2020
};

src/issue/IssueWebpackError.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { relative } from 'path';
22
import { Issue } from './Issue';
33
import { formatIssueLocation } from './IssueLocation';
4-
import normalizeSlash from '../utils/path/normalizeSlash';
4+
import forwardSlash from '../utils/path/forwardSlash';
55

66
class IssueWebpackError extends Error {
77
readonly hideStack = true;
@@ -14,11 +14,11 @@ class IssueWebpackError extends Error {
1414
// should be a NormalModule instance.
1515
// to avoid such a dependency, we do a workaround - error.file will contain formatted location instead
1616
if (issue.file) {
17-
const parts = [normalizeSlash(relative(context, issue.file))];
17+
this.file = forwardSlash(relative(context, issue.file));
18+
1819
if (issue.location) {
19-
parts.push(formatIssueLocation(issue.location));
20+
this.file += ` ${formatIssueLocation(issue.location)}`;
2021
}
21-
this.file = parts.join(' ');
2222
}
2323

2424
Error.captureStackTrace(this, this.constructor);

0 commit comments

Comments
 (0)