Grunt plugins not found using load-grunt-config - javascript

I've split out my grunt plugins into their own files and I'm using the load-grunt-config (https://github.com/firstandthird/load-grunt-config) to call them:
module.exports = function (grunt) {
'use strict';
require('load-grunt-config')(grunt);
};
I've got sass, autoprefixer, cssmin and watch tasks working but I'm also using Browsersync and px-to-rem these two plugins return:
Warning: Task "remify" not found. Use --force to continue.
and
Warning: Task "browsersync" not found. Use --force to continue.
when called individually or as part of a bigger task.
I've followed the syntax for the separate.js files for these two plugin so I'm at a loss. For example the remify.js file which is called when running grunt is written like this
module.exports = {
dist: {
options: {
base: 16,
fallback: true,
fallback_existing_rem: true,
ignore: []
},
files: {
'css/style.css': 'css/style.css'
}
}
};
Any ideas where this is going wrong?
I've also set up a gist of the example code, include package.json and a aliases.yml
https://gist.github.com/sturobson/f88258fd010e901e24d9

You have to call the grunt plugin exactly what it is. So where I've got remify I should be using px_to_rem and where I've got browsersync and I should have browserSync.
Silly me.

you can pass a second argument to load-grunt-config to provide some options where you could also define some pattern which can be used by load-grunt-tasks which is used internally.
if you don't pass a second argument, it uses the default-pattern of load-grunt-tasks which is grunt-*.
so if you want to load all devDependencies without defining them seperatly, do it like this:
require('load-grunt-config')(grunt, {
loadGruntTasks: {
pattern: '*',
scope: 'devDependencies'
}
});

Related

How to make couple of minified files from different js files using grunt

I am new to grunt and task runners in JS, so this might seem a simple question but I have been unable to find exact working answer.
I have :
concat: {
options: {
// define a string to put between each file in the concatenated output
separator: '\n\n'
},
dist: {
// the files to concatenate
src: ['scripts/app.js', 'scripts/constant.js'
],
// the location of the resulting JS file
dest: 'scripts/custom.js'
}
},
This task collects all my custom file together. What I want is to do similar thing for all my vendors file. Finally I should end up with two js only custom.js having my concatenated-minified code and vendor.js having concatenated-minfied libraries.
How do I write grunt configuration for this. Do I need to make two different tasks. If I write the above code twice with different input files, it seems to run the last code.
grunt-contrib-concat can be configured to utilize multiple-targets.
For further documentation on this subject refer to multi-tasks and Task Configuration and Targets in the grunt documentation.
Gruntfile.js
For your scenario you need to configure your concat task similar to this (Note: the new custom and vendor targets):
module.exports = function(grunt) {
grunt.initConfig({
concat: {
options: {
separator: '\n\n'
},
custom: {
src: ['scripts/app.js', 'scripts/constant.js'],
dest: 'scripts/output/custom.js'
},
vendor: {
// Modify the src and dest paths as required...
src: ['scripts/vendor/foo.js', 'scripts/vendor/baz.js'],
dest: 'scripts/output/vendor.js'
}
}
});
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.registerTask('concatenate', [
'concat:custom', // <-- Targets in a task are called using a colon separator.
'concat:vendor'
]);
};
Running concat
Using the example gist provided above you can run the concat task via the CLI by typing the following command:
$ grunt concatenate
Configuring Options
If you require different configuration options for both the custom and vendor targets you will need to move the options object inside their respective targets. As explained here.
Note: Using the example gist provided the options specified will apply to both targets.

Configuration of stylelint in Gruntfile

I'm trying to create a separate task called stylelint because for reasons I do not want it to be part of the postcss task.
In the gruntfile I'm writing:
stylelint: {
options: {},
src: './assets/css/precss/**'
}
When I run grunt stylelint it lints my code but when it finds an issue then I get Warning: Task "stylelint:src" failed. Use --force to continue.
Am I omitting something?
You should use grunt-stylelint rather than PostCSS as it supports the native stylelint format reporters. Your Gruntfile config should then look something like this:
stylelint: {
css: {
options: {
configFile: '.stylelintrc',
format: 'css'
},
src: [ 'assets/*.css' ]
},
},
I just realised that this is not possible. You have to run grunt with --force

Karma: Running a single test file from command line

So, I've been looking all over for this, found "similar" answers here, but not exactly what I want.
Right now if I want to test a single file with karma, I need to do fit(), fdescribe() on the file in question...
However, what I do want is to be able to just call karma, with the config file, and direct it to a specific file, so I don't need to modify the file at all, ie:
karma run --conf karma.conf.js --file /path/to/specific/test_file.js
is it possible to do this? Or with any helper? (using grunt or gulp?)
First you need to start karma server with
karma start
Then, you can use grep to filter a specific test or describe block:
karma run -- --grep=testDescriptionFilter
Even though --files is no longer supported, you can use an env variable to provide a list of files:
// karma.conf.js
function getSpecs(specList) {
if (specList) {
return specList.split(',')
} else {
return ['**/*_spec.js'] // whatever your default glob is
}
}
module.exports = function(config) {
config.set({
//...
files: ['app.js'].concat(getSpecs(process.env.KARMA_SPECS))
});
});
Then in CLI:
$ env KARMA_SPECS="spec1.js,spec2.js" karma start karma.conf.js --single-run
This option is no longer supported in recent versions of karma:
see https://github.com/karma-runner/karma/issues/1731#issuecomment-174227054
The files array can be redefined using the CLI as such:
karma start --files=Array("test/Spec/services/myServiceSpec.js")
or escaped:
karma start --files=Array\(\"test/Spec/services/myServiceSpec.js\"\)
References
karma-runner source: cli.js
karma-runner source: config.js
I tried #Yuriy Kharchenko's solution but ran into a Expected string or object with "pattern" property error.
Therefore I made the following modifications to his answer and now I'm able to run single files using Karma:
function getSpecs(specList) {
if (specList) {
return specList.toString();
} else {
return ['**/*_spec.js'] // whatever your default glob is
}
}
module.exports = function(config) {
config.set({
//...
files: [
{ pattern: getSpecs(process.env.KARMA_SPECS), type: "module"}
]
});
});
Note: This solution only works with a single file mentioned in the KARMA_SPECS env variable. Ex: export KARMA_SPECS="src/plugins/muc-views/tests/spec1.js"

how does the ignore parameter works in gulp and nodemon?

I'm trying to create a gulpfile that lint my personal javascript files (.js) but ignore any vendor/third party libaries.
My gulp file is listed below:
var gulp = require("gulp"),
uglify = require("gulp-uglify"),
jshint = require("gulp-jshint"),
jasmine = require("gulp-jasmine"),
nodemon = require("gulp-nodemon");
// lint JS files for bad habbits
gulp.task("lint", function () {
gulp.src(["**/*.js", "node_modules/*"])
.pipe(jshint())
.pipe(jshint.reporter("default"));
});
gulp.task("nodemon", function () {
nodemon({
script: "server.js",
ext: "html css jade js",
ignore: ["node_modules/*"]
})
.on("change", ["lint"])
.on("restart", function () {
console.log("Change detected, restarting server ...");
});
});
gulp.task("default",["nodemon"]);
When I run the "gulp default" command in my terminal it still lint the javascript files in the node_modules. I've tried variations of the glob syntax but I can't seem to achieve the desired behaviour.
Any idea where I've gone wrong?
Thanks.
The glob pattern you've set, node_modules/* only matches the files in the root of the node_modules directory, but not all the children with an highter depth.
You need to set is as node_modules/**/*, this will match everything. I advice you however to only match js files, with node_modules/**/*.js.
You also need to negate the pattern with !, gulp does not know that you want to do that, so it will look like:
gulp.src(['**/*.js', '!node_modules/**/*.js'])
For nodemon, following the same thing you can use the node_modules/**/* pattern.
The library used by gulp for globbing is minimatch.
use this ignore: ["node_modules/"] without '*' and it will work

How should project-level bundling be handled for non SPA use?

I am learning browserify and I am trying to do two basic things with it:
Transform (via shim) non-CommonJS modules for ease-of-use and dependency tracking
Bundle the libraries that are project-specific
I've found a working process for how to do all of this and automate it with Gulp. This works and produces the right output but, I am curious if it could be made simpler. It seems like I have to duplicate a lot of configuration on the project-based bundles. Here is the working example:
package.json
invalid comments added for clarification
{
//project info and dependencies omitted
//https://github.com/substack/node-browserify#browser-field
"browser": { //tell browserify about some of my libraries and where they reside
"jquery": "./bower_components/jquery/dist/jquery.js",
"bootstrap": "./bower_components/bootstrap/dist/js/bootstrap.js"
},
"browserify": {
//https://github.com/substack/node-browserify#browserifytransform
"transform": [
"browserify-shim"
]
},
"browserify-shim": {
//shim the modules defined above as needed
"jquery": {
"exports": "$"
},
"bootstrap": {
"depends": "jquery:$"
}
}
}
config.js
contains all task-runner related configuration settings
module.exports = {
browserify: {
// Enable source maps and leave un-ulgified
debug: true,
extensions: [],
//represents a separate bundle per item
bundleConfigs: [
{
//I really want to refer to the bundles here made in the package.json but
//if I do, the shim is never applied and the dependencies aren't included
entries: ['/bundles/shared-bundle.js'],
dest: '/dist/js',
outputName: 'shared.js'
}
]
},
//...
};
shared-bundle.js
acts as a bundling file where node loads the dependencies and at this point, the shim has been applied
require('bootstrap');
browserify-task.js
contains the browserify bundling gulp task
//module requires omitted
gulp.task('browserify', function (callback) {
var bundleQueue = config.bundleConfigs.length;
var browserifyBundle = function (bundleConfig) {
var bundler = browserify({
entries: bundleConfig.entries,
extensions: config.extensions,
debug: config.debug,
});
var bundle = function () {
return bundler.bundle()
// Use vinyl-source-stream to make the stream gulp compatible
.pipe(source(bundleConfig.outputName))
// Specify the output destination
.pipe(gulp.dest(bundleConfig.dest))
.on('end', reportFinished);
};
var reportFinished = function () {
if (bundleQueue) {
bundleQueue--;
if (bundleQueue === 0) {
// If queue is empty, tell gulp the task is complete
callback();
}
}
};
return bundle();
};
config.bundleConfigs.forEach(browserifyBundle);
});
In config.js where the first bundleConfig item's entries is a source to a file that has the require() modules, I'd like replace those with module names of modules defined in the package.json browser key.
In the config.js, if I change the bundle configuration to:
bundleConfigs: [
{
entries: ['bootstrap'],
dest: '/dist/js',
outputName: 'shared.js'
}
]
and run the gulp task, it will include bootstrap.js but it doesn't run the shim transformation. jQuery is not being included at all.
This leaves me with a few questions:
Is there a better way to be bundling my js for use in a non-SPA application (ie am I going about this the wrong way)?
If not, is there a way to ensure the shim transformation is run prior to the bundling so that I can have my bundle configuration in one place?
Certainly, you just have to tell your gulp file that it should shim first. Looks like you can add your own shim object when calling browserify from your gulp file. Check out this example
If you want to ensure everything is shimmed before you bundle them, use the deps array: "An array of tasks to be executed and completed before your task will run."
It would look something like this:
gulp.task('shim', function() {
// ...
});
gulp.task('browserify', ['shim'], function(){
// ...
});

Categories

Resources