Skip to content

Commit 1bea82e

Browse files
author
Christopher Quadflieg
committed
Revert "chore: remove tslint specific code"
This reverts commit 4ced550.
1 parent 4ced550 commit 1bea82e

File tree

13 files changed

+423
-8
lines changed

13 files changed

+423
-8
lines changed

packages/@vue/cli-plugin-e2e-cypress/__tests__/cypressPlugin.spec.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ test('should work with TS', async () => {
3030
plugins: {
3131
'@vue/cli-plugin-typescript': {
3232
'classComponent': true,
33+
'tsLint': true,
3334
'lintOn': ['save']
3435
},
3536
'@vue/cli-plugin-e2e-cypress': {}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
const fn = require('../lib/convertLintFlags')
2+
3+
test('convert ESLint flags to TSLint flags', () => {
4+
expect(fn(`
5+
/* eslint-disable */
6+
/* eslint-disable no-console, foo-bar, haha */
7+
// eslint-disable-next-line
8+
// eslint-disable-next-line no-console, foo-bar, haha
9+
foo() // eslint-disable-line
10+
foo() // eslint-disable-line no-console, foo-bar, haha
11+
`)).toMatch(`
12+
/* tslint:disable */
13+
/* tslint:disable:no-console, foo-bar, haha */
14+
// tslint:disable-next-line
15+
// tslint:disable-next-line:no-console, foo-bar, haha
16+
foo() // tslint:disable-line
17+
foo() // tslint:disable-line:no-console, foo-bar, haha
18+
`)
19+
})

packages/@vue/cli-plugin-typescript/__tests__/tsGenerator.spec.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,12 @@ test('use with router', async () => {
8181
})
8282

8383
test('lint', async () => {
84-
const { pkg } = await generateWithPlugin([
84+
const { pkg, files } = await generateWithPlugin([
8585
{
8686
id: 'ts',
8787
apply: require('../generator'),
8888
options: {
89+
tsLint: true,
8990
lintOn: ['save', 'commit']
9091
}
9192
}
@@ -98,6 +99,8 @@ test('lint', async () => {
9899
'*.ts': ['vue-cli-service lint', 'git add'],
99100
'*.vue': ['vue-cli-service lint', 'git add']
100101
})
102+
103+
expect(files['tslint.json']).toBeTruthy()
101104
})
102105

103106
test('lint with no lintOnSave', async () => {
@@ -106,6 +109,7 @@ test('lint with no lintOnSave', async () => {
106109
id: 'ts',
107110
apply: require('../generator'),
108111
options: {
112+
tsLint: true,
109113
lintOn: ['commit']
110114
}
111115
}
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
jest.setTimeout(30000)
2+
3+
const create = require('@vue/cli-test-utils/createTestProject')
4+
5+
test('should work', async () => {
6+
const project = await create('ts-tslint', {
7+
plugins: {
8+
'@vue/cli-plugin-typescript': {
9+
tsLint: true
10+
}
11+
}
12+
})
13+
const { read, write, run } = project
14+
const main = await read('src/main.ts')
15+
expect(main).toMatch(';')
16+
const app = await read('src/App.vue')
17+
expect(main).toMatch(';')
18+
// remove semicolons
19+
const updatedMain = main.replace(/;/g, '')
20+
await write('src/main.ts', updatedMain)
21+
// for Vue file, only remove semis in script section
22+
const updatedApp = app.replace(/<script(.|\n)*\/script>/, $ => {
23+
return $.replace(/;/g, '')
24+
})
25+
await write('src/App.vue', updatedApp)
26+
// lint
27+
await run('vue-cli-service lint')
28+
expect(await read('src/main.ts')).toMatch(';')
29+
30+
const lintedApp = await read('src/App.vue')
31+
expect(lintedApp).toMatch(';')
32+
// test if tslint is fixing vue files properly
33+
expect(lintedApp).toBe(app)
34+
})
35+
36+
test('should not fix with --no-fix option', async () => {
37+
const project = await create('ts-tslint-nofix', {
38+
plugins: {
39+
'@vue/cli-plugin-typescript': {
40+
tsLint: true
41+
}
42+
}
43+
})
44+
const { read, write, run } = project
45+
const main = await read('src/main.ts')
46+
expect(main).toMatch(';')
47+
const app = await read('src/App.vue')
48+
expect(main).toMatch(';')
49+
// remove semicolons
50+
const updatedMain = main.replace(/;/g, '')
51+
await write('src/main.ts', updatedMain)
52+
// for Vue file, only remove semis in script section
53+
const updatedApp = app.replace(/<script(.|\n)*\/script>/, $ => {
54+
return $.replace(/;/g, '')
55+
})
56+
await write('src/App.vue', updatedApp)
57+
58+
// lint with no fix should fail
59+
try {
60+
await run('vue-cli-service lint --no-fix')
61+
} catch (e) {
62+
expect(e.code).toBe(1)
63+
expect(e.failed).toBeTruthy()
64+
}
65+
66+
// files should not have been fixed
67+
expect(await read('src/main.ts')).not.toMatch(';')
68+
expect((await read('src/App.vue')).match(/<script(.|\n)*\/script>/)[1]).not.toMatch(';')
69+
})
70+
71+
test('should ignore issues in node_modules', async () => {
72+
const project = await create('ts-lint-node_modules', {
73+
plugins: {
74+
'@vue/cli-plugin-typescript': {
75+
tsLint: true
76+
}
77+
}
78+
})
79+
80+
const { read, write, run } = project
81+
const main = await read('src/main.ts')
82+
83+
// update file to not match tslint spec and dump it into the node_modules directory
84+
const updatedMain = main.replace(/;/g, '')
85+
await write('node_modules/bad.ts', updatedMain)
86+
87+
// lint
88+
await run('vue-cli-service lint')
89+
expect(await read('node_modules/bad.ts')).toMatch(updatedMain)
90+
})
91+
92+
test('should be able to fix mixed line endings', async () => {
93+
const project = await create('ts-lint-mixed-line-endings', {
94+
plugins: {
95+
'@vue/cli-plugin-typescript': {
96+
tsLint: true
97+
}
98+
}
99+
})
100+
101+
const { write, run } = project
102+
103+
const b64 = 'PHRlbXBsYXRlPjwvdGVtcGxhdGU+DQoNCjxzY3JpcHQgbGFuZz0idHMiPg0KZXhwb3J0IGRlZmF1bHQgY2xhc3MgVGVzdCAgew0KICBnZXQgYXNzaWduZWUoKSB7DQogICAgdmFyIGl0ZW1zOnt0ZXh0OnN0cmluZzsgdmFsdWU6c3RyaW5nIHwgbnVtYmVyIHwgbnVsbH1bXSA9IFtdOw0KICAgIHJldHVybiBpdGVtczsNCiAgfQ0KDQp9DQo8L3NjcmlwdD4NCg0K'
104+
const buf = Buffer.from(b64, 'base64')
105+
106+
await write('src/bad.vue', buf)
107+
108+
// Try twice to fix the file.
109+
// For now, it will fail the first time, which corresponds to the behaviour of tslint.
110+
try {
111+
await run('vue-cli-service lint -- src/bad.vue')
112+
} catch (e) { }
113+
114+
await run('vue-cli-service lint -- src/bad.vue')
115+
})

packages/@vue/cli-plugin-typescript/generator/convert.js

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
module.exports = (api, { convertJsToTs = true } = {}) => {
1+
module.exports = (api, { tsLint = false, convertJsToTs = true } = {}) => {
22
const jsRE = /\.js$/
33
const excludeRE = /^tests\/e2e\/|(\.config|rc)\.js$/
4+
const convertLintFlags = require('../lib/convertLintFlags')
45
api.postProcessFiles(files => {
56
if (convertJsToTs) {
67
// delete all js files that have a ts file of the same name
@@ -9,7 +10,10 @@ module.exports = (api, { convertJsToTs = true } = {}) => {
910
if (jsRE.test(file) && !excludeRE.test(file)) {
1011
const tsFile = file.replace(jsRE, '.ts')
1112
if (!files[tsFile]) {
12-
const content = files[file]
13+
let content = files[file]
14+
if (tsLint) {
15+
content = convertLintFlags(content)
16+
}
1317
files[tsFile] = content
1418
}
1519
delete files[file]
@@ -18,7 +22,10 @@ module.exports = (api, { convertJsToTs = true } = {}) => {
1822
} else {
1923
// rename only main file to main.ts
2024
const tsFile = api.entryFile.replace(jsRE, '.ts')
21-
const content = files[api.entryFile]
25+
let content = files[api.entryFile]
26+
if (tsLint) {
27+
content = convertLintFlags(content)
28+
}
2229
files[tsFile] = content
2330
delete files[api.entryFile]
2431
}

packages/@vue/cli-plugin-typescript/generator/index.js

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
module.exports = (api, {
22
classComponent,
3+
tsLint,
34
lintOn = [],
45
convertJsToTs,
56
allowJs
@@ -23,6 +24,42 @@ module.exports = (api, {
2324
})
2425
}
2526

27+
if (tsLint) {
28+
api.extendPackage({
29+
scripts: {
30+
lint: 'vue-cli-service lint'
31+
}
32+
})
33+
34+
if (!lintOn.includes('save')) {
35+
api.extendPackage({
36+
vue: {
37+
lintOnSave: false
38+
}
39+
})
40+
}
41+
42+
if (lintOn.includes('commit')) {
43+
api.extendPackage({
44+
devDependencies: {
45+
'lint-staged': '^9.5.0'
46+
},
47+
gitHooks: {
48+
'pre-commit': 'lint-staged'
49+
},
50+
'lint-staged': {
51+
'*.ts': ['vue-cli-service lint', 'git add'],
52+
'*.vue': ['vue-cli-service lint', 'git add']
53+
}
54+
})
55+
}
56+
57+
// lint and fix files on creation complete
58+
api.onCreateComplete(() => {
59+
return require('../lib/tslint')({}, api, true)
60+
})
61+
}
62+
2663
// late invoke compat
2764
if (invoking) {
2865
if (api.hasPlugin('unit-mocha')) {
@@ -47,5 +84,5 @@ module.exports = (api, {
4784
hasJest: api.hasPlugin('unit-jest')
4885
})
4986

50-
require('./convert')(api, { convertJsToTs })
87+
require('./convert')(api, { tsLint, convertJsToTs })
5188
}

packages/@vue/cli-plugin-typescript/generator/template/src/shims-tsx.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ import Vue, { VNode } from 'vue'
22

33
declare global {
44
namespace JSX {
5+
// tslint:disable no-empty-interface
56
interface Element extends VNode {}
7+
// tslint:disable no-empty-interface
68
interface ElementClass extends Vue {}
79
interface IntrinsicElements {
810
[elem: string]: any
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<%_ if (options.tsLint) { _%>
2+
{
3+
"defaultSeverity": "warning",
4+
"extends": [
5+
"tslint:recommended"
6+
],
7+
"linterOptions": {
8+
"exclude": [
9+
"node_modules/**"
10+
]
11+
},
12+
"rules": {
13+
"indent": [true, "spaces", 2],
14+
"interface-name": false,
15+
"no-consecutive-blank-lines": false,
16+
"object-literal-sort-keys": false,
17+
"ordered-imports": false,
18+
"quotemark": [true, "single"]
19+
}
20+
}
21+
<%_ } _%>

packages/@vue/cli-plugin-typescript/index.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
const path = require('path')
22

33
module.exports = (api, projectOptions) => {
4+
const fs = require('fs')
45
const useThreads = process.env.NODE_ENV === 'production' && !!projectOptions.parallel
56

67
api.chainWebpack(config => {
@@ -82,10 +83,26 @@ module.exports = (api, projectOptions) => {
8283
.plugin('fork-ts-checker')
8384
.use(require('fork-ts-checker-webpack-plugin'), [{
8485
vue: true,
86+
tslint: projectOptions.lintOnSave !== false && fs.existsSync(api.resolve('tslint.json')),
8587
formatter: 'codeframe',
8688
// https://github.com/TypeStrong/ts-loader#happypackmode-boolean-defaultfalse
8789
checkSyntacticErrors: useThreads
8890
}])
8991
}
9092
})
93+
94+
if (!api.hasPlugin('eslint')) {
95+
api.registerCommand('lint', {
96+
description: 'lint source files with TSLint',
97+
usage: 'vue-cli-service lint [options] [...files]',
98+
options: {
99+
'--format [formatter]': 'specify formatter (default: codeFrame)',
100+
'--no-fix': 'do not fix errors',
101+
'--formatters-dir [dir]': 'formatter directory',
102+
'--rules-dir [dir]': 'rules directory'
103+
}
104+
}, args => {
105+
return require('./lib/tslint')(args, api)
106+
})
107+
}
91108
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
module.exports = function convertLintFlags (file) {
2+
return file
3+
.replace(/\/\*\s?eslint-(enable|disable)([^*]+)?\*\//g, (_, $1, $2) => {
4+
if ($2) $2 = $2.trim()
5+
return `/* tslint:${$1}${$2 ? `:${$2}` : ``} */`
6+
})
7+
.replace(/\/\/\s?eslint-disable-(next-)?line(.+)?/g, (_, $1, $2) => {
8+
if ($2) $2 = $2.trim()
9+
return `// tslint:disable-${$1 || ''}line${$2 ? `:${$2}` : ``}`
10+
})
11+
}

0 commit comments

Comments
 (0)