Skip to content
This repository was archived by the owner on Sep 28, 2020. It is now read-only.

Commit 847f5e0

Browse files
committed
use loader-fs-cache as the caching engine
1 parent d7f003d commit 847f5e0

File tree

4 files changed

+274
-134
lines changed

4 files changed

+274
-134
lines changed

index.js

+82-100
Original file line numberDiff line numberDiff line change
@@ -1,93 +1,40 @@
11
var eslint = require("eslint")
22
var assign = require("object-assign")
33
var loaderUtils = require("loader-utils")
4-
var crypto = require("crypto")
5-
var fs = require("fs")
6-
var findCacheDir = require("find-cache-dir")
74
var 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

109
var 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
*/
157106
module.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
}

package.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,11 @@
2020
},
2121
"dependencies": {
2222
"find-cache-dir": "^0.1.1",
23+
"loader-fs-cache": "^1.0.0",
2324
"loader-utils": "^1.0.2",
2425
"object-assign": "^4.0.1",
25-
"object-hash": "^1.1.4"
26+
"object-hash": "^1.1.4",
27+
"rimraf": "^2.6.1"
2628
},
2729
"devDependencies": {
2830
"ava": "^0.17.0",

0 commit comments

Comments
 (0)