1- module . exports = function lint ( args = { } , api , silent ) {
2- const cwd = api . resolve ( '.' )
3- const fs = require ( 'fs' )
4- const path = require ( 'path' )
5- const globby = require ( 'globby' )
6- const tslint = require ( 'tslint' )
7- const ts = require ( 'typescript' )
8- /* eslint-disable-next-line node/no-extraneous-require */
9- const vueCompiler = require ( 'vue-template-compiler' )
10- const isVueFile = file => / \. v u e ( \. t s ) ? $ / . test ( file )
11-
12- const options = {
13- fix : args [ 'fix' ] !== false ,
14- formatter : args . format || 'codeFrame' ,
15- formattersDirectory : args [ 'formatters-dir' ] ,
16- rulesDirectory : args [ 'rules-dir' ]
17- }
18-
19- // hack to make tslint --fix work for *.vue files:
20- // we save the non-script parts to a cache right before
21- // linting the file, and patch fs.writeFileSync to combine the fixed script
22- // back with the non-script parts.
23- // this works because (luckily) tslint lints synchronously.
24- const vueFileCache = new Map ( )
25- const writeFileSync = fs . writeFileSync
26-
27- const patchWriteFile = ( ) => {
28- fs . writeFileSync = ( file , content , options ) => {
29- if ( isVueFile ( file ) ) {
30- const parts = vueFileCache . get ( path . normalize ( file ) )
31- if ( parts ) {
32- parts . content = content
33- const { before, after } = parts
34- content = `${ before } \n${ content . trim ( ) } \n${ after } `
35- }
1+ const fs = require ( 'fs' )
2+ const path = require ( 'path' )
3+ const globby = require ( 'globby' )
4+ const tslint = require ( 'tslint' )
5+ const ts = require ( 'typescript' )
6+ /* eslint-disable-next-line node/no-extraneous-require */
7+ const vueCompiler = require ( 'vue-template-compiler' )
8+
9+ const isVueFile = file => / \. v u e ( \. t s ) ? $ / . test ( file )
10+
11+ // hack to make tslint --fix work for *.vue files:
12+ // we save the non-script parts to a cache right before
13+ // linting the file, and patch fs.writeFileSync to combine the fixed script
14+ // back with the non-script parts.
15+ // this works because (luckily) tslint lints synchronously.
16+ const vueFileCache = new Map ( )
17+ const writeFileSync = fs . writeFileSync
18+
19+ const patchWriteFile = ( ) => {
20+ fs . writeFileSync = ( file , content , options ) => {
21+ if ( isVueFile ( file ) ) {
22+ const parts = vueFileCache . get ( path . normalize ( file ) )
23+ if ( parts ) {
24+ parts . content = content
25+ const { before, after } = parts
26+ content = `${ before } \n${ content . trim ( ) } \n${ after } `
3627 }
37- return writeFileSync ( file , content , options )
3828 }
29+ return writeFileSync ( file , content , options )
3930 }
31+ }
4032
41- const restoreWriteFile = ( ) => {
42- fs . writeFileSync = writeFileSync
43- }
44-
45- const parseTSFromVueFile = file => {
46- // If the file has already been cached, don't read the file again. Use the cache instead.
47- if ( vueFileCache . has ( file ) ) {
48- return vueFileCache . get ( file )
49- }
33+ const restoreWriteFile = ( ) => {
34+ fs . writeFileSync = writeFileSync
35+ }
5036
51- const content = fs . readFileSync ( file , 'utf-8' )
52- const { script } = vueCompiler . parseComponent ( content , { pad : 'line' } )
53- if ( script && / ^ t s x ? $ / . test ( script . lang ) ) {
54- vueFileCache . set ( file , {
55- before : content . slice ( 0 , script . start ) ,
56- after : content . slice ( script . end ) ,
57- content : script . content
58- } )
59- return script
60- }
37+ const parseTSFromVueFile = file => {
38+ // If the file has already been cached, don't read the file again. Use the cache instead.
39+ if ( vueFileCache . has ( file ) ) {
40+ return vueFileCache . get ( file )
6141 }
6242
63- const program = tslint . Linter . createProgram ( api . resolve ( 'tsconfig.json' ) )
43+ const content = fs . readFileSync ( file , 'utf-8' )
44+ const { script } = vueCompiler . parseComponent ( content , { pad : 'line' } )
45+ if ( script && / ^ t s x ? $ / . test ( script . lang ) ) {
46+ vueFileCache . set ( file , {
47+ before : content . slice ( 0 , script . start ) ,
48+ after : content . slice ( script . end ) ,
49+ content : script . content
50+ } )
51+ return script
52+ }
53+ }
6454
65- // patch getSourceFile for *.vue files
66- // so that it returns the <script> block only
67- const patchProgram = program => {
68- const getSourceFile = program . getSourceFile
69- program . getSourceFile = function ( file , languageVersion , onError ) {
70- if ( isVueFile ( file ) ) {
71- const { content, lang = 'js' } = parseTSFromVueFile ( file ) || { content : '' , lang : 'js' }
72- const contentLang = ts . ScriptKind [ lang . toUpperCase ( ) ]
73- return ts . createSourceFile ( file , content , languageVersion , true , contentLang )
74- } else {
75- return getSourceFile . call ( this , file , languageVersion , onError )
76- }
55+ // patch getSourceFile for *.vue files
56+ // so that it returns the <script> block only
57+ const patchProgram = program => {
58+ const getSourceFile = program . getSourceFile
59+ program . getSourceFile = function ( file , languageVersion , onError ) {
60+ if ( isVueFile ( file ) ) {
61+ const { content, lang = 'js' } = parseTSFromVueFile ( file ) || { content : '' , lang : 'js' }
62+ const contentLang = ts . ScriptKind [ lang . toUpperCase ( ) ]
63+ return ts . createSourceFile ( file , content , languageVersion , true , contentLang )
64+ } else {
65+ return getSourceFile . call ( this , file , languageVersion , onError )
7766 }
7867 }
68+ }
7969
70+ module . exports = function lint ( args = { } , api , silent ) {
71+ const cwd = api . resolve ( '.' )
72+
73+ const program = tslint . Linter . createProgram ( api . resolve ( 'tsconfig.json' ) )
8074 patchProgram ( program )
8175
82- const linter = new tslint . Linter ( options , program )
76+ const linter = new tslint . Linter ( {
77+ fix : args [ 'fix' ] !== false ,
78+ formatter : args . format || 'codeFrame' ,
79+ formattersDirectory : args [ 'formatters-dir' ] ,
80+ rulesDirectory : args [ 'rules-dir' ]
81+ } , program )
8382
8483 // patch linter.updateProgram to ensure every program has correct getSourceFile
8584 const updateProgram = linter . updateProgram
85+ // eslint-disable-next-line no-shadow
8686 linter . updateProgram = function ( ...args ) {
8787 updateProgram . call ( this , ...args )
8888 patchProgram ( this . program )
@@ -102,7 +102,7 @@ module.exports = function lint (args = {}, api, silent) {
102102 ruleSeverity : 'off'
103103 } ) )
104104
105- const lint = file => {
105+ const lintFile = file => {
106106 const filePath = api . resolve ( file )
107107 const isVue = isVueFile ( file )
108108 patchWriteFile ( )
@@ -116,7 +116,7 @@ module.exports = function lint (args = {}, api, silent) {
116116 restoreWriteFile ( )
117117 }
118118
119- const files = args . _ && args . _ . length
119+ const patterns = args . _ && args . _ . length
120120 ? args . _
121121 : [ 'src/**/*.ts' , 'src/**/*.vue' , 'src/**/*.tsx' , 'tests/**/*.ts' , 'tests/**/*.tsx' ]
122122
@@ -125,11 +125,11 @@ module.exports = function lint (args = {}, api, silent) {
125125 // use the raw tslint.json data because config contains absolute paths
126126 const rawTslintConfig = tslint . Configuration . readConfigurationFile ( tslintConfigPath )
127127 const excludedGlobs = rawTslintConfig . linterOptions . exclude
128- excludedGlobs . forEach ( ( g ) => files . push ( '!' + g ) )
128+ excludedGlobs . forEach ( ( g ) => patterns . push ( '!' + g ) )
129129 }
130130
131- return globby ( files , { cwd } ) . then ( files => {
132- files . forEach ( lint )
131+ return globby ( patterns , { cwd } ) . then ( files => {
132+ files . forEach ( lintFile )
133133 if ( silent ) return
134134 const result = linter . getResult ( )
135135 if ( result . output . trim ( ) ) {
0 commit comments