Closed stinoga closed 9 years ago
That's a tough one. So you've got some imports that come from your stylus options.paths
, and you want to selectively compile your dest
css based on src
files that have modified imports?
The grunt-newer
task only works with a multi-task's files
config (which may be generated by separate src
and dest
properties if files
is not present). It doesn't reach out into other tasks' options (like paths
). So I don't think this is going to be possible.
The only general solution I can think of right now (related to grunt-newer
) would be to add an isNewer
option that would be called for every source file considered. Then if the return from isNewer
was true
or the source file had been modified since the corresponding dest file (or last successful run if no dest file), it would be included. But this would require that you supply an isNewer
function that parsed your @import
s and decided if the resolved imports had been modified. Sounds like too much work.
To be clear, here's what the isNewer
option might look like:
grunt.initConfig({
newer: {
options: {
isNewer: function(taskName, targetName, srcPath, time, callback) {
if (taskName === 'stylus') {
resolveImports(srcPath, function(imports) {
anyNewer(imports, time, callback);
});
}
}
}
} // ... other task config
});
And you would have to provide the resolveImports
(call callback with paths to @import
ed files) and anyNewer
(call callback with true
if any of the provided files have mtimes more recent than time
) functions. They wouldn't have to be async, but it still seems like more pain than gain perhaps.
Hmmmm... that could work though, and may still be a good bit faster that compiling every stylus file. I'll give it a look. Thanks Tim!
Note that the code above won't work currently. I was just thinking about what it might look like if the isNewer
option were implemented (it is not yet). Just trying to gage if this sounded like a potential solution.
@stinoga if you want to experiment, you can replace your grunt-newer
install with this branch: https://github.com/tschaub/grunt-newer/tree/is-newer (maybe easiest if you manually remove node_modules/grunt-newer
, and edit your package.json
to have grunt-newer
point to https://github.com/tschaub/grunt-newer#is-newer
).
Note that the signature for the isNewer
function is (taskName, targetName, srcPath, time, callback)
. That's a bit awkward, but it should give you what you need.
:+1: Having the same issue with LESS, and this type of generic solution could work quite well.
@tschaub I'm looking into an implementation of what you suggested above. Apart from writing the @import parsing function, how do I get access to the anyNewer
function:
resolveImports(srcPath, function(imports) {
anyNewer(imports, time, callback);
});
I'm not understanding the relationship of how to access the util library within the grunt-newer module inside of my own project's Gruntfile.js.
@samtsai with the isNewer
option, you'd have to provide something like resolveImports
and anyNewer
. Here's an quick (untested) implementation of an anyNewer
function that takes an array of paths and calls the callback with true
if any of the files has an mtime
greater than the provided time.
var fs = require('fs');
var async = require('async');
function newer(pathname, time, callback) {
fs.stat(pathname, function(err, stats) {
callback(stats && stats.mtime > timestamp);
});
}
function anyNewer(paths, time, callback) {
async.some(paths, newer, callback);
}
Since this would be a common pattern, I'll see about supporting a different option - called something like additionalSrc
. That would take a function like the resolveImports
above. Then the task itself could do the timestamp comparison.
This would be huge. Just switched to grunt and newer falls down with stylus without this addition. Recompiling all the files is a massive hit on the workflow so it would be great to have this.
See #35 for a new proposed solution.
Trying to use grunt-newer on a large enterprise site using Stylus, so that we only compile the files necessary, rather than all stylus files every time one is changed.
This is working great, however if a
.styl
file is updated that is imported into parent files, we need to update those as well. Any ideas on how to accomplish that without touching every file that has an@import
call?