From 001001cb3725720a2b700254db34827d42ca8ef0 Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Wed, 6 Sep 2017 19:12:13 +0200 Subject: [PATCH] build: custom tslint rules not executing in IDEs (#6817) Fixes our custom tslint rules not executing IDEs, because they're written in TypeScript. This is the preferred option over switching them back to ES6, because some rules require access to TS files from other parts of the build (e.g. the Rollup globals rule). --- tools/gulp/tasks/lint.ts | 15 ++------------- tools/tslint-rules/noViewEncapsulationRule.ts | 6 +++--- tools/tslint-rules/tsLoaderRule.js | 13 +++++++++++++ tslint.json | 2 +- 4 files changed, 19 insertions(+), 17 deletions(-) create mode 100644 tools/tslint-rules/tsLoaderRule.js diff --git a/tools/gulp/tasks/lint.ts b/tools/gulp/tasks/lint.ts index b81ce409387..b51b84ba654 100644 --- a/tools/gulp/tasks/lint.ts +++ b/tools/gulp/tasks/lint.ts @@ -6,7 +6,6 @@ import {red} from 'chalk'; // These types lack of type definitions const madge = require('madge'); -const resolveBin = require('resolve-bin'); /** Glob that matches all SCSS or CSS files that should be linted. */ const stylesGlob = '+(tools|src)/**/!(*.bundle).+(css|scss)'; @@ -28,10 +27,10 @@ task('stylelint', execNodeTask( )); /** Task to run TSLint against the e2e/ and src/ directories. */ -task('tslint', execTsLintTask()); +task('tslint', execNodeTask('tslint', tsLintBaseFlags)); /** Task that automatically fixes TSLint warnings. */ -task('tslint:fix', execTsLintTask('--fix')); +task('tslint:fix', execNodeTask('tslint', [...tsLintBaseFlags, '--fix'])); /** Task that runs madge to detect circular dependencies. */ task('madge', ['material:clean-build'], () => { @@ -51,13 +50,3 @@ task('madge', ['material:clean-build'], () => { function formatMadgeCircularModules(circularModules: string[][]): string { return circularModules.map((modulePaths: string[]) => `\n - ${modulePaths.join(' > ')}`).join(''); } - -/** Creates a gulp task function that will run TSLint together with ts-node. */ -function execTsLintTask(...flags: string[]) { - const tslintBinPath = resolveBin.sync('tslint'); - const tsNodeOptions = ['-O', '{"module": "commonjs"}']; - - // TS-Node needs the module compiler option to be set to `commonjs` because the transpiled - // TypeScript files will be running inside of NodeJS. - return execNodeTask('ts-node', [...tsNodeOptions, tslintBinPath, ...tsLintBaseFlags, ...flags]); -} diff --git a/tools/tslint-rules/noViewEncapsulationRule.ts b/tools/tslint-rules/noViewEncapsulationRule.ts index 9b130174d50..196aa37ae34 100644 --- a/tools/tslint-rules/noViewEncapsulationRule.ts +++ b/tools/tslint-rules/noViewEncapsulationRule.ts @@ -35,17 +35,17 @@ class Walker extends Lint.RuleWalker { this._enabled = fileGlobs.some(p => minimatch(relativeFilePath, p)); } - visitClassDeclaration(node) { + visitClassDeclaration(node: ts.ClassDeclaration) { if (!this._enabled || !node.decorators) { return; } node.decorators - .map(decorator => decorator.expression) + .map(decorator => decorator.expression as any) .filter(expression => expression.expression.getText() === 'Component') .filter(expression => expression.arguments.length && expression.arguments[0].properties) .forEach(expression => { - const hasTurnedOffEncapsulation = expression.arguments[0].properties.some(prop => { + const hasTurnedOffEncapsulation = expression.arguments[0].properties.some((prop: any) => { const value = prop.initializer.getText(); return prop.name.getText() === 'encapsulation' && value.endsWith('.None'); }); diff --git a/tools/tslint-rules/tsLoaderRule.js b/tools/tslint-rules/tsLoaderRule.js new file mode 100644 index 00000000000..4ba565f1b9d --- /dev/null +++ b/tools/tslint-rules/tsLoaderRule.js @@ -0,0 +1,13 @@ +const path = require('path'); +const Lint = require('tslint'); + +// Custom rule that registers all of the custom rules, written in TypeScript, with ts-node. +// This is necessary, because `tslint` and IDEs won't execute any rules that aren't in a .js file. +require('ts-node').register({ + project: path.join(__dirname, '../gulp/tsconfig.json') +}); + +// Add a noop rule so tslint doesn't complain. +exports.Rule = class Rule extends Lint.Rules.AbstractRule { + apply() {} +} diff --git a/tslint.json b/tslint.json index 911ffe3cf7a..af2c655674a 100644 --- a/tslint.json +++ b/tslint.json @@ -85,7 +85,7 @@ "linebreak-style": [true, "LF"], // Custom Rules - + "ts-loader": true, "no-exposed-todo": true, "no-view-encapsulation": [ true,