Ignore "Local NPM module not found" warning in Grunt - gruntjs

I'm using matchdep to read dependencies from my package.json file into grunt.
require('matchdep').filterAll('grunt-*').forEach(grunt.loadNpmTasks);
I have my dependencies split between dependencies (for everyone) and devDependencies (for front-end developers.)
Our back-end devs will run the following to get a build of the static assets without requiring jasmine, phantomJS, etc (things that will be run by front-end devs and the CI server)
$ npm install --production
$ grunt build
However, when using the --production build, grunt.loadNpmTasks() will emit a warning for any missing packages.
>> Local Npm module "grunt-contrib-watch" not found. Is it installed?
Is there a way to supress this warning?

You have to question why your "back-end devs" would have to actually build your package - put otherwise, why do they need grunt but NOT devDependencies. This is kind of backwards (requiring users to build your package is certainly an anti-pattern).
That being said, using matchdep, you can / should use:
require('matchdep').filter inside your "production" target
require('matchdep').filterAll inside your "development" target
Certainly, that would require you to specialize your grunt build (eg: have grunt builddev and grunt buildproduction - or maybe use environment variables) - but again, see above...

You can use CLI flags to pass options into grunt. For consistency, I am using a --production flag, just as I do with npm.
So, from the CLI:
$ grunt build --production
And then in the Gruntfile:
var dependencies;
// test for the production flag
if (grunt.option('production')) {
// scan dependencies but ignore dev
dependencies = require('matchdep').filter('grunt-*');
} else {
// scan all dependencies
dependencies = require('matchdep').filterAll('grunt-*');
}
// load only relevant dependencies
dependencies.forEach(grunt.loadNpmTasks);
This is done at the top of the module before any custom tasks are registered.

Related

VSTS webpack build task cannot find CLI

I have a .NET (4.7) Web Application inside a project directory called MyWebApp.Web
As part of the build process I run npm install, webpack-cli is a dependency.
But when I run the webpack build task with MyWebApp.Web set as the working directory I get the following error:
Error: Cannot find module 'D:\a\1\s\MyWebApp.Web\node_modules\webpack\bin\webpack.js'
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:581:15)
at Function.Module._load (internal/modules/cjs/loader.js:507:25)
at Function.Module.runMain (internal/modules/cjs/loader.js:742:12)
at startup (internal/bootstrap/node.js:236:19)
at bootstrapNodeJSCore (internal/bootstrap/node.js:560:3)
If I try and run webpack via an NPM script I get webpack's built in interactive "a CLI must be installed" prompt, indicating that the module cannot be found.
Is there anything I'm missing that needs to be in place for webpack to "see" the node modules?
It transpires that in the Variables tab process.env.NODE_ENV was set to production so dev dependencies were not being installed.
Removing this environment variable solved the problem.
I was doing this specifically to invoke webpack's "production" mode (partly because that's how the webpack Visual Studio extension works). This approach always worked on dev environments because the modules were already installed from previous development builds but on the VSTS build agent we were only ever running a production build.
I've now set up separate webpack.common.js, webpack.config.js (for dev), and webpack.prod.js files using webpack-merge, as per the webpack documentation. This targets different configs to different environments rather than relying on environment variables.
try :
npm i webpack webpack-cli -g --save-dev

How to install NPM package from GitHub for Meteor?

I have forked an npm package on GitHub, made changes to it, and now want to install the package in my Meteor app directly from GitHub.
My package.json looks like so:
{
"dependencies": {
"semantic-ui-react": "git+https://git#github.com/nolandg/Semantic-UI-React.git",
}
}
I then run
meteor npm install
Which appears to work fine and tells me it's installed the package:
semantic-ui-react#0.61.6 (git+https://git#github.com/nolandg/Semantic-UI-React.git#f27d5c736e5de1eed0acf7769f18caee57578526)
And indeed the package appears in the node_modules folder. But when I try to start my Meteor app, I get this error:
Cannot set property '/my-website/node_modules/semantic-ui-react/package.json' of undefined
at Resolver._resolvePkgJsonMain (/tools/isobuild/resolver.js:320:9)
Has anyone successfully install an npm package in a Meteor app directly from GitHub? I can't figure this one out. Thanks!
Meteor version: 1.4.2.3
The main reason why the package does not work when fetching from git is because it is not configured to work that way. This is not a Meteor specific problem, but a problem that a JS developer may face sometimes.
For this particular case there are two problems:
The whitelist files field in package.json only contains src and dist folder. That means when you fetch it by npm almost all config files needed to build the code are gone.
Code for this package requies to be built in order to work with your code. This is done when the author publish it to npm, but you fetch it directly from github so this step is undone.
Because you already folked and modified the package, so let modify the package.json as below (remove all the comments I added them to give you some explanation), push it to github, and fetch it again by npm:
// remove the "files" field
// ...
"scripts": {
// this script is used to build the package
"postinstall": "postinstall-build dist \"npm run build:commonjs\""
// ...
},
"dependencies": {
// this helps build the package
"postinstall-build": "^2.1.3"
},
// ...
Packages are not usually installed from github, they are published, which means that many versions of a package are available, you can choose which one you get. I'm not sure if what you are doing is possible, but it's certainly inadvisable.
If you want to make changes to a github package, you can download the it to your local machine and do npm link, so that it uses your local package instead of the one on npm. Read more about it at https://docs.npmjs.com/cli/link
Why do you not use simple command?
meteor npm install https://github.com/nolandg/Semantic-UI-React.git
I did:
meteor create test
cd test
meteor npm install
meteor add react react-dom
meteor npm install https://github.com/nolandg/Semantic-UI-React.git
meteor
And no errors (-:

Why does grunt allow global installations?

I've installed both the grunt-cli and grunt globally using the -g option.
However when I try and run grunt I get this error:
grunt --gruntfile /Users/a/root/config/Gruntfile.js
grunt-cli: The grunt command line interface. (v0.1.13)
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
This is confusing as it seems to say that you are suppose to do a local install.
It seems contradictory actually. I clearly have a grunt file in place.
Grunt-cli is installed globally so that the grunt command is available to be run from any location on your system. Without the global installation, you would need to rely on somewhat abstract methods of running local grunt installs (npm run-script and friends), which are clunky for this use.
The entire point of the global install is only to load and run a local Gruntfile.js using the locally installed version of Grunt. The error message indicates this:
either a Gruntfile wasn't found or grunt hasn't been installed locally to your project.
In other words, to run Grunt, you need to create a Gruntfile.js and you must have a local copy of Grunt installed to your project alongside the file. The CLI is just there to kick off the process without troublesome fiddling.

What is the correct option to use Grunt locally and on the production server, --save or --save-dev?

The install page on the Grunt website gives the following suggestion
Grunt and Grunt plugins should be defined as devDependencies in your
project's package.json. This will allow you to install all of your
project's dependencies with a single command: npm install.
I want to use grunt to run some tasks that are specific to local development, e.g.
development: concatenate javascript, but dont minify
production: concatenate and minify javascript
If I install Grunt as a dev dependency, does this mean when I run NPM install on the production server - grunt will not be installed into node modules?
What is the correct option to be able to use Grunt both locally and on the production server?
It doesn't matter if you install Grunt as a dev dependency, it will still be installed when you run npm install.
The scenario where dev dependencies are not installed is when you run npm install <package> because the consensus is you are an end user looking to use (not build/test) the package. However, you can still include the dev dependencies by adding the --dev flag.
You should install grunt with --save-dev. What it does is add a line to your project's package.json. Similar to when you install any other node module with --save-dev. Then, if you run npm install on any machine with the same package.json, all those modules will be downloaded and installed locally, and usable by your project.
As for running different tasks in production and development, I assume you know how to configure grunt to do that.

Meteor package pre-build npm module with browserify

I have an npm module I want to wrap in Meteor package, and work with it on client side and server side both. This npm module isn't shipped with built 'dist' file but with sources only instead and npm build script, so it is supposed to be built with browserify or webpack.
package.json contains npm build script for minimized package:
"scripts": {
"prod": "browserify ./index.js -x react | uglifyjs > ./dev/prod.js"
},
I want to execute this script (or my own) and only then do
Package.onUse(function(api) {
api.addFiles('../somenpmfolder???/dev/prod.js', ['client', 'server']);
}
Obviously just Npm.require wouldn't work as it doesn't work when executed on client.
I can build script manually and just shove dist inside my package but it isn't right way doing things. I leave it as a last resort for myself.
This is half of answer on my question: https://stackoverflow.com/a/17081463/2123547
What I want to have next is this pre-build stage.
There's a new package appeared that does browserify job. I checked it and it work well for me.
https://github.com/elidoran/cosmos-browserify/

Resources