Gulp with browserify: Cannot find start module - javascript

I have pretty much the exact same problem as described in Gulp with browserify: Cannot find module src/js/main.js: I have a JavaScript project that I can build using browserify from the command line, but not in gulp. But the solution for that question does not work for me.
From the command line:
browserify -t reactify ./js/inspector > static/js/inspector.js
works perfectly. When I run the following gulp task:
gulp.task('browserify', function() {
return browserify({
transform: ['reactify'],
entries: ['./js/inspector.js']
})
.bundle()
.pipe(source('inspector.js'))
.pipe(gulp.dest('./static/js/'));
});
and run it, I get the following error in the console:
Error: Cannot find module '../../inspector'
and also the generated file has the same length as the CLI file but not the same order of modules. Which puzzles me.
I have the same version of browserify in my global and local modules, and I've not knowingly configured it, anywhere.
Unlike Ben Davis, who asked the other question, adding a ./ to the start of my path changes nothing.
I don't understand why browserify gives a different, and broken, output, when run through gulp.
Update: The directory structure of the project:
gulpfile.js
node_modules/
js/ (also contains subdirectories with JS code)
inspector.js
static/
js/
inspector.js (built)
Update: When I run Browserify through Grunt, I also get a different file, but it works.

You can try wrapping your return function in an IIFC.
//======================================
// Task: browserify
//======================================
gulp.task('browserify', function() {
return (function() {
browserify(config.src)
.bundle()
.pipe(source(config.name))
.pipe(gulp.dest(config.dest));
})();
});
I am using the above successfully in a current proj.

I had other modules that required the root module, à la:
var inspector = require('../../inspector');
This is what caused the problem (somehow). Putting in a root module that was never required by anything else made gulp + browserify work without any problems.
I'll see if I can create a minimal reproduction project for the gulp / browserify maintainers.

Related

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

Using gulp-load-tasks in a gulpfile

I have a project that was using Grunt. I am moving it to use Gulp. My Grunt implementation was like this:
gruntfile.js
/e2e
page.e2e.js
/tasks
e2e.js
/configuration
clean.js
concat.js
I have this approach working in Grunt. However, I now want to mimic this approach in Gulp. At this time, I have the following in Gulpfile.js
gulpfile.js
'use strict';
var gulp = require('gulp');
var tasks = require('gulp-load-tasks')('tasks');
Then, in e2e.js, I have the following:
e2e.js
var gulp = require('gulp');
var rimraf = require('gulp-rimraf');
gulp.task('clean, function(cb) {
console.log('here');
});
When I run gulp from the command-line, I get an error that says: "Error: Task e2e can't support dependencies that is not an array of strings." I'm not sure how to fix this. I haven't even gotten to the part where I'm putting the definition of the clean task in /tasks/configuration/clean.js.
Thank you for any insights you can provide!
You have an error in the code:
gulp.task('clean, function(cb) {
console.log('here');
});
You forgot to close the string 'clean.
Running gulp from the command line should technically return nothing / error out since you have no default task defined (is shorthand for gulp default).
With regards to the actual message you are getting something isn't checking out with task e2e when gulp-load-tasks is pulling it in.
In regards to that structure i dunno if i'd use gulp-load-tasks, instead try:
https://www.npmjs.com/package/require-dir
oh and also to load your gulp modules (if any) check out:
https://www.npmjs.com/package/gulp-load-plugins
Need more info, what's in your e2e file?

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' }))

Node.js/Grunt - Can't run Grunt's watch - why?

I am trying to use the autoprefixer css post-processor. I am following a tutorial and have installed npm. Using a npm, I then installed grunt and autoprefixer inside my project root using that package.json file: https://github.com/nDmitry/grunt-autoprefixer/blob/master/package.json
Following the tutorial, I then created this Gruntfile.js inside my project root:
module.exports = function (grunt) {
grunt.initConfig({
autoprefixer: {
dist: {
files: {
'build/style.css': 'style.css'
}
}
},
watch: {
styles: {
files: ['style.css'],
tasks: ['autoprefixer']
}
}
});
grunt.loadNpmTasks('grunt-autoprefixer');
grunt.loadNpmTasks('grunt-contrib-watch');
};
After that the tutorial advises to use Grunt Watch using
./node_modules/.bin/grunt watch
Which results in
-bash: ./node_modules/.bin/grunt: No such file or directory
I also tried to navigate to the grunt folder inside my project, then it says
-bash: node_modules/grunt: is a directory
I also have a node_modules folder directly in my local user folder, but addressing that folder grunt also just tells me that its a folder.
Pleaser help me, why is this not working? I am willing to really learn grunt, but I am not even able to get started using the getting started guide...
Have you installed the grunt-cli? (npm install grunt-cli -g) What happens when you run grunt in your project root? The command you should be running is simply grunt watch, in your project root.
Edit: Your project root must also have a package.json file in which you define your development dependencies; e.g.
{
"name":"yourprojectname",
"version":"0.0.1",
"devDependencies":{
"grunt":"*",
"grunt-contrib-watch":"*",
"grunt-autoprefixer":"*"
}
}
if there is acutally a space in the executable name you need to put it in quotes
"./node_modules/.bin/grunt watch"
otherwise linux will run "./node_modules/.bin/grunt" with watch as a flag.
if that still doesn't work,
could be a few problems, either your ldconfig isn't updated, the files aren't set to executable, or the user you are trying to execute the command with doesn't have permission.
first try running "ldconfig" (just type and run it)
more info here
http://www.cyberciti.biz/tips/linux-shared-library-management.html
chmod -x the files to make them executable.
any luck?

Working project structure that uses grunt.js to combine JavaScript files using RequireJS?

I have some projects that use RequireJS to load individual JavaScript modules in the browser, but I haven't optimized them yet. In both development and production, the app makes a separate request for each JavaScript file, and now I would like to fix that using Grunt.
I have tried to put together a simple project structure to no avail, so I'm wondering if someone can provide a working example for me. My goals are the following:
In development mode, everything works in the browser by issuing a separate request for each required module. No grunt tasks or concatenation are required in development mode.
When I'm ready, I can run a grunt task to optimize (combine) all of the JavaScript files using r.js and test that out locally. Once I'm convinced the optimized application runs correctly, I can deploy it.
Here's a sample structure for the sake of this conversation:
grunt-requirejs-example/
grunt.js
main.js (application entry point)
index.html (references main.js)
lib/ (stuff that main.js depends on)
a.js
b.js
requirejs/
require.js
text.js
build/ (optimized app goes here)
node_modules/ (necessary grunt tasks live here)
Specifically, I'm looking for a working project structure that I can start from. My main questions are:
If this project structure is flawed, what do you recommend?
What exactly needs to be in my grunt.js file, especially to get the r.js optimizer working?
If all of this isn't worth the work and there's a way to use the grunt watch task to automatically build everything in development mode every time I save a file, then I'm all ears. I want to avoid anything that slows down the loop from making a change to seeing it in the browser.
I use the grunt-contrib-requirejs task to build project based on require.js. Install it inside your project directory with:
npm install grunt-contrib-requirejs --save-dev
BTW: --save-dev will add the package to your development dependencies in your package.json. If you're not using a package.json in your project, ignore it.
Load the task in your grunt file with:
grunt.loadNpmTasks('grunt-contrib-requirejs');
And add the configuration to your grunt.initConfig
requirejs: {
production: {
options: {
baseUrl: "path/to/base",
mainConfigFile: "path/to/config.js",
out: "path/to/optimized.js"
}
}
}
Now you're able to build your require.js stuff into a single file that will be minimized with uglifyjs by running grunt requirejs
You can bundle a set of different tasks into some sort of main task, by adding this to your grunt file
grunt.registerTask('default', ['lint', 'requirejs']);
With this, you can simply type grunt and grunt will automatically run the default task with the two 'subtasks': lint and requirejs.
If you need a special production task: define it like the above
grunt.registerTask('production', ['lint', 'requirejs', 'less', 'copy']);
and run it with
grunt production
If you need different behaviors for 'production' and 'development' inside i.e. the requirejs task, you can use so called targets. In the configuration example above it's already defined as production. You can add another target if you need (BTW, you can define a global config for all targets by adding a options object on the same level)
requirejs: {
// global config
options: {
baseUrl: "path/to/base",
mainConfigFile: "path/to/config.js"
},
production: {
// overwrites the default config above
options: {
out: "path/to/production.js"
}
},
development: {
// overwrites the default config above
options: {
out: "path/to/development.js",
optimize: none // no minification
}
}
}
Now you can run them both at the same time with grunt requirejs or individually with grunt requirejs:production, or you define them in the different tasks with:
grunt.registerTask('production', ['lint', 'requirejs:production']);
grunt.registerTask('development', ['lint', 'requirejs:development']);
Now to answer your questions:
I would definitely use a subfolder in your project. In my case I use a 'src' folder for development that is build into a 'htdocs' folder for production. The project layout I prefere is:
project/
src/
js/
libs/
jquery.js
...
appname/
a.js
b.js
...
main.js // require.js starter
index.html
...
build/
... //some tmp folder for the build process
htdocs/
... // production build
node_modules/
...
.gitignore
grunt.js
package.json
see above
You can do so, but I wouldn't recommend to add requirejs to the watch task, it's a resource hungry task and it will slow down your machine noticeable.
Last but not least: Be very cautious when playing around with r.js. Especially when you want to optimize the whole project with r.js by adding a modules directive to your config. R.js will delete the output directory without asking. If it happens that it is accidentally configured to be your system root, r.js will erase your HDD. Be warned, I erased my whole htdocs folder permanently some time ago while setting up my grunt task... Always add keepBuildDir:true to your options when playing around with the r.js config.

Categories