Skip to content

Commit 00c2044

Browse files
committed
Merge pull request MoOx#86 from cssnext/watch-imported
Watch imported
2 parents c6db9de + af5b78f commit 00c2044

File tree

7 files changed

+114
-14
lines changed

7 files changed

+114
-14
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# 1.2.0 - 2015-04-02
22

33
- Added: pseudoElements single colon fallback for pseudoElements double colons
4+
- Added: `--watch` CLI option now checks for changes in imported files
45

56
# 1.1.0 - 2015-03-05
67

bin/cssnext.js

Lines changed: 56 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,55 @@ if (input && !fs.existsSync(input)) {
8484

8585
config.from = input
8686

87+
// init & adjust watcher with postcss-import dependencies
88+
var watcher
89+
if (config.watch) {
90+
if (!input || !output) {
91+
console.error(colors.red("--watch option need both <input> & <output> files to work"))
92+
exit(3)
93+
}
94+
95+
watcher = require("chokidar").watch(input, {ignoreInitial: true})
96+
97+
// watch `@import`ed files
98+
if (config.import) {
99+
// keep a up to date list of imported files
100+
var importedFiles = [input]
101+
var arrayDiff = function(array, array2) {
102+
return array.filter(function(i) {
103+
return array2.indexOf(i) < 0
104+
})
105+
}
106+
107+
var watcherOnImport = function(imported) {
108+
var filesToUnWatch = arrayDiff(importedFiles, imported)
109+
console.log("unwtach: ", filesToUnWatch)
110+
watcher.unwatch(filesToUnWatch)
111+
importedFiles = imported
112+
console.log("add:", importedFiles)
113+
watcher.add(importedFiles)
114+
}
115+
116+
// import need an object so we can pass onImport() cb
117+
if (typeof config.import !== "object") {
118+
config.import = {}
119+
}
120+
121+
// keep the existing onImport callback if any
122+
if (config.import.onImport) {
123+
config.import.onImport = function(files) {
124+
var originalOnImport = config.import.onImport
125+
watcherOnImport(files)
126+
originalOnImport(files)
127+
}
128+
}
129+
// or just add the watcher updater onImport() cb
130+
else {
131+
config.import.onImport = watcherOnImport
132+
}
133+
}
134+
}
135+
87136
function transform() {
88137
require("read-file-stdin")(input, function(err, buffer) {
89138
if (err) {
@@ -119,15 +168,13 @@ function transform() {
119168

120169
transform()
121170

122-
if (config.watch) {
123-
if (!input || !output) {
124-
console.error(colors.red("--watch option need both <input> & <output> files to work"))
125-
exit(3)
126-
}
127-
require("node-watch")(input, transform)
128-
if (verbose) {
129-
log(colors.cyan("Watching"), input)
130-
}
171+
if (watcher) {
172+
watcher.on("ready", function() {
173+
if (verbose) {
174+
log(colors.cyan("Watching"), input)
175+
}
176+
watcher.on("all", transform)
177+
})
131178
}
132179

133180
/**

index.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,12 +110,12 @@ function cssnext(string, options) {
110110

111111
// features
112112
Object.keys(cssnext.features).forEach(function(key) {
113-
// feature is enabled if: not force disable && (force enabled || no data yet || !supported yet)
113+
// feature is auto enabled if: not disable && (enabled || no data yet || !supported yet)
114114
if (
115-
// feature is force disabled
115+
// feature is not disabled
116116
features[key] !== false &&
117117
(
118-
// feature is forced enabled
118+
// feature is enabled
119119
features[key] === true ||
120120

121121
// feature don't have any browsers data (yet)

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,11 @@
2929
"dependencies": {
3030
"autoprefixer-core": "^5.0.0",
3131
"caniuse-api": "^1.2.1",
32+
"chokidar": "^1.0.0-rc4",
3233
"colors": "^1.0.2",
3334
"commander": "^2.3.0",
3435
"csswring": "^3.0.0",
3536
"exit": "^0.1.2",
36-
"node-watch": "^0.3.4",
3737
"object-assign": "^2.0.0",
3838
"pixrem": "^1.1.0",
3939
"pleeease-filters": "^1.0.0",

test/cli.js

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
* Test dependencies
33
*/
44
var exec = require("child_process").exec
5+
var fs = require("fs")
56

67
var test = require("tape")
78

@@ -41,7 +42,7 @@ test("cli", function(t) {
4142
childProcess.stdin.end()
4243
planned+=1
4344

44-
exec(cssnextBin + " test/fixtures/cli.wtf.css", function(err, stdout, stderr) {
45+
exec(cssnextBin + " test/fixtures/cli.dont-exist.css", function(err, stdout, stderr) {
4546
t.ok(err && err.code === 1, "should return an error when input file is unreadable")
4647
t.ok(utils.contains(stderr, "Unable to read file"), "should show that the input file is not found")
4748
})
@@ -133,6 +134,7 @@ test("cli", function(t) {
133134
t.ok(err && err.signal === "SIGTERM", "should only be killed by an interrupt when `--watch` option passed")
134135
if (err && !err.killed) { throw err }
135136
})
137+
136138
var msgWatch = "should output error messages when `--watch` option passed"
137139
var watchTimeout = setTimeout(function() {
138140
t.fail(msgWatch)
@@ -146,6 +148,54 @@ test("cli", function(t) {
146148
}
147149
})
148150
planned+=2
151+
152+
// watch/import tests
153+
var watchOut = "test/fixtures/cli.output--watch-import.css"
154+
var watchImportProcess = exec(cssnextBin + " --watch test/fixtures/cli.watch-import.css " + watchOut, function(err) {
155+
if (err && !err.killed) { throw err }
156+
})
157+
158+
// watch an empty file doesn't seems to work great, so I am using
159+
// /**/ to get a content
160+
// yeah...
161+
162+
// trigger a change in cli.import.css to add a new watched file cli.import2.css
163+
fs.writeFileSync("test/fixtures/cli.watch-import.css", "/**/ @import 'cli.watch-import-import.css';")
164+
165+
// we are using setTimeout for the watcher to do his job
166+
setTimeout(function() {
167+
// check the output has been updated (watcher works)
168+
t.equal(fs.readFileSync(watchOut, {encoding:"utf8"}), "/**/ watch{}", "should update the file")
169+
170+
// remove this newly imported file
171+
fs.writeFileSync("test/fixtures/cli.watch-import.css", "/**/")
172+
173+
// check the output has been update
174+
setTimeout(function() {
175+
t.equal(fs.readFileSync(watchOut, {encoding:"utf8"}), "/**/", "should update the file, again")
176+
177+
// previously imported file should not be watched anymore
178+
// to check that we read output mtime, modify the file that should not be watched
179+
// and check back that the output file has the same mtime
180+
var outStat = fs.statSync(watchOut)
181+
setTimeout(function() {
182+
// trigger a change in previously imported file
183+
var now = (new Date()).getTime()
184+
fs.utimesSync("test/fixtures/cli.watch-import-import.css", now, now)
185+
186+
setTimeout(function() {
187+
// this time, it should not trigger anything
188+
var outStatAfter = fs.statSync(watchOut)
189+
t.equal(outStat.mtime.getTime(), outStatAfter.mtime.getTime(), "should not modify a file if a previously imported file is modified")
190+
191+
utils.remove("cli.output--watch-import")
192+
watchImportProcess.kill()
193+
}, 2000)
194+
}, 2000)
195+
}, 2000)
196+
}, 2000)
197+
198+
planned+=3
149199
}
150200

151201
t.plan(planned)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
watch{}

test/fixtures/cli.watch-import.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/**/

0 commit comments

Comments
 (0)