I am new to Grunt and have been struggling all day to make this work:
This is my Gulpfile.js:
'use strict';
// Time how long tasks take. Can help when optimizing build times
require('time-grunt')(grunt);
// Automatically load required Grunt tasks
require('jit-grunt')(grunt);
module.exports = function(grunt) {
// Define the configuration for all the tasks
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
// Make sure code styles are up to par and there are no obvious mistakes
jshint: {
options: {
jshintrc: '.jshintrc',
reporter: require('jshint-stylish')
},
all: {
src: [
'Gruntfile.js',
'app/scripts/{,*/}*.js'
]
}
}
});
grunt.registerTask('build', [
'jshint'
]);
grunt.registerTask('default', ['build']);
};
This my package.json:
{
"name": "conFusion",
"private": true,
"devDependencies": {
"grunt": "^1.0.1",
"grunt-contrib-jshint": "^1.0.0",
"jit-grunt": "^0.10.0",
"jshint-stylish": "^2.2.1",
"time-grunt": "^1.4.0"
},
"engines": {
"node": ">=0.10.0"
}
}
And this is the error message i get:
grunt build
Loading "Gruntfile.js"
tasks...ERROR >>
ReferenceError: grunt is not defined
Warning: Task "build" not found.Use--force to continue.
Aborted due to warnings.
Pls guys, I need help. I am working on windows 10, so am using the command line there.
module.exports = function(grunt) {
That is where you define a grunt variable. It is an argument to the function you created.
But you try to use it here:
require('time-grunt')(grunt);
and here:
require('jit-grunt')(grunt);
This is outside the function where the variable does not exist.
Move those lines inside the function.
Related
I have some test files with tests I'd like to run against my app.
I am attempting to use karma, karma-webpack, karma-babel-preprocessor, karma-chrome-launcher, and jasmine in my testing. My app depends on many things, including backbone, marionette, etc. My app is built using webpack, and I am attempting to use webpack to bundle my files together for testing. (I initially wanted to see if I could skip this step, i.e. simply import a file to be tested, but it seems this is impossible.)
My test script looks like
package.json (scripts section)
"test": "./node_modules/karma/bin/karma start",
The rest of the files:
karma.conf.js
var webpackConfig = require('./config/webpack/webpack.test.conf.js');
module.exports = function(config) {
config.set({
basePath: '',
frameworks: ['jasmine'],
files: [
{ pattern: 'test/**/*.spec.js', watched: true },
{ pattern: 'test/*.spec.js', watched: true }
],
exclude: [
],
preprocessors: {
'test/**/*.spec.js': ['webpack'],
'test/*.spec.js': ['webpack']
},
webpack: webpackConfig,
webpackMiddleware: {
stats: 'errors-only'
},
reporters: ['progress'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false,
concurrency: Infinity
})
}
test/test.spec.js This file is seen
describe("A suite", function () {
it("contains spec with an expectation", function () {
expect(true).toBe(true);
});
});
describe("Another suite", function () {
it("contains another spec with an expectation", function () {
expect(true).toBe(false);
});
});
test/models/devicegroup.spec.js This file is not seen
import backbone from 'backbone';
describe("backbone", function () {
it("containsasdfasdfasdfasdfspec with an expectation", function ()
{
expect(true).toBe(false);
});
});
My folder structure is:
- karma.conf.js
- test/
- - test.spec.js
- - models/
- - - devicegroup.spec.js
- public/
- - js/
- - - app.js
When my files don't have import statements at the top, karma will run and pass/fail as expected. Putting an import statement at the top will cause karma to ignore the file. No errors are thrown.
How can I make karma / karma-webpack run my tests that have import statements / what is the karma-safe way to import modules into my tests?
When test/models/devicegroup.spec.js does not have an import statement:
// import backbone from 'backbone';
describe("backbone", function () {
it("contains with an expectation", function () {
expect(true).toBe(false);
});
});
the terminal output is: (notice one less test is run)
When test/models/devicegroup.spec.js does have an import statement:
import backbone from 'backbone';
describe("backbone", function () {
it("contains with an expectation", function () {
expect(true).toBe(false);
});
});
the terminal output is:
I see no errors in the browser Karma opens.
EDIT:
I have experimented by adding my source files to the files and preprocessors attributes in my karma.conf.js file, as per this repo example. There was no change in behavior other than a massively increased testing time.
karma.conf.js
files: [
{ pattern: 'public/js/**/*.js', watched: true},
{ pattern: 'test/**/*.spec.js', watched: true },
// each file acts as entry point for the webpack configuration
],
preprocessors: {
// add webpack as preprocessor
'public/js/**/*.js': ['webpack'],
'test/**/*.spec.js': ['webpack'],
},
EDIT2:
For the sake of experimentation (and based off this person's struggles), I have tried the above karma.conf.js in every possible combination - only test files in files and preprocessors, only source files, test files in one but not the other, source files in one but not the other, none, both. No good results, though occasionally new errors.
Little late, but I ran into the same problem, and was searching for hours, why my imports prevent the test suite from being executed. karma-webpack-4.0.0-rc.2 brought the enlightenment by providing error messages!!
I my case a couple of modules where not found, angular-mock, jquery, angular and more.
How to fix
Put there modules into the files array in your karma.config like:
files = [
"node_modules/jquery/dist/jquery.js",
"node_modules/angular/angular.js",
"node_modules/angular-mocks/angular-mocks.js",
{ pattern: "test/**/*.ts", watched: false }
I hope, this helps someone.
EDIT
My current versions of the testing related packages:
"#types/jasmine": "^2.8.8",
"jasmine": "^3.2.0",
"jasmine-core": "^3.2.1",
"jasmine-reporters": "2.3.2",
"jasmine-ts": "^0.2.1",
"karma": "3.0.0",
"karma-chrome-launcher": "2.2.0",
"karma-jasmine": "1.1.2",
"karma-junit-reporter": "1.2.0",
"karma-phantomjs-launcher": "1.0.4",
"karma-sourcemap-loader": "^0.3.7",
"karma-spec-reporter": "0.0.32",
"karma-webpack": "^4.0.0-rc.2",
"typescript": "3.0.3",
"webpack": "4.17.2",
"webpack-cli": "^3.1.0",
"webpack-dev-server": "3.1.8"
Loading "Gruntfile.js" tasks...ERROR >> SyntaxError: Unexpected string Warning: Task "default" not found. Use --force to continue. Aborted due to warnings. getting this error while launching grunt from command promt can anybody help on this issue?
my Gruntfile.js file is:-
'use strict';
module.exports = function (grunt) {
grunt.initConfig({
require('time-grunt')(grunt);
require('jit-grunt')(grunt);
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
jshint: {
options: {
jshintrc: '.jshintrc',
reporter: require('jshint-stylish')
},
all: {
src: [
'Gruntfile.js',
'app/scripts/{,*/}*.js'
]
}
}
});
grunt.registerTask('build', [
'jshint'
]);
grunt.registerTask('default',['build']);
});
};
Can you please try including this?
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.registerTask('build', [
'jshint'
]);
I've put together a few pretty standard grunt tasks with a reasonable number of dependencies, but for some reason it takes 1-3 minutes to actually load the dependencies. I'm moderately new to grunt, but since most of the other questions about extreme slowness loading grunt dependencies cite times of a few seconds, I'm guessing I'm doing something very wrong.
Here's what my gruntfile looks like:
const path = require("path");
module.exports = function(grunt) {
require('jit-grunt')(grunt);
require('time-grunt')(grunt);
const ignoredSourceScriptPatterns = ['!**/*.debug.js', '!**/*.min.js', '!scripts/*', '!**/*.map'],
baseUIPath = 'presentation/ui',
scripts = grunt.file.expand({filter: 'isFile',
matchBase: true,
cwd: baseUIPath},
['*.js', ...ignoredSourceScriptPatterns]);
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
copy: {
build: {
cwd: 'presentation/',
src: 'ui/**',
dest: path.join('presentation', 'static'),
expand: true
}
},
uglify: {
options: {
sourceMap: true,
compress: false
},
build: {
cwd: baseUIPath,
files: function() {
var modules = grunt.file.expand({
filter: 'isDirectory',
expand: true,
cwd: 'presentation/ui/modules'
}, ['**', '!**/css', '!**/scripts', ...ignoredSourceScriptPatterns]),
components = grunt.file.expand({
filter: 'isFile',
expand: true,
cwd: 'presentation/ui'
}, ['components/!*.js', ...ignoredSourceScriptPatterns]),
files, componentFiles;
files = modules.map(function(path) {
var modulePath = `modules/${path}/scripts`,
moduleName = modulePath.split('/').reduce(function(result, next) {
var nameFragment;
switch(next) {
case "modules":
nameFragment = "Poptart.";
break;
case "scripts":
nameFragment = "min.js";
break;
default:
nameFragment = `${next.charAt(0).toUpperCase() + next.slice(1)}.`;
break;
}
return result + nameFragment;
}, "");
return {
src: grunt.file.expand({
filter: 'isFile'
}, [`${baseUIPath}/${modulePath}/*.js`, ...ignoredSourceScriptPatterns]).sort(
function(a, b) {
return a.length - b.length;
}
),
dest: `${baseUIPath}/${modulePath}/${moduleName}`
};
});
componentFiles = components.map(function(componentPath) {
return {
src: `${baseUIPath}/${componentPath}`,
dest: `${baseUIPath}/${componentPath.replace('.js', '.min.js')}`
};
});
files = [...files, ...componentFiles];
files.push({
src: grunt.file.expand({
filter: 'isFile'
}, [`${baseUIPath}/*.js`, ...ignoredSourceScriptPatterns]),
dest: `${baseUIPath}/poptart.min.js`
});
return files;
}(),
extDot: 'last',
expand: true
}
},
cssmin: {
options: {
sourceMap: true
},
build: {
cwd: 'presentation/static/ui/',
src: ['**/*.css', '!css/jquery-ui/**', '!css/ionicons/**', '!**/*.min.js'],
dest: 'presentation/static/ui/',
ext: '.min.css',
expand: true
}
},
eslint: {
options: {
configFile: 'presentation/build/eslint.json',
ignorePath: 'presentation/build/.eslintignore'
},
target: ['presentation/**/*.js', '!presentation/ui/scripts/*', '!presentation/static/**']
},
shell: {
test: {
command: 'python manage.py test -p "*tests.py"',
options: {
stdout: true,
failOnError: true
}
}
},
karma: {
unit: {
configFile: 'karma.conf.js',
singleRun: true
}
},
mochaTest: {
unit: {
options: {
reporter: 'spec'
},
src: ['presentation/test/server/*.js']
}
}
});
/*grunt.loadNpmTasks('grunt-shell');
grunt.loadNpmTasks('grunt-eslint');
grunt.loadNpmTasks('grunt-karma');
grunt.loadNpmTasks('grunt-mocha-test');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-newer');*/
grunt.registerTask('default', ['lint', 'test']);
grunt.registerTask('test', ['shell:test', 'mochaTest:unit', 'karma:unit']);
grunt.registerTask('lint', ['eslint']);
grunt.registerTask('build-static', ['uglify', 'copy', 'cssmin']);
};
And my dev dependencies from package.json:
"devDependencies": {
"chai": "^3.5.0",
"chai-jquery": "^2.0.0",
"eslint": "^3.7.1",
"grunt": "^1.0.1",
"grunt-contrib-copy": "^1.0.0",
"grunt-contrib-cssmin": "^1.0.2",
"grunt-contrib-uglify": "^2.0.0",
"grunt-eslint": "^19.0.0",
"grunt-karma": "^2.0.0",
"grunt-mocha-test": "^0.13.2",
"grunt-newer": "^1.2.0",
"grunt-shell": "^1.3.1",
"jit-grunt": "^0.10.0",
"jquery": "^3.1.1",
"karma": "^1.3.0",
"karma-chai": "^0.1.0",
"karma-chrome-launcher": "^2.0.0",
"karma-cli": "^1.0.1",
"karma-jquery-chai": "^0.1.3",
"karma-mocha": "^1.3.0",
"karma-phantomjs-launcher": "^1.0.2",
"karma-sinon": "^1.0.5",
"mocha": "^3.2.0",
"sinon": "^1.17.6",
"sinon-chai": "^2.8.0",
"time-grunt": "^1.4.0"
}
Here's what I've tried so far:
Using time-grunt to verify that loading tasks was actually the problem. It was. actually running tasks took very reasonable amounts of time.
using jit-grunt. This made no noticeable difference.
npm prune. This actually did make a fairly big (~30 seconds) difference, but still leaves me at a completely unreasonable time for task loading.
Removing and unloading some of the dependencies (uglify, copy, cssmin) I had added around the time that I started seeing this problem (originally, when I just had the testing/linting tasks, everything worked nice and fast). This also made no noticeable difference.
So. What else could be causing slowness on this scale?
Thanks for your help!
So it looks like the root cause of this was some inefficient file searching in the uglify task. I'd completely forgotten that I had made that giant blob of crazy and IEF, which explains why I was seeing the slowness even when I wasn't running the uglify task. I suppose it also explains why the time for the file search was getting lumped in with the loading tasks.
In any event, the main culprit was (predictably) where I was returning the source/dest paths for the dynamically found script modules, here:
return {
src: grunt.file.expand({
filter: 'isFile'
}, [`${baseUIPath}/${modulePath}/*.js`, ...ignoredSourceScriptPatterns]).sort(
function(a, b) {
return a.length - b.length;
}
),
dest: `${baseUIPath}/${modulePath}/${moduleName}`
};
Unspurprising because it is in a loop. In any event, I noticed it was missing a cwd. Adding that cut the time down to 7s. Still needs improving, but at least now I know what to improve.
Morals of this story:
add cwd's when search for files
Maybe just don't search for files if you don't have to
I tried running your Gruntfile and installed the dependencies manually, and the loading time of the Gruntfile was ~4 secs. Not fast, but not the minutes you talk about.
My guess is grunt.file.expand is working hard. Maybe presentation/ui folder is too big? What do you get by running tree presentation/ui | wc -l ? That shows the number of files you have there.
Otherwise, it would be helpful to also see your package.json and npm ls output.
I'm new to Grunt so maybe this is an easy question, but I'm really at a loss with this...
I'm tying to declare all my files in "package.json" and inside grunt just import them.
Something like this:
// package.json
{
"config": {
"files": {
"css": ["../assets/css/main.scss", "../assets/css/plugins.scss"]
}
},
"dependencies": {
"grunt": "~0.4.5",
"grunt-contrib-sass": "~0.8.1"
}
}
// grunt.js
module.exports = function (grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
sass: {
dev: {
options: { style: 'compressed', noCache: true },
files: { '../assets/min/min.css': '<%= pkg.config.files.css %>' }
}
}
});
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.registerTask('default', ['sass:dev']);
};
I says the source files are empty. But if I declare only one file it works just fine.
While if I declare them directly inside "grunt.js" works...
// grunt.js
module.exports = function (grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
sass: {
dev: {
options: { style: 'compressed', noCache: true },
files: { '../assets/min/min.css': ["../assets/css/main.scss", "../assets/css/plugins.scss"] }
}
}
});
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.registerTask('default', ['sass:dev']);
};
Can someone tell me how to make the first one work?
Thanks :)
The problem is that by sticking pkg.config.files.css into the template, it's probably stringifying it. Try just passing in the variable directly:
// Wrong
'<%= pkg.config.files.css %>'
// Right
pkg.config.files.css
This way, Grunt will just pass in the array as you're expecting it to.
EDIT:
If this doesn't work, here's an alternative way to access package.json. While the above is valid JS, it may not be valid with Grunt because if grunt.file.readJSON runs asynchronously, it will be undefined until it finishes, which would be after grunt already initialized the config object. Thus, grunt goes back and inserts the data when it's available.
I'm trying to use GruntJS to make some improvements to my workflow - I've been using Compass for a while but I'm wanting to try out Bourbon and so I've been trying to get this working but failing.
I'm getting the following error when I run 'grunt':
ERROR: Cannot find module 'bourbon'
I've installed this through Node using 'npm install' with the following 'package.json' file:
{
"name" : "project",
"description": "description",
"version" : "0.0.1",
"dependencies" : {
"node-sass": "~0.8.4",
"node-bourbon": "~1.0.0",
"grunt": "~0.4.4",
"grunt-contrib-watch": "~0.6.1",
"grunt-sass": "~0.12.0",
"grunt-contrib-uglify": "~0.4.0",
"matchdep": "~0.3.0"
}
}
My grunt file looks like this:
module.exports = function(grunt) {
grunt.loadNpmTasks('grunt-sass');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.initConfig({
uglify: {
my_target: {
files: {
'assets/js/main.js': ['_/js/scripts.js']
} // files
} // my_target
}, // uglify
sass: {
dist: {
options: {
includePaths: require('bourbon').includePaths,
outputStyle: 'compressed'
},
files: {
'assets/css/main.css': '_/stylesheets/**/*.scss'
}
}
},
watch: {
options: { livereload: true },
grunt: { files: ['gruntfile.js'] },
scripts: {
files: ['_/js/scripts.js'],
tasks: ['uglify']
}, //script
sass: {
files: ['_/stylesheets/**/*.scss'],
tasks: ['sass']
}, //sass
php: {
files: ['**/*.php']
}
} //watch
}) //initConfig
grunt.registerTask('default', 'watch');
} //exports
I've also imported the file in the top of my SCSS stylesheets using:
#import 'bourbon';
Not sure what I'm doing wrong here, any help would be greatly appreciated!
Please let me know if you need any more info.
You are requiring the wrong package name. It should be:
includePaths: require('node-bourbon').includePaths
but you have:
includePaths: require('bourbon').includePaths
Install Bourbon manually:
Install the gem:
$ gem install bourbon
Install Bourbon into your project's stylesheets directory by generating the bourbon folder:
$ bourbon install