问题
I'm fairly new to Grunt, so this might be quite a basic question. I've got a Gruntfile.js that looks like this:
/*global module:false*/
module.exports = function (grunt) {
grunt.initConfig({
});
grunt.registerTask('default', 'measureText');
grunt.registerTask('measureText', 'Measures size of text', function() {
grunt.log.writeln('========================================================================');
grunt.log.writeln('= output of ImageMagick should be on next line: =');
var im = require("node-imagemagick");
im.identify(['-format', '%wx%h', 'build/text.png'], function(err, output){
if (err) throw err;
console.log('dimension: '+output); // <-- NOTHING WRITTEN!
});
grunt.log.writeln('========================================================================');
return;
});
};
As you can see, it's calling the node-imagemagick method identify to get the width and height of an image (build/text.png). When I run my grunt script above, there is no output from the identify() callback. (That's the console.log line above).
Yet if I create a Node script (e.g. test-node-imagemagick.js) to test that same code, it works just fine, e.g.
#!/usr/bin/env node
var im = require("node-imagemagick");
im.identify(['-format', '%wx%h', 'build/text.png'], function(err, output){
if (err) throw err;
console.log('dimension: '+output);
});
So how do I call Node packages from within Grunt tasks, and get returned values?
By the way, I did install the package by doing:
$ npm install node-imagemagick
... from the directory that contains the Gruntfile.js.
Thanks!
回答1:
Edit:
The reason your task never completes is because of your ambiguous return at the end:
return; <---
You are disrupting the async call to:
im.identify(function(){
//do async
})
return; //exit task
Try this:
grunt.registerTask('measureText', function(done) {
//omitting code
im.identify(function(){
//do async stuff
done()
})
})
The function argument done() tells the task runner that it should finish after you do something asynchronous instead of ending before any of that code executes.
Original:
Your requires looks very different in each of those scripts.
require('imagemagick')
--- vs ---
require('node-imagemagick')
Grunt is probably swallowing the error
Also, I think its just:
npm install imagemagick
回答2:
I just found the answer by some more digging, here: Using a node module within a Grunt Task fails
Basically, my Grunt task has to be asynchronous if it is to receive a callback:
/*global module:false*/
module.exports = function (grunt) {
var im = require("node-imagemagick");
grunt.initConfig({
});
grunt.registerTask('default', 'measureText');
grunt.registerTask('measureText', 'Measures size of text', function() {
var done = this.async(); // <-- Make the task asynchronous!
grunt.log.writeln('========================================================================');
grunt.log.writeln('= output of ImageMagick should be on next line: =');
im.identify(['-format', '%wx%h', 'build/text.png'], function(err, output){
if (err) throw err;
console.log('dimension: '+output);
done();
});
});
};
Of course, that means that the output would not actually appear between the two lines of equals signs, if I'd kept the second line there.
回答3:
Doing some more research I was able to get this to work. First off, I would switch to this library which was recommended by the imagemagick developer README.
https://github.com/aheckmann/gm
But, that is up to you if you want to use an unmaintained library.
Anyway here it is:
grunt.registerTask('measureText', function(done) {
//omitting code
var done = this.async() //create async task
im.identify('/path/to/image', function(err, output){
//do async stuff
console.log('dimension: %s', output)
done()
})
//or use gm
gm('/path/to/image')
.size(function(err, size) {
console.log('gm size: %s', size)
done()
})
})
来源:https://stackoverflow.com/questions/28597314/retrieving-output-from-node-script-in-a-grunt-task