@@ -26,13 +26,13 @@ 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
+ parts . content = content
32
+ const { before , after } = parts
33
+ content = content . slice ( parts . paddingOffset )
34
+ content += / \r ? \n $ / . test ( content ) ? '' : '\n'
35
+ content = ` ${ before } ${ content } ${ after } `
36
36
}
37
37
return writeFileSync ( file , content , options )
38
38
}
@@ -42,22 +42,50 @@ module.exports = function lint (args = {}, api, silent) {
42
42
fs . writeFileSync = writeFileSync
43
43
}
44
44
45
+ const padContent = ( parts ) => {
46
+ // move trailing newline from opening script tag to the before part
47
+ const firstNewline = parts . content . match ( / ^ \r ? \n / )
48
+ if ( firstNewline ) {
49
+ parts . before += firstNewline [ 0 ]
50
+ parts . content = parts . content . slice ( firstNewline [ 0 ] . length )
51
+ }
52
+
53
+ const newlineCount = parts . before . split ( / \r ? \n / g) . length
54
+ const padding = Array ( newlineCount ) . join ( '//\n' )
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' }
60
70
}
71
+
72
+ const parts = {
73
+ before : fileContent . slice ( 0 , start ) ,
74
+ after : fileContent . slice ( end ) ,
75
+ content,
76
+ lang,
77
+ paddingOffset : 0
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