11var eslint = require ( "eslint" )
22var assign = require ( "object-assign" )
33var loaderUtils = require ( "loader-utils" )
4- var crypto = require ( "crypto" )
5- var fs = require ( "fs" )
6- var findCacheDir = require ( "find-cache-dir" )
74var objectHash = require ( "object-hash" )
8- var os = require ( "os" )
5+ var pkg = require ( "./package.json" )
6+ var createCache = require ( "loader-fs-cache" )
7+ var cache = createCache ( "eslint-loader" )
98
109var engines = { }
11- var rules = { }
12- var cache = null
13- var cachePath = null
1410
1511/**
16- * linter
12+ * printLinterOutput
1713 *
18- * @param {String|Buffer } input JavaScript string
14+ * @param {Object } eslint.executeOnText return value
1915 * @param {Object } config eslint configuration
2016 * @param {Object } webpack webpack instance
2117 * @return {void }
2218 */
23- function lint ( input , config , webpack ) {
24- var resourcePath = webpack . resourcePath
25- var cwd = process . cwd ( )
26-
27- // remove cwd from resource path in case webpack has been started from project
28- // root, to allow having relative paths in .eslintignore
29- if ( resourcePath . indexOf ( cwd ) === 0 ) {
30- resourcePath = resourcePath . substr ( cwd . length + 1 )
31- }
32-
33- // get engine
34- var configHash = objectHash ( config )
35- var engine = engines [ configHash ]
36- var rulesHash = rules [ configHash ]
37-
38- var res
39- // If cache is enable and the data are the same as in the cache, just
40- // use them
41- if ( config . cache ) {
42- // just get rules hash once per engine for performance reasons
43- if ( ! rulesHash ) {
44- rulesHash = objectHash ( engine . getConfigForFile ( resourcePath ) )
45- rules [ configHash ] = rulesHash
46- }
47- var inputMD5 = crypto . createHash ( "md5" ) . update ( input ) . digest ( "hex" )
48- if (
49- cache [ resourcePath ] &&
50- cache [ resourcePath ] . hash === inputMD5 &&
51- cache [ resourcePath ] . rules === rulesHash
52- ) {
53- res = cache [ resourcePath ] . res
54- }
55- }
56-
57- // Re-lint the text if the cache off or miss
58- if ( ! res ) {
59- res = engine . executeOnText ( input , resourcePath , true )
60-
61- // Save new results in the cache
62- if ( config . cache ) {
63- cache [ resourcePath ] = {
64- hash : inputMD5 ,
65- rules : rulesHash ,
66- res : res ,
67- }
68- fs . writeFileSync ( cachePath , JSON . stringify ( cache ) )
69- }
70- }
71-
72- // executeOnText ensure we will have res.results[0] only
73-
19+ function printLinterOutput ( res , config , webpack ) {
7420 // skip ignored file warning
75- if ( ! (
76- res . warningCount === 1 &&
77- res . results [ 0 ] . messages [ 0 ] &&
78- res . results [ 0 ] . messages [ 0 ] . message &&
79- res . results [ 0 ] . messages [ 0 ] . message . indexOf ( "ignore" ) > 1
80- ) ) {
21+ if (
22+ ! ( res . warningCount === 1 &&
23+ res . results [ 0 ] . messages [ 0 ] &&
24+ res . results [ 0 ] . messages [ 0 ] . message &&
25+ res . results [ 0 ] . messages [ 0 ] . message . indexOf ( "ignore" ) > 1 )
26+ ) {
8127 // quiet filter done now
8228 // eslint allow rules to be specified in the input between comments
8329 // so we can found warnings defined in the input itself
8430 if ( res . warningCount && config . quiet ) {
8531 res . warningCount = 0
8632 res . results [ 0 ] . warningCount = 0
87- res . results [ 0 ] . messages = res . results [ 0 ] . messages
88- . filter ( function ( message ) {
89- return message . severity !== 1
90- } )
33+ res . results [ 0 ] . messages = res . results [ 0 ] . messages . filter ( function (
34+ message
35+ ) {
36+ return message . severity !== 1
37+ } )
9138 }
9239
9340 // if enabled, use eslint auto-fixing where possible
@@ -128,19 +75,21 @@ function lint(input, config, webpack) {
12875 if ( emitter ) {
12976 emitter ( messages )
13077 if ( config . failOnError && res . errorCount ) {
131- throw new Error ( "Module failed because of a eslint error.\n"
132- + messages )
78+ throw new Error (
79+ "Module failed because of a eslint error.\n" + messages
80+ )
13381 }
13482 else if ( config . failOnWarning && res . warningCount ) {
135- throw new Error ( "Module failed because of a eslint warning.\n"
136- + messages )
83+ throw new Error (
84+ "Module failed because of a eslint warning.\n" + messages
85+ )
13786 }
13887 }
13988 else {
14089 throw new Error (
14190 "Your module system doesn't support emitWarning. " +
142- "Update available? \n" +
143- messages
91+ "Update available? \n" +
92+ messages
14493 )
14594 }
14695 }
@@ -155,45 +104,78 @@ function lint(input, config, webpack) {
155104 * @return {void }
156105 */
157106module . exports = function ( input , map ) {
107+ var webpack = this
108+
158109 var config = assign (
159110 // loader defaults
160111 {
161112 formatter : require ( "eslint/lib/formatters/stylish" ) ,
113+ cacheIdentifier : JSON . stringify ( {
114+ "eslint-loader" : pkg . version ,
115+ eslint : eslint . version ,
116+ config : configHash ,
117+ } ) ,
162118 } ,
163119 // user defaults
164- this . options . eslint || { } ,
120+ webpack . options . eslint || { } ,
165121 // loader query string
166- loaderUtils . getOptions ( this )
122+ loaderUtils . getOptions ( webpack )
167123 )
168- this . cacheable ( )
169-
170124 // Create the engine only once per config
171125 var configHash = objectHash ( config )
172126 if ( ! engines [ configHash ] ) {
173127 engines [ configHash ] = new eslint . CLIEngine ( config )
174128 }
175129
176- // Read the cached information only once and if enable
177- if ( cache === null ) {
178- if ( config . cache ) {
179- var thunk = findCacheDir ( {
180- name : "eslint-loader" ,
181- thunk : true ,
182- create : true ,
183- } )
184- cachePath = thunk ( "data.json" ) || os . tmpdir ( ) + "/data.json"
185- try {
186- cache = require ( cachePath )
187- }
188- catch ( e ) {
189- cache = { }
130+ var cacheDirectory = config . cacheDirectory
131+ var cacheIdentifier = config . cacheIdentifier
132+
133+ delete config . cacheDirectory
134+ delete config . cacheIdentifier
135+
136+ webpack . cacheable ( )
137+
138+ var resourcePath = webpack . resourcePath
139+ var cwd = process . cwd ( )
140+
141+ // remove cwd from resource path in case webpack has been started from project
142+ // root, to allow having relative paths in .eslintignore
143+ if ( resourcePath . indexOf ( cwd ) === 0 ) {
144+ resourcePath = resourcePath . substr ( cwd . length + 1 )
145+ }
146+
147+ var engine = engines [ configHash ]
148+ // return early if cached
149+ if ( config . cache ) {
150+ var callback = webpack . async ( )
151+ return cache (
152+ {
153+ directory : cacheDirectory ,
154+ identifier : cacheIdentifier ,
155+ options : config ,
156+ transform : function ( ) {
157+ return lint ( engine , input , resourcePath )
158+ } ,
159+ } ,
160+ function ( err , res ) {
161+ if ( err ) {
162+ return callback ( err )
163+ }
164+ //eslint-disable-next-line
165+ console . log ( lint ( engine , input , resourcePath ) ) ;
166+ printLinterOutput (
167+ res || lint ( engine , input , resourcePath ) ,
168+ config ,
169+ webpack
170+ )
171+ return callback ( null , input , map )
190172 }
191- }
192- else {
193- cache = false
194- }
173+ )
195174 }
175+ printLinterOutput ( lint ( engine , input , resourcePath ) , config , webpack )
176+ webpack . callback ( input , map )
177+ }
196178
197- lint ( input , config , this )
198- this . callback ( null , input , map )
179+ function lint ( engine , input , resourcePath ) {
180+ return engine . executeOnText ( input , resourcePath , true )
199181}
0 commit comments