vinllen vinllen - 2 months ago 7
Node.js Question

grunt hang on Running "delta" task

I'm a newbie to node and grunt, all right, the Front-end technology. The grunt is hang on running "delta" task when i execute

grunt live
command:

...
Running "index:build" (index) task
Running "karma:continuous" (karma) task
INFO [karma]: Karma v0.12.37 server started at http://localhost:9018/
INFO [launcher]: Starting browser PhantomJS
INFO [PhantomJS 1.9.8 (Linux 0.0.0)]: Connected on socket suzSULuEb4R90dkkuH9_ with id 66784053
PhantomJS 1.9.8 (Linux 0.0.0) LOG: 'Starting Karma'
........................
PhantomJS 1.9.8 (Linux 0.0.0): Executed 24 of 24 SUCCESS (0.095 secs / 0.089 secs)

Running "connect:dev" (connect) task
Started connect web server on localhost:9000.

Running "delta" task
Waiting...


As shown in the list,
localhost:9000
doesnot work in web server, how to solve this problem ?

Here is my package.json:

{
"author": "Mathieu Lemay",
"name": "opendaylight-dlux",
"description": "openDayLight User eXperience",
"version": "0.2.0",
"homepage": "http://opendaylight.org",
"license": "EPL-1.0",
"bugs": "https://bugs.opendaylight.org/",
"repository": {
"type": "git",
"url": "https://git.opendaylight.org/gerrit/dlux.git"
},
"preferGlobal": true,
"dependencies": {},
"devDependencies": {
"angular-mocks": "~1.2.22",
"bower": "~1.3.12",
"connect-livereload": "^0.2.0",
"connect-modrewrite": "~0.5.4",
"graceful-fs": "^4.1.6",
"grunt": "^0.4.5",
"grunt-bump": "0.0.13",
"grunt-cli": "~0.1.13",
"grunt-coffeelint": "0.0.8",
"grunt-concurrent": "~0.3.0",
"grunt-contrib-clean": "~0.4.1",
"grunt-contrib-coffee": "~0.7.0",
"grunt-contrib-compass": "~0.3.0",
"grunt-contrib-concat": "~0.3.0",
"grunt-contrib-connect": "~0.3.0",
"grunt-contrib-copy": "~0.4.1",
"grunt-contrib-cssmin": "~0.6.0",
"grunt-contrib-htmlmin": "~0.1.3",
"grunt-contrib-imagemin": "~0.1.4",
"grunt-contrib-jshint": "^1.0.0",
"grunt-contrib-less": "~0.8.2",
"grunt-contrib-uglify": "~0.2.0",
"grunt-contrib-watch": "^0.6.1",
"grunt-conventional-changelog": "~1.0.0",
"grunt-google-cdn": "~0.2.0",
"grunt-html2js": "~0.2.4",
"grunt-karma": "~0.8.0",
"grunt-ng-annotate": "~0.3.2",
"grunt-open": "~0.2.0",
"grunt-recess": "~0.5.0",
"grunt-replace": "~0.7.8",
"grunt-rev": "~0.1.0",
"grunt-shell": "~0.7.0",
"grunt-svgmin": "~0.2.0",
"grunt-usemin": "~0.1.11",
"jasmine": "~2.0.1",
"karma": "^0.12.37",
"karma-chrome-launcher": "~0.1.4",
"karma-coffee-preprocessor": "~0.2.1",
"karma-coverage": "~0.2.6",
"karma-firefox-launcher": "~0.1.3",
"karma-jasmine": "~0.1.5",
"karma-phantomjs-launcher": "~0.1.4",
"karma-requirejs": "~0.2.2",
"matchdep": "~0.1.2",
"minimatch": "^3.0.3",
"recess": "^1.1.9",
"requirejs": "~2.1.19",
"ycssmin": "^1.0.1"
},
"engines": {
"node": ">=0.8.0"
},
"scripts": {
"test": "grunt test"
}
}


And here comes my Gruntfile.js, it's a bit complicate:

var lrSnippet = require('connect-livereload')();
var mountFolder = function (connect, dir) {
return connect.static(require('path').resolve(dir));
};

module.exports = function ( grunt ) {

/**
* Load required Grunt tasks. These are installed based on the versions listed
* in `package.json` when you do `npm install` in this directory.
*/
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-conventional-changelog');
grunt.loadNpmTasks('grunt-bump');
//grunt.loadNpmTasks('grunt-recess');
grunt.loadNpmTasks('grunt-shell');
grunt.loadNpmTasks('grunt-karma');
grunt.loadNpmTasks('grunt-ng-annotate');
grunt.loadNpmTasks('grunt-html2js');
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-contrib-connect');
grunt.loadNpmTasks('grunt-open');
grunt.loadNpmTasks('grunt-replace');

/**
* Load in our build configuration file.
*/
var userConfig = require( './build.config.js' );

var envConfig = {

replace: {
development: {
options: {
patterns: [
{
json: grunt.file.readJSON('./config/development.json')
}
]
},
files: [
{
expand: true,
flatten: true,
src: ['./config/env.module.js'],
dest: 'src/common/config/'
}
]
},
production: {
options: {
patterns: [
{
json: grunt.file.readJSON('./config/production.json')
}
]
},
files: [
{
expand: true,
flatten: true,
src: ['./config/env.module.js'],
dest: 'src/common/config/'
}
]
}
}
}

/**
* This is the configuration object Grunt uses to give each plugin its
* instructions.
*/
var taskConfig = {
/**
* We read in our `package.json` file so we can access the package name and
* version. It's already there, so we don't repeat ourselves here.
*/
pkg: grunt.file.readJSON("package.json"),

/**
* The banner is the comment that is placed at the top of our compiled
* source files. It is first processed as a Grunt template, where the `<%=`
* pairs are evaluated based on this very configuration object.
*/
meta: {
banner:
'/**\n' +
' * <%= pkg.name %> - v<%= pkg.version %> - <%= grunt.template.today("yyyy-mm-dd") %>\n' +
' * <%= pkg.homepage %>\n' +
' *\n' +
' * Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author %>\n' +
' * Licensed <%= pkg.licenses.type %> <<%= pkg.licenses.url %>>\n' +
' */\n'
},

/**
* Creates a changelog on a new version.
*/
changelog: {
options: {
dest: 'CHANGELOG.md',
template: 'changelog.tpl'
}
},

/**
* Increments the version number, etc.
*/
bump: {
options: {
files: [
"package.json",
"bower.json"
],
commit: false,
commitMessage: 'chore(release): v%VERSION%',
commitFiles: [
"package.json",
"client/bower.json"
],
createTag: false,
tagName: 'v%VERSION%',
tagMessage: 'Version %VERSION%',
push: false,
pushTo: 'origin'
}
},

/**
* The directories to delete when `grunt clean` is executed.
*/
clean: [
'<%= build_dir %>',
'<%= compile_dir %>'
],

/**
* The `copy` task just copies files from A to B. We use it here to copy
* our project assets (images, fonts, etc.) and javascripts into
* `build_dir`, and then to copy the assets to `compile_dir`.
*/
copy: {
build_app_assets: {
files: [
{
src: [ '**' ],
dest: '<%= build_dir %>/assets/',
cwd: 'src/assets',
expand: true
}
]
},
build_vendor_assets: {
files: [
{
src: [ '<%= vendor_files.assets %>' ],
dest: '<%= build_dir %>/assets/',
cwd: '.',
expand: true,
flatten: true
}
]
},
build_appjs: {
files: [
{
src: [ '<%= app_files.js %>', '<%= app_files.css %>', '<%= app_files.lang %>' ],
dest: '<%= build_dir %>/',
cwd: '.',
expand: true
}
]
},
copy_template: {
files: [
{
src: ['<%= app_files.templates %>'],
dest: '<%= build_dir %>/',
cwd: '.',
expand: true
}
]
},
build_vendorjs: {
files: [
{
src: [ '<%= vendor_files.js %>' ],
dest: '<%= build_dir %>/',
cwd: '.',
expand: true
}
]
},
build_appimages: {
files: [
{
src: [ '<%= app_files.images %>' ],
dest: '<%= build_dir %>/',
cwd: '.',
expand: true
}
]
},
build_vendorimages: {
files: [
{
src: [ '<%= vendor_files.images %>' ],
dest: '<%= build_dir %>/',
cwd: '.',
expand: true
}
]
},
build_vendorcss: {
files: [
{
src: [ '<%= vendor_files.css %>' ],
dest: '<%= build_dir %>',
cwd: '.',
expand: true
}
]
},
compile_assets: {
files: [
{
src: [ '**' ],
dest: '<%= compile_dir %>/assets',
cwd: '<%= build_dir %>/assets',
expand: true
}
]
},

compile_font: {
files: [
{
src: [ '**' ],
dest: '<%= compile_dir %>/font',
cwd: '<%= build_dir %>/font',
expand: true
}
]
}
},

/**
* `grunt concat` concatenates multiple source files into a single file.
*/
concat: {
/**
* The `build_css` target concatenates compiled CSS and vendor CSS
* together.
*/
build_css: {
src: [
'<%= vendor_files.css %>',
'<%= build_dir %>/assets/<%= pkg.name %>-<%= pkg.version %>.css'
],
dest: '<%= build_dir %>/assets/<%= pkg.name %>-<%= pkg.version %>.css'
},
/**
* The `compile_js` target is the concatenation of our application source
* code and all specified vendor source code into a single file.
*/
compile_js: {
options: {
banner: '<%= meta.banner %>'
},
src: [
'<%= vendor_files.js %>',
'module.prefix',
'<%= build_dir %>/src/**/*.js',
'<%= html2js.common.dest %>',
'<%= html2js.app.dest %>',
'module.suffix'
],
dest: '<%= compile_dir %>/assets/<%= pkg.name %>-<%= pkg.version %>.js'
}
},

/**
* `ng-min` annotates the sources before minifying. That is, it allows us
* to code without the array syntax.
*/
ngAnnotate: {
options: {
singleQuotes:true
},
app: {
files: [
{
src: [ '<%= app_files.js %>' ],
cwd: '<%= build_dir %>',
dest: '<%= build_dir %>',
expand: true
}
]
}
},

/**
* Minify the sources!
*/
uglify: {
compile: {
options: {
banner: '<%= meta.banner %>'
},
files: {
'<%= concat.compile_js.dest %>': '<%= concat.compile_js.dest %>'
}
}
},

/**
* `less` less plugin handles the LESS compilation and minification automatically
* this has been changed to the LESS plugin from recess plugin above because of
* out of memory issues with the original plugin.
*/

less: {
development: {
options: {
paths: ["assets/css"],
compress: false,
syncImport: true,
strictImports: true
},
files: {
'<%= build_dir %>/assets/<%= pkg.name %>-<%= pkg.version %>.css': '<%= app_files.less %>'
}
},
production: {
options: {
paths: ["assets/css"],
compress: true,
cleancss: true
},
files: {
'<%= build_dir %>/assets/<%= pkg.name %>-<%= pkg.version %>.css': '<%= app_files.less %>'
}
}
},

/**
* `jshint` defines the rules of our linter as well as which files we
* should check. This file, all javascript sources, and all our unit tests
* are linted based on the policies listed in `options`. But we can also
* specify exclusionary patterns by prefixing them with an exclamation
* point (!); this is useful when code comes from a third party but is
* nonetheless inside `src/`.
*/
jshint: {
src: [
'<%= app_files.js %>',
'<%= app_files.app_assets %>',
],
test: [
'<%= app_files.jsunit %>'
],
gruntfile: [
'OriginalGruntfile.js'
],
options: {
curly: true,
immed: true,
newcap: true,
noarg: true,
sub: true,
boss: true,
eqnull: true
},
globals: {}
},


/**
* HTML2JS is a Grunt plugin that takes all of your template files and
* places them into JavaScript files as strings that are added to
* AngularJS's template cache. This means that the templates too become
* part of the initial payload as one JavaScript file. Neat!
*/
html2js: {
/**
* These are the templates from `src/app`.
*/
app: {
options: {
base: 'src/app'
},
src: [ '<%= app_files.atpl %>' ],
dest: '<%= build_dir %>/templates-app.js'
},

/**
* These are the templates from `src/common`.
*/
common: {
options: {
base: 'src/common'
},
src: [ '<%= app_files.ctpl %>' ],
dest: '<%= build_dir %>/templates-common.js'
}
},

/**
* The Karma configurations.
*/
karma: {
options: {
configFile: '<%= build_dir %>/karma-unit.js'
},
unit: {
runnerPort: 9102,
background: true,
port: 9877 // IMPORTANT!
},
continuous: {
singleRun: true,
browsers: ['PhantomJS']
}
},

/**
* The `index` task compiles the `index.html` file as a Grunt template. CSS
* and JS files co-exist here but they get split apart later.
*/
index: {

/**
* During development, we don't want to have wait for compilation,
* concatenation, minification, etc. So to avoid these steps, we simply
* add all script files directly to the `<head>` of `index.html`. The
* `src` property contains the list of included files.
*/
build: {
dir: '<%= build_dir %>',
src: [
'<%= html2js.common.dest %>',
'<%= html2js.app.dest %>',
'<%= vendor_files.css %>',
'<%= build_dir %>/assets/<%= pkg.name %>-<%= pkg.version %>.css'
]
},

/**
* When it is time to have a completely compiled application, we can
* alter the above to include only a single JavaScript and a single CSS
* file. Now we're back!
*/
compile: {
dir: '<%= compile_dir %>',
src: [
'<%= concat.compile_js.dest %>',
'<%= concat.build_css.dest %>'
//'<%= recess.compile.dest %>'
]
}
},

/**
* This task compiles the karma template so that changes to its file array
* don't have to be managed manually.
*/
karmaconfig: {
unit: {
dir: '<%= build_dir %>',
src: [
'<%= vendor_files.js %>',
'<%= html2js.app.dest %>',
'<%= html2js.common.dest %>',
'<%= app_files.js_common %>',
'<%= app_files.js_app %>',
'<%= app_files.jsunit %>'
]
}
},
connect: {
livereload: {
options: {
port: 9000,
hostname: '0.0.0.0',
middleware: function (connect) {
return [
mountFolder(connect, 'build'),
lrSnippet
];
}
}
},
dev: {
options: {
hostname: '0.0.0.0',
port: 9000,
base: 'build'
}
},
prod: {
options: {
port: 9001,
base: 'bin',
keepalive: true
}
}
},
open: {
dev: {
path: 'http://127.0.0.1:9000/'
},
prod: {
path: 'http://127.0.0.1:9001/'
}
},
/**
* And for rapid development, we have a watch set up that checks to see if
* any of the files listed below change, and then to execute the listed
* tasks when they do. This just saves us from having to type "grunt" into
* the command-line every time we want to see what we're working on; we can
* instead just leave "grunt watch" running in a background terminal. Set it
* and forget it, as Ron Popeil used to tell us.
*
* But we don't need the same thing to happen for all the files.
*/
delta: {
/**
* By default, we want the Live Reload to work for all tasks; this is
* overridden in some tasks (like this file) where browser resources are
* unaffected. It runs by default on port 35729, which your browser
* plugin should auto-detect.
*/
options: {
livereload: true
},

/**
* When the Gruntfile changes, we just want to lint it. In fact, when
* your Gruntfile changes, it will automatically be reloaded!
*/
gruntfile: {
files: 'OriginalGruntfile.js',
tasks: [ 'jshint:gruntfile' ],
options: {
livereload: false
}
},

/**
* When our JavaScript source files change, we want to run lint them and
* run our unit tests.
*/
jssrc: {
files: [
'<%= app_files.js %>', '<%= app_files.lang %>'
],
tasks: [ 'jshint:src', 'karma:unit:run', 'copy:build_appjs' ]
},

/**
* When assets are changed, copy them. Note that this will *not* copy new
* files, so this is probably not very useful.
*/
assets: {
files: [
'src/assets/**/*'
],
tasks: [ 'copy:build_app_assets' ]
},

/**
* When index.html changes, we need to compile it.
*/
html: {
files: [ '<%= app_files.html %>' ],
tasks: [ 'index:build' ]
},

/**
* When our templates change, we only rewrite the template cache.
*/
tpls: {
files: [
'<%= app_files.atpl %>',
'<%= app_files.ctpl %>'
],
tasks: ['copy:copy_template']/*[ 'html2js' ]*/
},

/**
* When the CSS files change, we need to compile and minify them.
*/
less: {
files: [ 'src/**/*.less' ],
tasks: [ 'less:development' ]
},

/**
* When a JavaScript unit test file changes, we only want to lint it and
* run the unit tests. We don't want to do any live reloading.
*/
jsunit: {
files: [
'<%= app_files.jsunit %>'
],
tasks: [ 'jshint:test', 'karma:unit:run' ],
options: {
livereload: false
}
}
},
shell : {
requirejs: {
command: "node node_modules/requirejs/bin/r.js -o optimize.js"
}
}
};

grunt.initConfig( grunt.util._.extend( taskConfig, userConfig, envConfig ) );

/**
* In order to make it safe to just compile or copy *only* what was changed,
* we need to ensure we are starting from a clean, fresh build. So we rename
* the `watch` task to `delta` (that's why the configuration var above is
* `delta`) and then add a new task called `watch` that does a clean build
* before watching for changes.
*/
grunt.renameTask( 'watch', 'delta' );
grunt.registerTask( 'watch', [ 'build', 'karma:unit', 'delta' ] );

grunt.registerTask('live', ['build', 'connect:dev', 'delta']);
/**
* The default task is to build and compile.
*/
grunt.registerTask( 'default', [ 'compile' ] );

/**
* The `build` task gets your app ready to run for development and testing.
*/
grunt.registerTask( 'common', [
'clean', 'html2js', 'jshint', 'concat:build_css', 'less:development',
'copy:build_app_assets', 'copy:build_vendor_assets',
'copy:build_appjs', 'copy:copy_template', 'copy:build_vendorimages', 'copy:build_appimages', 'copy:build_vendorjs', 'copy:build_vendorcss', 'karmaconfig', 'index:build'
]);

grunt.registerTask( 'build', ['replace:development', 'common', 'karma:continuous']);

/**
* The `compile` task gets your app ready for deployment by concatenating and
* minifying your code.
*/
grunt.registerTask( 'compile', ['replace:production', 'common', 'karma:continuous', 'ngAnnotate', 'shell:requirejs']);

/**
* A utility function to get all app JavaScript sources.
*/
function filterForJS ( files ) {
return files.filter( function ( file ) {
return file.match( /\.js$/ );
});
}

/**
* A utility function to get all app CSS sources.
*/
function filterForCSS ( files ) {
return files.filter( function ( file ) {
return file.match( /\.css$/ );
});
}

/**
* The index.html template includes the stylesheet and javascript sources
* based on dynamic names calculated in this Gruntfile. This task assembles
* the list into variables for the template to use and then runs the
* compilation.
*/
grunt.registerMultiTask( 'index', 'Process index.html template', function () {
var dirRE = new RegExp( '^('+grunt.config('build_dir')+'|'+grunt.config('compile_dir')+')\/', 'g' );
var jsFiles = filterForJS( this.filesSrc ).map( function ( file ) {
return file.replace( dirRE, '' );
});
var cssFiles = filterForCSS( this.filesSrc ).map( function ( file ) {
return file.replace( dirRE, '' );
});

grunt.file.copy('src/index.html', this.data.dir + '/index.html', {
process: function ( contents, path ) {
return grunt.template.process( contents, {
data: {
scripts: jsFiles,
styles: cssFiles,
version: grunt.config( 'pkg.version' )
}
});
}
});
});

/**
* In order to avoid having to specify manually the files needed for karma to
* run, we use grunt to manage the list for us. The `karma/*` files are
* compiled as grunt templates for use by Karma. Yay!
*/
grunt.registerMultiTask( 'karmaconfig', 'Process karma config templates', function () {
var jsFiles = filterForJS( this.filesSrc );

grunt.file.copy( 'karma/karma-unit.tpl.js', grunt.config( 'build_dir' ) + '/karma-unit.js', {
process: function ( contents, path ) {
return grunt.template.process( contents, {
data: {
scripts: jsFiles
}
});
}
});
});

};

Answer

"Waiting..." usually means the server is up and running...
But I see right now watching your Gruntfile that the message "Started connect web server on localhost:9000" you see after grunt live means a connect web server was started (see https://github.com/gruntjs/grunt-contrib-connect), and not a 'real' web server, which you can point your browser to (this is why you don't get any answer from http://localhost:9000...).
It looks like to me your Gruntfile is designed to set up a test environment, and not a staging environment (which is what I think you do expect...).
How to design a staging environment depends upon you app...
For example, do you use express (http://expressjs.com/) or something similar to setup a web framework?
If the answer is yes, you should simply add a task to run node app.js; if the answer is 'no', you should specify which web server you are using...

Comments