Skip to content

Commit 097f37a

Browse files
authored
Improve incremental rebuild; use absolute paths internally (#113)
This incremental rebuild is much smarter. Also fixed edge case where a file is both a dependency and an entry point. Using absolute paths internally is a must for reliable smart rebuilding (dependency messages can contain absolute paths). We are calculating the relative path for presentation to the user.
1 parent ffc3b30 commit 097f37a

File tree

3 files changed

+43
-11
lines changed

3 files changed

+43
-11
lines changed

index.js

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ const postcss = require('postcss')
1414
const postcssrc = require('postcss-load-config')
1515
const reporter = require('postcss-reporter/lib/formatter')()
1616

17+
const depGraph = require('./lib/depGraph')
18+
1719
const logo = `
1820
/|\\
1921
// //
@@ -179,6 +181,8 @@ Promise.resolve()
179181
error('Input Error: Must use --dir or --replace with multiple input files')
180182
}
181183

184+
if (i[0] !== 'stdin') i = i.map(i => path.resolve(i))
185+
182186
input = i
183187

184188
return files(input)
@@ -195,15 +199,18 @@ Promise.resolve()
195199
watcher
196200
.on('ready', (file) => console.warn(chalk.bold.cyan('Waiting for file changes...')))
197201
.on('change', (file) => {
198-
if (input.indexOf(file) === -1) {
199-
return files(input)
200-
.then((results) => watcher.add(dependencies(results)))
201-
.then(() => console.warn(chalk.bold.cyan('Waiting for file changes...')))
202-
.catch(error)
203-
}
202+
let recompile = []
203+
204+
if (~input.indexOf(file)) recompile.push(file)
204205

205-
files(file)
206-
.then((result) => watcher.add(dependencies(result)))
206+
recompile = recompile.concat(
207+
depGraph.dependantsOf(file).filter(file => ~input.indexOf(file))
208+
)
209+
210+
if (!recompile.length) recompile = input
211+
212+
return files(recompile)
213+
.then((results) => watcher.add(dependencies(results)))
207214
.then(() => console.warn(chalk.bold.cyan('Waiting for file changes...')))
208215
.catch(error)
209216
})
@@ -256,11 +263,13 @@ function css (css, file) {
256263
if (!argv.config) argv.config = path.dirname(file)
257264
}
258265

266+
const relativePath = file !== 'stdin' ? path.relative(path.resolve(), file) : file
267+
259268
if (!argv.config) argv.config = process.cwd()
260269

261270
const time = process.hrtime()
262271

263-
spinner.text = `Processing ${file}`
272+
spinner.text = `Processing ${relativePath}`
264273
spinner.start()
265274

266275
return rc(ctx, argv.config)
@@ -310,7 +319,7 @@ function css (css, file) {
310319
}
311320
} else {
312321
spinner.text = chalk.bold.green(
313-
`Finished ${file} (${Math.round(process.hrtime(time)[1] / 1e6)}ms)`
322+
`Finished ${relativePath} (${Math.round(process.hrtime(time)[1] / 1e6)}ms)`
314323
)
315324
spinner.succeed()
316325
return process.stdout.write(result.css, 'utf8')
@@ -319,7 +328,7 @@ function css (css, file) {
319328
return Promise.all(tasks)
320329
.then(() => {
321330
spinner.text = chalk.bold.green(
322-
`Finished ${file} (${Math.round(process.hrtime(time)[1] / 1e6)}ms)`
331+
`Finished ${relativePath} (${Math.round(process.hrtime(time)[1] / 1e6)}ms)`
323332
)
324333
if (result.warnings().length) {
325334
spinner.fail()
@@ -345,6 +354,7 @@ function dependencies (results) {
345354

346355
result.messages
347356
.filter((msg) => msg.type === 'dependency' ? msg : '')
357+
.map(depGraph.add)
348358
.forEach((dependency) => messages.push(dependency.file))
349359
})
350360

lib/depGraph.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
const path = require('path')
2+
const DepGraph = require('dependency-graph').DepGraph
3+
4+
const graph = new DepGraph()
5+
6+
exports.add = message => {
7+
message.parent = path.resolve(message.parent)
8+
message.file = path.resolve(message.file)
9+
10+
graph.addNode(message.parent)
11+
graph.addNode(message.file)
12+
graph.addDependency(message.parent, message.file)
13+
return message
14+
}
15+
16+
exports.dependantsOf = node => {
17+
node = path.resolve(node)
18+
19+
if (graph.hasNode(node)) return graph.dependantsOf(node)
20+
return []
21+
}

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
"dependencies": {
1919
"chalk": "^1.1.3",
2020
"chokidar": "^1.6.1",
21+
"dependency-graph": "^0.5.0",
2122
"fs-promise": "^1.0.0",
2223
"get-stdin": "^5.0.1",
2324
"globby": "^6.1.0",

0 commit comments

Comments
 (0)