@@ -26,13 +26,13 @@ module.exports = function lint (args = {}, api, silent) {
2626
2727 const patchWriteFile = ( ) => {
2828 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 } `
3636 }
3737 return writeFileSync ( file , content , options )
3838 }
@@ -42,22 +42,50 @@ module.exports = function lint (args = {}, api, silent) {
4242 fs . writeFileSync = writeFileSync
4343 }
4444
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+
4559 const parseTSFromVueFile = file => {
60+ file = path . normalize ( file )
4661 // If the file has already been cached, don't read the file again. Use the cache instead.
4762 if ( vueFileCache . has ( file ) ) {
4863 return vueFileCache . get ( file )
4964 }
5065
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' }
6070 }
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
6189 }
6290
6391 const program = tslint . Linter . createProgram ( api . resolve ( 'tsconfig.json' ) )
@@ -68,7 +96,7 @@ module.exports = function lint (args = {}, api, silent) {
6896 const getSourceFile = program . getSourceFile
6997 program . getSourceFile = function ( file , languageVersion , onError ) {
7098 if ( isVueFile ( file ) ) {
71- const { content, lang = 'js' } = parseTSFromVueFile ( file ) || { content : '' , lang : 'js' }
99+ const { content, lang } = parseTSFromVueFile ( file )
72100 const contentLang = ts . ScriptKind [ lang . toUpperCase ( ) ]
73101 return ts . createSourceFile ( file , content , languageVersion , true , contentLang )
74102 } else {
@@ -93,25 +121,15 @@ module.exports = function lint (args = {}, api, silent) {
93121 . find ( file => fs . existsSync ( file ) )
94122
95123 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- } ) )
104124
105125 const lint = file => {
106126 const filePath = api . resolve ( file )
107- const isVue = isVueFile ( file )
108127 patchWriteFile ( )
109128 linter . lint (
110129 // append .ts so that tslint apply TS rules
111130 filePath ,
112131 '' ,
113- // use Vue config to ignore blank lines
114- isVue ? vueConfig : config
132+ config
115133 )
116134 restoreWriteFile ( )
117135 }
0 commit comments