grunt让Nodejs规范起来

从零开始nodejs系列文章,将介绍如何利Javascript做为服务端脚本,通过Nodejs框架web开发。Nodejs框架是基于V8的引擎,是目前速度最快的Javascript引擎。chrome浏览器就基于V8,同时打开20-30个网页都很流畅。Nodejs标准的web开发框架Express,可以帮助我们迅速建立web站点,比起PHP的开发效率更高,而且学习曲线更低。非常适合小型网站,个性化网站,我们自己的Geek网站!!

关于作者

  • 张丹(Conan), 程序员Java,R,PHP,Javascript
  • weibo:@Conan_Z
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/nodejs-grunt-intro/

grunt

前言
一个应用开发到一定阶段,普遍会遇到一个问题。当功能越来越多,代码量越来越大,bug修复越来越频繁,开发人员一波一波的交替,…..应该用会向着越来越不可控发展。我们不能再准确估计新功能的开发时间,也不知道一个bug修复后是否会引发另一个bug出现。所有的程序开发,都会面临着这样的问题。

C/C++程序通过makefile管理编译测试打包的过程,Java程序通过Maven,Ant实现项目构建管理功能,Python有pip,Ruby有gem。在Nodejs的领域,我们同样需要一个项目构建工具,这就是Grunt。Grunt可以执行像压缩, 编译, 单元测试, 代码检查以及打包发布的任务。

目录

  1. Grunt介绍
  2. Grunt安装
  3. Grunt使用
  4. Grunt常用插件:
    1).grunt-contrib-uglify:压缩js代码
    2).grunt-contrib-concat:合并js文件
    3).grunt-contrib-qunit:单元测试
    4).grunt-contrib-jshint:js代码检查
    5).grunt-contrib-watch:文件监控

1. Grunt介绍

Grunt是一个自动化的项目构建工具. 如果你需要重复的执行像压缩, 编译, 单元测试, 代码检查以及打包发布的任务. 那么你可以使用Grunt来处理这些任务, 你所需要做的只是配置好Grunt, 这样能很大程度的简化你的工作.

如果在团队中使用Grunt, 你只需要与其他人员约定好使用Grunt应该规避的问题, 就能够很方便的自动化的处理大部分的常见工作任务, 你所付出的努力几乎为0.

2. Grunt安装

Grunt和Grunt插件都是通过npm, Node.js包管理器安装和管理的.

我的系统环境

  • win7 64bit
  • Nodejs:v0.10.5
  • Npm:1.2.19
~ D:\workspace\javascript>node -v
v0.10.5

~ D:\workspace\javascript>npm -v
1.2.19

在系统中,我们已经安装好了Nodejs和npm。win7安装nodejs请参考文章:Nodejs开发框架Express3.0开发手记–从零开始

安装grunt-cli
grunt-cli并不grunt,grunt-cli的作用是管理本地各版本的grunt,让命令行可以直接执行grunt命令。

下面全局安装grunt-cli(-g)


~ D:\workspace\javascript>npm install -g grunt-cli

D:\toolkit\nodejs\grunt -> D:\toolkit\nodejs\node_modules\grunt-cli\bin\grunt
grunt-cli@0.1.9 D:\toolkit\nodejs\node_modules\grunt-cli
├── resolve@0.3.1
├── nopt@1.0.10 (abbrev@1.0.4)
└── findup-sync@0.1.2 (lodash@1.0.1, glob@3.1.21)

我们看到grunt-cli似乎做了一个软件链接,把grunt脚本复制到nodejs安装根目录里。

接下来全局安装grunt


~ D:\workspace\javascript>npm install -g grunt

~ D:\workspace\javascript>grunt
grunt-cli: The grunt command line interface. (v0.1.9)

Fatal error: Unable to find local grunt.

If you're seeing this message, either a Gruntfile wasn't found or grunt
hasn't been installed locally to your project. For more information about
installing and configuring grunt, please see the Getting Started guide:

http://gruntjs.com/getting-started

执行grunt命令,我们发现系统报错了,提示不能加载本地库。因为,grunt命令执行,是需要当前目录中包括package.json和Gruntfile.js两个文件。

package.json,是npm项目配置文件
Gruntfile.js,是专门用来配置grunt的配置文件

接下来,我们创建一个express3的项目。


~ D:\workspace\javascript>express -e nodejs-grunt
~ D:\workspace\javascript>cd nodejs-grunt && npm install	 
~ D:\workspace\javascript\nodejs-grunt>npm install grunt --save-dev

安装-save-dev,就可以,直接把grunt作为devDependencies写入的package.json中。


~ vi package.json

{
  "name": "nodejs-grunt",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node app.js"
  },
  "dependencies": {
    "express": "3.2.2",
    "ejs": "*"
  },
  "devDependencies": {
    "grunt": "~0.4.1",
  }
}

然后,我们再执行grunt,系统提示缺少Gruntfile文件


~ D:\workspace\javascript\nodejs-grunt>grunt
A valid Gruntfile could not be found. Please see the getting started guide for
more information on how to configure grunt: http://gruntjs.com/getting-started
Fatal error: Unable to find Gruntfile.

创建Gruntfile文件


~ vi Gruntfile.js

module.exports = function(grunt) {
  // Project configuration.
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    uglify: {
      options: {
        banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
      },
      build: {
        src: 'src/<%= pkg.name %>.js',
        dest: 'build/<%= pkg.name %>.min.js'
      }
    }
  });
  // Load the plugin that provides the "uglify" task.
  grunt.loadNpmTasks('grunt-contrib-uglify');
  // Default task(s).
  grunt.registerTask('default', ['uglify']);
};

再次运行grunt,这时提示是grunt-contrib-uglify包找不到,是Gruntfile.js配置文件中的错误了。


~ D:\workspace\javascript\nodejs-grunt>grunt
>> Local Npm module "grunt-contrib-uglify" not found. Is it installed?
Warning: Task "uglify" not found. Use --force to continue.

我们编辑package.js, 在devDependencies中增加grunt-contrib-uglify的依赖库


~ vi package.js
{
  "name": "application-name",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node app.js"
  },
  "dependencies": {
    "express": "3.2.2",
    "ejs": "*"
  },
  "devDependencies": {
    "grunt": "~0.4.1"
    "grunt-contrib-uglify": "~0.1.1"
  }
}

~ D:\workspace\javascript\nodejs-grunt>npm install

我们创建两个目录src和build,和nodejs-grunt.js的文件


~ D:\workspace\javascript\nodejs-grunt>mkdir src
~ D:\workspace\javascript\nodejs-grunt>mkdir build

~ D:\workspace\javascript\nodejs-grunt>vi src/nodejs-grunt.js
var sayHello = function(name){
	return "Hello " + name;
}

我们再执行grunt


~ D:\workspace\javascript\nodejs-grunt>grunt
Running "uglify:build" (uglify) task
File "build/nodejs-grunt.min.js" created.
Uncompressed size: 59 bytes.
Compressed size: 40 bytes gzipped (43 bytes minified).

Done, without errors.

grunt运行正常,并且执行了uglify:build的任务。打开build/nodejs-grunt.min.js文件

~ D:\workspace\javascript\nodejs-grunt>vi build/nodejs-grunt.min.js

/*! nodejs-grunt 2013-08-17 */
var sayHello=function(l){return"Hello "+l};

我们可以看到一个新生成的压缩文件nodejs-grunt.min.js。

上面的例子,是一个js文件压缩的例子。

3. Grunt使用

我们可以通过help帮助,看一下grunt怎么用。


~ D:\workspace\javascript\nodejs-grunt>grunt --help
Grunt: The JavaScript Task Runner (v0.4.1)

Usage
 grunt [options] [task [task ...]]

Options
    --help, -h  Display this help text.
        --base  Specify an alternate base path. By default, all file paths are
                relative to the Gruntfile. (grunt.file.setBase) *
    --no-color  Disable colored output.
   --gruntfile  Specify an alternate Gruntfile. By default, grunt looks in the
                current or parent directories for the nearest Gruntfile.js or
                Gruntfile.coffee file.
   --debug, -d  Enable debugging mode for tasks that support it.
       --stack  Print a stack trace when exiting with a warning or fatal error.
   --force, -f  A way to force your way past warnings. Want a suggestion? Don't
                use this option, fix your code.
       --tasks  Additional directory paths to scan for task and "extra" files.
                (grunt.loadTasks) *
         --npm  Npm-installed grunt plugins to scan for task and "extra" files.
                (grunt.loadNpmTasks) *
    --no-write  Disable writing files (dry run).
 --verbose, -v  Verbose mode. A lot more information output.
 --version, -V  Print the grunt version. Combine with --verbose for more info.
  --completion  Output shell auto-completion rules. See the grunt-cli
                documentation for more information.

Options marked with * have methods exposed via the grunt API and should instead
be specified inside the Gruntfile wherever possible.

Available tasks
        uglify  Minify files with UglifyJS. *
       default  Alias for "uglify" task.

Tasks run in the order specified. Arguments may be passed to tasks that accept
them by using colons, like "lint:files". Tasks marked with * are "multi tasks"
and will iterate over all sub-targets if no argument is specified.

The list of available tasks may change based on tasks directories or grunt
plugins specified in the Gruntfile or via command-line options.

For more information, see http://gruntjs.com/

有两方面是我们需要注意的:

  1. Options: grunt支持的命令
  2. Available tasks: 当目录可执行的任务

4. Grunt常用插件

  • grunt-contrib-uglify:压缩js代码
  • grunt-contrib-concat:合并js文件
  • grunt-contrib-qunit:单元测试
  • grunt-contrib-jshint:js代码检查
  • grunt-contrib-watch:监控文件修改并重新执行注册的任务

1). grunt-contrib-uglify:是执行压缩JS代码的任务
具体操作请查看”2.Grunt安装”,

2). grunt-contrib-concat:是执行合并文件的任务。
插件安装及更新到配置


~ D:\workspace\javascript\nodejs-grunt>npm install grunt-contrib-concat --save-dev

修改Gruntfile.js文件


grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    concat:{
      options: {
        //定义一个字符串插入没个文件之间用于连接输出
        separator: ';'
      },
      dist: {
          src: ['src/*.js'],
          dest: 'build/<%= pkg.name %>.cat.js'
      }
    },
  });
grunt.loadNpmTasks('grunt-contrib-qunit');
grunt.registerTask('default', ['uglify','concat']);

在src目录,新增加文件src/sayBye.js


~ vi src/sayBye.js

var sayBye = function(name){
	return "Bye " + name;
}

执行concat任务


~ D:\workspace\javascript\nodejs-grunt>grunt concat
Running "concat:dist" (concat) task
File "build/nodejs-grunt.cat.js" created.

Done, without errors.

查看生成的文件build/nodejs-grunt.cat.js


~ vi build/nodejs-grunt.cat.js

var sayHello = function(name){
	return "Hello " + name;
};var sayBye = function(name){
	return "Bye " + name;
}

两个文件完全的合并。

3). grunt-contrib-qunit:是执行QUint单元测试的任务。

插件安装及更新到配置


~ D:\workspace\javascript\nodejs-grunt>npm install grunt-contrib-qunit --save-dev

修改Gruntfile.js文件


grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    qunit: {
      files: ['test/*.html']
    }
  });
grunt.loadNpmTasks('grunt-contrib-qunit');
grunt.registerTask('default', ['uglify','concat','qunit']);

创建一个test目录,并编写用于测试的qunit.html文件


~ mkdir test
~ vi test/qunit.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="http://github.com/jquery/qunit/raw/master/qunit/qunit.css" type="text/css" media="screen" />
<script type="text/javascript" src="http://github.com/jquery/qunit/raw/master/qunit/qunit.js"></script>
<script>
test("hello", function() {
ok(true, "world");
});
</script>
</head>
<body>
<h1 id="qunit-header">QUnit example</h1>
<h2 id="qunit-banner"></h2>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol>
</body>
</html>

执行qunit命令


~ D:\workspace\javascript\nodejs-grunt>grunt qunit
Running "qunit:files" (qunit) task
Testing test/qunit.html .OK
>> 1 assertions passed (67ms)

Done, without errors.

完成单元测试!!

4). grunt-contrib-jshint:是执行代码验证的任务
插件安装及更新到配置


~ D:\workspace\javascript\nodejs-grunt>npm install grunt-contrib-jshint --save-dev

修改Gruntfile.js文件


grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    jshint: {
        files: ['gruntfile.js', 'src/*.js', 'build/*.js'],
        options: {
            globals: {
                exports: true
            }
        }
    }
  });
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.registerTask('default', ['uglify','concat','qunit','jshint']);

执行jshint代码检查


~ D:\workspace\javascript\nodejs-grunt>grunt jshint
Running "jshint:files" (jshint) task
Linting src/nodejs-grunt.js ...ERROR
[L3:C2] W033: Missing semicolon.
}
Linting build/nodejs-grunt.cat.js ...ERROR
[L5:C2] W033: Missing semicolon.
}
Linting build/nodejs-grunt.min.js ...ERROR
[L2:C42] W033: Missing semicolon.
var sayHello=function(l){return"Hello "+l};

Warning: Task "jshint:files" failed. Use --force to continue.

Aborted due to warnings.

好多的错误啊,细看一下,都是”丢失分号”的错误。


~ vi src/sayBye.js
var sayBye = function(name){
	return "Bye " + name;
};

增加最后一行的分号,解决上面的错误。

5). grunt-contrib-watch,是监控指定文件被修改,重新启动已注册的任务
我感觉这个插入,就点类似于supervisor的功能。

插件安装及更新到配置


~ D:\workspace\javascript\nodejs-grunt>npm install grunt-contrib-watch --save-dev

修改Gruntfile.js文件


grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    watch: {
        files: ['<%= jshint.files %>'],
        tasks: ['jshint', 'qunit']
    }
  });
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('default', ['uglify','concat','qunit','jshint']);

执行watch任务


~ D:\workspace\javascript\nodejs-grunt>grunt watch
Running "watch" task
Waiting...OK

#手动修改src/sayBye.js文件,下面watch的任务被触发
>> File "src\sayBye.js" changed.

Running "jshint:files" (jshint) task
Linting src/sayBye.js ...ERROR
[L3:C2] W033: Missing semicolon.
}
Linting build/nodejs-grunt.cat.js ...ERROR
[L3:C3] W032: Unnecessary semicolon.
};;var sayBye = function(name){
Linting build/nodejs-grunt.min.js ...ERROR
[L2:C42] W033: Missing semicolon.
var sayHello=function(l){return"Hello "+l};

Warning: Task "jshint:files" failed. Use --force to continue.

Aborted due to warnings.
Completed in 0.770s at Sat Aug 17 2013 20:49:15 GMT+0800 (中国标准时间) - Waiting...

上面介绍的5个任务,可能是我们比较常用配置的任务,大家也可以按照需要指定自己的任务。

下面贴上所最终的package.json和Gruntfile.js文件代码

package.json


{
  "name": "nodejs-grunt",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node app.js"
  },
  "dependencies": {
    "express": "3.2.2",
    "ejs": "*"
  },
  "devDependencies": {
    "grunt": "~0.4.1",
    "grunt-contrib-uglify": "~0.1.1",
    "grunt-contrib-concat": "~0.3.0",
    "grunt-contrib-qunit": "~0.2.2",
    "grunt-contrib-jshint": "~0.6.3",
    "grunt-contrib-watch": "~0.5.2"
  }
}

Gruntfile.js


module.exports = function(grunt) {

  // Project configuration.
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    uglify: {
      options: {
        banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
      },
      build: {
        src: 'src/<%= pkg.name %>.js',
        dest: 'build/<%= pkg.name %>.min.js'
      }
    },
    concat:{
      options: {
        //定义一个字符串插入没个文件之间用于连接输出
        separator: ';'
      },
      dist: {
          src: ['src/*.js'],
          dest: 'build/<%= pkg.name %>.cat.js'
      }
    },
    qunit: {
      files: ['test/*.html']
    },
    jshint: {
        files: ['gruntfile.js', 'src/*.js', 'build/*.js'],
        options: {
            globals: {
                exports: true
            }
        }
    },
    watch: {
        files: ['<%= jshint.files %>'],
        tasks: ['jshint', 'qunit']
    }
  });

  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-qunit');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-watch');

  // Default task(s).
  grunt.registerTask('default', ['uglify','concat','qunit','jshint']);

};

转载请注明出处:
http://blog.fens.me/nodejs-grunt-intro/

打赏作者

This entry was posted in Javascript语言实践

0 0 votes
Article Rating
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

35 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments

[…] grunt:请参考,grunt让Nodejs规范起来 […]

[…] Nodejs领域: Jasmine做单元测试,Karma自动化完成单元测试,Grunt启动Karma统一项目管理,Yeoman最后封装成一个项目原型模板,npm做nodejs的包依赖管理,bower做javascript的包依赖管理。Java领域:JUnit做单元测试, Maven自动化单元测试,统一项目管理,构建项目原型模板,包依赖管理。 […]

hidoos

grunt很强大啊!使用yeoman可以搭建项目框架,就更方便了,不过感觉grunt学起来挺复杂的,yeoman就更复杂了!

Conan Zhang

grunt只是一个自动化管理工具,本身并不复杂,复杂度可能源于第三方的插件。

比如单元测试,要用到karma, jasmine等插件,你可能不熟悉karam, jasmine。这些其实并不属于grunt。

yeoman也很简单就是,构建一个项目模板。同样地,需要第三方的插件来支持。http://blog.fens.me/nodejs-yeoman-intro/

所以,我们可以理解为,grunt和yeoman是管理第三方插件的工具。当你的项目足够大,用到几十个,几百个第三方插件的时候。grunt,yeoman能非常优雅的管理好项目。

taffy

最近在用grunt,文档讲的很清楚,从头至尾走了一遍,有收获。

Conan Zhang

🙂

Paul

张哥, 有个问题请教一下, 为什么服务器上grunt启动后, 只能在服务器本地访问, 外网不能访问呢?

我在弄reveal.js, grunt启动后, 外网打不开, 但在服务器wget是可以拿到文件的. 还是nodejs初学者, 还请指教

code:
// Serve presentation locally
grunt.registerTask( ‘serve’, [ ‘connect’, ‘watch’ ] );

grunt serve –port 8001

Conan Zhang

1. grunt主要被用在开发环境,不适合部署在生产环境,因为性能不太好。
2. 对外网的服务器,直接用node吧

Paul

好的, 谢谢, 虽不明但觉厉, 以后常来学习 😉

Chris Tam

npm install -g grunt这个应该可以不用安装了,Grunt.js 0.4之后,其不再使用全局方式安装整个Grunt.js,而是在全局安装Grunt.js Client,然后在当前项目中安装Grunt,来避免未来不同项目对Grunt不同版本的依赖关系。

如果安装了之前的版本,可以使用npm的命令来删除掉原来的Grunt.js。

npm uninstall -g grunt

然后安装Grunt.js Client:

npm install -g grunt-cli

Conan Zhang

文章快一年了,可能会有了一些变化!等我有时间,再用新版本做一遍吧。

箜箜

还没时间吗? 一路error下来………….

Conan Zhang

实在不好意思,还是没有时间更新这里。
我建议你可以选择用gulp,配置文件用js取代了json结构,比grunt要简单一些,我现在项目都转到gulp了。

箜 箜

那 希望博主 来一篇 gulp 的教程~~

Conan Zhang

嗯,有时间就写。

anna miu

嗯,卸载了。。

[…] 项目管理:npm,grunt, bower, yeoman […]

[…] 通过本文的介绍,我们基本上了解了uglifyJS2包的功能和使用方法,然后就可以放心大胆地对JS代码进行压缩了。在实际的前端项目中,一般不用自己配置uglifyJS2包,而是通过grunt来调用uglifyJS2进行代码发布前的压缩,关于grunt使用,请参考文章:grunt让Nodejs规范起来。 […]

mokingone

文章写的很清楚,学习了。

Conan Zhang

🙂

QuenTine

你好,我用了yeoman的angular-fullstack插件创建了一个项目,按照网上流传的方式配置了webstorm的运行设置(就是把Javascript file 里写grunt路径、参数写grunt参数的那个),运行可以启动服务器,但是debug就不能启动,停在”concurrent:server” (concurrent) task上。(

前面是:

Running “serve” task
[D] Task source: /home/quentine/WebstormProjects/paotuanke/Gruntfile.js

Running “clean:server” (clean) task
[D] Task source: /home/quentine/WebstormProjects/paotuanke/node_modules/grunt-contrib-clean/tasks/clean.js

Running “env:all” (env) task
[D] Task source: /home/quentine/WebstormProjects/paotuanke/node_modules/grunt-env/tasks/env.js

Running “injector:less” (injector) task
[D] Task source: /home/quentine/WebstormProjects/paotuanke/node_modules/grunt-asset-injector/tasks/injector.js
Missing option `template`, using `dest` as template instead
Injecting less files (4 files)
>> Nothing changed

Running “concurrent:server” (concurrent) task
[D] Task source: /home/quentine/WebstormProjects/paotuanke/node_modules/grunt-concurrent/tasks/concurrent.js

如果是run,下一个自动执行的是:

Running “coffee:server” (coffee) task
[D] Task source: /home/quentine/WebstormProjects/paotuanke/node_modules/grunt-contrib-coffee/tasks/coffee.js
File .tmp/app/account/account.js created.
File .tmp/app/account/account.js.map created (source map).
File .tmp/app/account/login/login.js created.
File .tmp/app/account/login/login.js.map created (source map).
File .tmp/app/account/settings/settings.js created.
File .tmp/app/account/settings/settings.js.map created (source map).
File .tmp/app/account/signup/signup.js created.
File .tmp/app/account/signup/signup.js.map created (source map).
File .tmp/app/admin/admin.js created.
File .tmp/app/admin/admin.js.map created (source map).
File .tmp/app/app.js created.
File .tmp/app/app.js.map created (source map).
File .tmp/app/main/main.js created.
File .tmp/app/main/main.js.map created (source map).
File .tmp/components/auth/auth.js created.
File .tmp/components/auth/auth.js.map created (source map).
File .tmp/components/auth/user.js created.
File .tmp/components/auth/user.js.map created (source map).
File .tmp/components/modal/modal.js created.
File .tmp/components/modal/modal.js.map created (source map).
File .tmp/components/mongoose-error/mongoose-error.js created.
File .tmp/components/mongoose-error/mongoose-error.js.map created (source map).
File .tmp/components/navbar/navbar.js created.
File .tmp/components/navbar/navbar.js.map created (source map).
File .tmp/components/socket/socket.js created.
File .tmp/components/socket/socket.js.map created (source map).

Done, without errors.

Execution Time (2014-10-17 12:58:40 UTC)
loading tasks 236ms ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 34%
coffee:server 451ms ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 66%
Total 688ms

Running “jade:compile” (jade) task
[D] Task source: /home/quentine/WebstormProjects/paotuanke/node_modules/grunt-contrib-jade/tasks/jade.js
File .tmp/app/account/login/login.html created.
File .tmp/app/account/settings/settings.html created.
File .tmp/app/account/signup/signup.html created.
File .tmp/app/admin/admin.html created.
File .tmp/app/main/main.html created.
File .tmp/components/modal/modal.html created.
File .tmp/components/navbar/navbar.html created.

Done, without errors.

Execution Time (2014-10-17 12:58:40 UTC)
loading tasks 179ms ▇▇▇▇▇▇▇▇▇▇▇▇ 24%
jade:compile 553ms ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 75%
Total 733ms

Running “less:server” (less) task
[D] Task source: /home/quentine/WebstormProjects/paotuanke/node_modules/grunt-contrib-less/tasks/less.js
File .tmp/app/app.css created: 0 B → 149.29 kB

Done, without errors.

Execution Time (2014-10-17 12:58:40 UTC)
loading tasks 333ms ▇▇▇▇▇▇▇▇▇▇▇▇▇ 26%
less:server 967ms ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 74%
Total 1.3s

Running “injector:scripts” (injector) task
[D] Task source: /home/quentine/WebstormProjects/paotuanke/node_modules/grunt-asset-injector/tasks/injector.js
Missing option `template`, using `dest` as template instead
Injecting js files (13 files)
>> Nothing changed

Running “injector:less” (injector) task
[D] Task source: /home/quentine/WebstormProjects/paotuanke/node_modules/grunt-asset-injector/tasks/injector.js
Missing option `template`, using `dest` as template instead
Injecting less files (4 files)
>> Nothing changed

Running “injector:css” (injector) task
[D] Task source: /home/quentine/WebstormProjects/paotuanke/node_modules/grunt-asset-injector/tasks/injector.js
Missing option `template`, using `dest` as template instead
>> Nothing changed

Running “wiredep:target” (wiredep) task
[D] Task source: /home/quentine/WebstormProjects/paotuanke/node_modules/grunt-wiredep/tasks/wiredep.js

Running “autoprefixer:dist” (autoprefixer) task
[D] Task source: /home/quentine/WebstormProjects/paotuanke/node_modules/grunt-autoprefixer/tasks/autoprefixer.js
File .tmp/app/app.css created.

Running “express:dev” (express) task
[D] Task source: /home/quentine/WebstormProjects/paotuanke/node_modules/grunt-express-server/tasks/express.js
Starting background Express server
debugger listening on port 5858
Express server listening on 9000, in development mode

Running “wait” task
[D] Task source: /home/quentine/WebstormProjects/paotuanke/Gruntfile.js
>> Waiting for server reload…
finished populating users
Done waiting!

Running “open:server” (open) task
[D] Task source: /home/quentine/WebstormProjects/paotuanke/node_modules/grunt-open/tasks/open.js

Running “watch” task
[D] Task source: /home/quentine/WebstormProjects/paotuanke/node_modules/grunt-contrib-watch/tasks/watch.js
Waiting…

请问如何解决。

Conan Zhang

你说的这个插入没有用过,你需要自己查看源代码解决问题。

QuenTine

谢谢张哥

Conan Zhang

也没帮上什么,多交流。 🙂

pbwei

vi /build/nodejs-grunt.min.js
这一步错误 应改为 vi build/nodejs-grunt.min.js

Conan Zhang

同学很仔细,我已经修改了。

kika

hi, Conan, 请教一个问题,grunt.registerTask注册一个自定义任务,执行该任务时如果有报错,grunt如何输出这个错误。

Conan Zhang

默认就会把错误日志输出了

ziyun

Uglification failed. Use –force to continue
老师,这个是怎么回事呢?

Conan Zhang

加个参数吧–force运行

lenchs

PhantomJS timed out, possibly due to a missing QUnit start() call.单元测试报这个错,解决不了,有没有方法?

Conan Zhang

这个不是grunt的问题,检查QUnit 的文档,看文档说明操作。

Grubbyhunter

4 里面 2)这里应该是楼主笔误吧,
grunt.loadNpmTasks(‘grunt-contrib-qunit’);
应该是
grunt.loadNpmTasks(‘grunt-contrib-concat’);

Peach

执行sudo npm install -g gulp时出现如下错误:
npm WARN engine gulp@3.9.0: wanted: {“node”:”>= 0.9″} (current: {“node”:”0.13.0-pre”,”npm”:”2.11.3″})
npm ERR! Linux 3.13.0-48-generic
npm ERR! argv “/usr/local/bin/node” “/usr/local/bin/npm” “install” “-g” “gulp”
npm ERR! node v0.13.0-pre
npm ERR! npm v2.11.3
npm ERR! code ETARGET

npm ERR! notarget No compatible version found: vinyl-fs@’>=0.3.0 <0.4.0'
npm ERR! notarget Valid install targets:
npm ERR! notarget ["0.0.1","0.0.2","0.1.0","1.0.0"]
npm ERR! notarget
npm ERR! notarget This is most likely not a problem with npm itself.
npm ERR! notarget In most cases you or one of your dependencies are requesting
npm ERR! notarget a package version that doesn't exist.
npm ERR! notarget
npm ERR! notarget It was specified as a dependency of 'gulp'
npm ERR! notarget
有人知道为什么吗?

Conan Zhang

网络不通。用换个网络或者用cnpm试试。CNPM介绍http://blog.fens.me/nodejs-cnpm-npm/

35
0
Would love your thoughts, please comment.x
()
x