@@ -26,38 +26,66 @@ module.exports = function lint (args = {}, api, silent) {
26
26
27
27
const patchWriteFile = ( ) => {
28
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
- }
29
+ const parts = vueFileCache . get ( path . normalize ( file ) )
30
+ if ( ! parts ) {
31
+ return writeFileSync ( file , content , options )
36
32
}
37
- return writeFileSync ( file , content , options )
33
+
34
+ // update cached content
35
+ parts . content = content
36
+
37
+ content = content . slice ( parts . paddingOffset )
38
+ // remove one leading and trailing linebreak, if any
39
+ content = content . replace ( / ^ \r ? \n / , '' ) . replace ( / \r ? \n $ / , '' )
40
+
41
+ const { before, after } = parts
42
+
43
+ return writeFileSync ( file , `${ before } \n${ content } \n${ after } ` , options )
38
44
}
39
45
}
40
46
41
47
const restoreWriteFile = ( ) => {
42
48
fs . writeFileSync = writeFileSync
43
49
}
44
50
51
+ const padContent = ( parts ) => {
52
+ const lineCount = parts . before . split ( / \r ? \n / g) . length
53
+ const padding = Array ( lineCount ) . join ( '//\n' )
54
+
55
+ parts . content = padding + parts . content
56
+ parts . paddingOffset = padding . length
57
+ }
58
+
45
59
const parseTSFromVueFile = file => {
60
+ file = path . normalize ( file )
46
61
// If the file has already been cached, don't read the file again. Use the cache instead.
47
62
if ( vueFileCache . has ( file ) ) {
48
63
return vueFileCache . get ( file )
49
64
}
50
65
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
66
+ const fileContent = fs . readFileSync ( file , 'utf-8' )
67
+ const { start, end, content, lang } = vueCompiler . parseComponent ( fileContent ) . script || { }
68
+ if ( ! / ^ t s x ? $ / . test ( lang ) ) {
69
+ return { content : '' , lang : 'js' }
70
+ }
71
+
72
+ const parts = {
73
+ before : fileContent . slice ( 0 , start ) ,
74
+ after : fileContent . slice ( end ) ,
75
+ content,
76
+ lang,
77
+ paddingOffset : 0
60
78
}
79
+ vueFileCache . set ( file , parts )
80
+
81
+ // FIXME pad script content
82
+ // this should be done by vueCompiler.parseComponent with options { pad: 'line' },
83
+ // but it does this only if no lang is set, so it does not work for lang="ts".
84
+ // https://github.com/vuejs/vue/blob/dev/src/sfc/parser.js#L119
85
+ // we do it here until upstream dep supports this correctly
86
+ padContent ( parts )
87
+
88
+ return parts
61
89
}
62
90
63
91
const program = tslint . Linter . createProgram ( api . resolve ( 'tsconfig.json' ) )
@@ -68,7 +96,7 @@ module.exports = function lint (args = {}, api, silent) {
68
96
const getSourceFile = program . getSourceFile
69
97
program . getSourceFile = function ( file , languageVersion , onError ) {
70
98
if ( isVueFile ( file ) ) {
71
- const { content, lang = 'js' } = parseTSFromVueFile ( file ) || { content : '' , lang : 'js' }
99
+ const { content, lang } = parseTSFromVueFile ( file )
72
100
const contentLang = ts . ScriptKind [ lang . toUpperCase ( ) ]
73
101
return ts . createSourceFile ( file , content , languageVersion , true , contentLang )
74
102
} else {
@@ -93,25 +121,15 @@ module.exports = function lint (args = {}, api, silent) {
93
121
. find ( file => fs . existsSync ( file ) )
94
122
95
123
const config = tslint . Configuration . findConfiguration ( tslintConfigPath ) . results
96
- // create a patched config that disables the blank lines rule,
97
- // so that we get correct line numbers in error reports for *.vue files.
98
- const vueConfig = Object . assign ( config )
99
- const rules = vueConfig . rules = new Map ( vueConfig . rules )
100
- const rule = rules . get ( 'no-consecutive-blank-lines' )
101
- rules . set ( 'no-consecutive-blank-lines' , Object . assign ( { } , rule , {
102
- ruleSeverity : 'off'
103
- } ) )
104
124
105
125
const lint = file => {
106
126
const filePath = api . resolve ( file )
107
- const isVue = isVueFile ( file )
108
127
patchWriteFile ( )
109
128
linter . lint (
110
129
// append .ts so that tslint apply TS rules
111
130
filePath ,
112
131
'' ,
113
- // use Vue config to ignore blank lines
114
- isVue ? vueConfig : config
132
+ config
115
133
)
116
134
restoreWriteFile ( )
117
135
}
0 commit comments