Require node_modules from a relative path in gulpfile.js - javascript

All works fine when I have the node_modules folder in the sameone as the gulpfile.js.
But whenever I place node_modules anywhere outside it, I can't seem to make it work by using relative paths:
var gulp = require('../../node_modules/gulp');
var rename = require('../../node_modules/gulp-rename');
I get the following message:
[20:11:45] Task 'default' is not in your gulpfile
[20:11:45] Please check the documentation for proper gulpfile formatting
But I in fact have a default task and it runs as expected when not using relative paths.
I also tried including them without specifiying the node_modules folder, as I though it should be:
var gulp = require('../../gulp');
var rename = require('../../gulp-rename');
But I get the following error:
module.js:538
throw err;
^
Error: Cannot find module '../../gulp'
What am I doing wrong?

Try calling require without a path, like this:
var gulp = require('gulp');
var rename = require('gulp-rename');
This triggers require to search for the node_modules folder, automatically checking each parent folder up to the root. https://nodejs.org/api/modules.html#modules_loading_from_node_modules_folders

Related

How to webpack bundle a file which requires another file at runtime depending upon command line argument?

Consider a very simple application with the project structure
-- package.json
-- webpack.config.js
-- src
|---index.js
|---runner.js
The index.js takes in command line arg to require a file, at runtime. Here is index.js:
function requireAtRuntime(filename){
const runner = require(filename);
runner.run()
}
var filename = process.argv[2];
requireAtRuntime(filename);
runner.js
function run(){
console.log("hello world");
}
exports.run = run
package.json contains the script:
//
scripts :{
"start" : "node src/index.js ./runner.js"
}
This start scripts work well. Now the issue if I want to webpack index.js, runner.js is not included as it dependency and the bundle throws the error when i try to run
node dist/main.js path/to/runner.js
Error: Cannot find module 'path/to/runner.js'
How do I build my webpack so that it can too take filename as command line argument and require it during runtime (or store it before somewhere)?
We need to provide some kind of hint to webpack around what all files may be dynamically required. Lets assume we have multiple runners. We need to put all of them in a folder like shown below
-- package.json
-- webpack.config.js
-- src
|---index.js
|---runners
|---runner1.js
|---runner2.js
Now we need to change the requireAtRuntime() function.
index.js:
function requireAtRuntime(filename){
const runner = require(`./runners/${filename)`);
runner.run()
}
var filename = process.argv[2];
requireAtRuntime(filename);
This will make webpack to fetch all the files in runners and bundle them during compile time.
Now we can run it as
node src/index.js runner1/2 (before bundling) or
node dist/main.js runner1/2 (after bundling)
you have to declaratively specify runner.js as externals, so that webpack won't bundle it at compile time
https://webpack.js.org/configuration/externals/

require path in browserify is not recognized

I have below project structure as shown in the screenshot below. Both index.js and test.js are located at the same path i.e. ./assets/js/ but still the path is not recognized. The error says
Error: Cannot find module 'test.js' from
'C:\Users\meghshyam\desktop\browserifyproj\assets\js'
Use var test = require('./test.js');
This way you are letting node know that its a file in the same folder

Grunt: have package.json and Gruntfile.js on different folders

Im having problems trying to implement grunt on diferent folders, in my root i have:
<root>/package.json
<root>/node_modules
And inside another folder, my gruntfile with diferent subfolders and files wich i work:
<root>/apps/static/Gruntfile.js
If i go to root and execute
grunt --gruntfile /apps/static/Gruntfile.js MyTaskName
I get:
Local Npm module "grunt-contrib-concat" not found. Is it installed?
Local Npm module "grunt-contrib-cssmin" not found. Is it installed?
Local Npm module "grunt-contrib-clean" not found. Is it installed?
Local Npm module "grunt-contrib-watch" not found. Is it installed?
Local Npm module "grunt-contrib-uglify" not found. Is it installed?
And i run several times npm install.
On my gruntfile.js y have
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-uglify');
I triple check and folders are ok (in fact, originally gruntfile and package where in the same folder and everything was working perfect, run several task and everything is ok). I really need to have a common package.json and node_modules on root and the Gruntfile.js on a specific project folder
Any idea whats going on? thanks in advance
Grunt makes certain assumptions regarding the location of gruntfile.js.
When you specify the location of gruntfile.js using the --gruntfile option, Grunt sets the current directory to the directory containing the specified file:
// Change working directory so that all paths are relative to the
// Gruntfile's location (or the --base option, if specified).
process.chdir(grunt.option('base') || path.dirname(gruntfile));
And when Grunt loads NPM tasks, it does so relative to the current directory:
var root = path.resolve('node_modules');
var pkgfile = path.join(root, name, 'package.json');
There is a --base option with which the current directory can be specifed, but whether or not that will solve your problem (without introducing other problems) I do not know. The simplest solution is likely to locate gruntfile.js where it wants and expects to be located.
Sometimes, it may be the need of project to have Gruntfile.js in a different folder than package.json.
I had a very similar use-case where there were multiple submodules each with its own build process, one of them was Grunt. But at the same time I wanted to have a common package.json just to avoid multiple node_modules folders being created, so that common dependencies (including transitive) use to install once. It helped in reducing install time as well as disk usage.
I was expecting a solution in Grunt itself. But as #cartant mentioned, Grunt has made certain assumptions.
So, here is what I did:
In Gruntfile.js,
Define a function:
function loadExternalNpmTasks(grunt, name) {
const tasksdir = path.join(root, 'node_modules', name, 'tasks');
if (grunt.file.exists(tasksdir)) {
grunt.loadTasks(tasksdir);
} else {
grunt.log.error('Npm module "' + name + '" not found. Is it installed?');
}
}
And instead of
grunt.loadNpmTasks('grunt-contrib-concat');
do:
loadExternalNpmTasks(grunt, 'grunt-contrib-concat');
Reference: https://github.com/gruntjs/grunt/blob/master/lib/grunt/task.js#L396

Traceur + browserify + uglyify in gulp

I want to have a gulpfile that first transforms my es6 code to es5 and save it to one dir, then browserify it (on every file, not just an entry file) and save it to another dir, lastly I want to minify it and put it in the browserified folder as .min.js files. Here's a diagram of what the result should look like:
src/
es6/
index.js
mod.js
es5/
index.js
mod.js
es5-browser/
index.js
index.min.js
mod.js
mod.min.js
Here's my gulpfile so far but I keep getting a can't find module error:
var gulp = require('gulp');
var traceur = require('gulp-traceur');
var browserify = require('gulp-browserify');
var sourcemaps = require('gulp-sourcemaps');
gulp.task('es5ize', function () {
return gulp.src('src/es6/**/*.js')
.pipe(sourcemaps.init())
.pipe(traceur({sourceMaps: true}))
.pipe(sourcemaps.write())
.pipe(gulp.dest('src/es5'))
.pipe(browserify({
debug : true
}))
.pipe(gulp.dest('src/es5-browser'))
;
});
I know I shouldn't be using gulp-browserify but I wasn't able to get anything like this to work with vinyl either.
It works up until the browserify step
How can I get this to work?
EDIT:
I want to be able to keep this in gulp and not have to exec anything, since I will eventually want to use watchify on this too
All the other examples that are close to this first have browserify create a bundle and then manipulate that bundle but this means that it will always start browserifed which I don't want. They also seem to need to specify an entry file for browserify but I want to specify a glob and have it transform everthing that matches
you need traceur to compile as commonjs modules so browserify will understand .pipe(traceur({modules: 'commonjs' }))

require a file outside of node_modules with grunt

I am trying to require a node module that is used in my app into my gruntfile.js but whatever I do i get : Cannot find module 'appjs/config
In the gruntfile I simply do : var myconfig = require('appjs/config');
But it just don't want to load, is there a way to import this files easily? I also tried various path but appjs is at the root where the gruntfile is.
Have you tried this?
var myconfig = require('./appjs/config');
Seems like this should work, if appjs is in the same directory as your gruntfile.

Categories