npm/gulp/nodejs : Different files for production - node.js

I have a gulp script that concatenate and minify my JavaScript.
With the gulp-html-replace plugin I can replace all my JS dependancies by the concatened file in my index.html.
I end up with a dev version (/dev/index.html), with all the single JS files included (easier for debugging) and a production version,with all JS concatened (/prod/index.html).
For now I have a config flag (in NodeJS) in a config.js file and I do the following :
res.render(((config.build === 'prod') ? './prod' : './dev') + 'myPage')
But I'm not really happy with this solution as it adds a lot of code and it's easy to forget to write this code.
Is there a better solution ?
Does this solution take place in Gulp
(by havign a gulp prod and a gulp dev for example)
Or does it take place in Node (by setting up a virtual directory for example)
I am new to this npm/gulp/node workflow and not sure of what belongs where

The way I like to do it is by maintaining two separate versions for index.html.
index-development.html for dev environment and index-production.html for production environment.
The index-development.html includes all the scripts and css (non minified and concatenated) and index-production.html as minified and concatenated scripts and css links.
I construct index.html from gulp script.
By default the index-development.html will be deployed.
If I specify parameter p to the gulp script, it will deploy index-production.html
No need to update the file path of the file to be served in your express router.
First do
npm install yargs
In gulp, I include
var argv = require('yargs').argv;
Check if parameter p (gulp -p) is passed to the gulp (p for production) with
var isProduction = argv.p;
and then,
if(isProduction){
taskSequence = ['combineControllers','combineServices','productionsIndex','startServer'];
} else{
taskSequence = ['developmentIndex','startServer'];
}
gulp.task('default', taskSequence);
gulp.task('startServer', function(){
exec('npm start', function (err, stdout, stderr) {
console.log(stdout);
console.log(stderr);
cb(err);
});
});
gulp.task('productionsIndex', function(done) {
return gulp.src('./www/index-productions.html')
.pipe(concat('index.html'))
.pipe(gulp.dest('./public/'));
});
gulp.task('developmentIndex', function(done) {
return gulp.src('./www/index-development.html')
.pipe(concat('index.html'))
.pipe(gulp.dest('./public/'));
});
This way, your index.html file will be constructed dynamically without having to change of the code in your express and you can serve it like
res.render('index');
if you want to user myPage.html everywhere, just replace index.html and index in the code above with myPage.html and myPage.
EDIT:
To start your application in development environment, simply run gulp
To start your application in production environment, simply run gulp -p
Simple!

in your app initialization process you can set the path of your views.
app.set('views', process.cwd() + ((config.build === 'prod') ? '/prod' : '/dev'));
Now you can call the render function like this:
res.render('myPage');

Related

Using gulp.src(xyz).pipe(gulp.dest(xyz)); Facing Issues, Why not working for me?

Following code, tried with both ./ as src and dest. Gave security administration full rights to folders, just in case if there was any issue.
So whenever I change styles.css from the styles folder, the code runs good on gulp watch and detects change too. It does run styles command on file change too. But then no folders are created in my dest folder.
var gulp = require('gulp');
gulp.task('styles' , function() {
return gulp.src('/app/assets/styles/styles.css')
.pipe(gulp.dest('/app/styles.css'));
});
gulp.task('watch',function(){
gulp.watch('./app/assets/styles/styles.css',
function() {
gulp.start('styles');
});
});
gulp.dest() takes a folder only, not a file. It probably is creating a folder, it is just called styles.css! Look under that for your file styles.css.
You probably want gulp.dest('./app'). the file name will be retained automatically.
I would also simplify to the below. gulp.start is not really documented.
gulp.task('watch',function(){
gulp.watch('./app/assets/styles/styles.css', ['styles']);
});
gulp.task('styles' , function() {
// added the . before /app here and in dest
return gulp.src('./app/assets/styles/styles.css')
.pipe(gulp.dest('./app'));
});

Scss to css in angular while compiling

I need some help.
I'm looking for a way to generate (or update if the file already exists) a .css file that is a conversion by an .scss file. All of this when compiling.
Explaining this in a better way :
I'm writing some code, everything is ok and I decide to save. Perfect. ctrl+s and the app run perfectly. Nice. Now I've added a style.scss file somewhere (it doesn't really matter the path). How do I "tell" to the compiler that everytime he compile he also has to 'take' this .scss file, convert it in a .css file, and put it in a specific path?
Well, I found a way to do what I needed to do.
I've created my gulpfile.js in this way :
var gulp = require('gulp');
var sass = require('gulp-sass');
var watch = require('gulp-watch');
gulp.task('styles', function () {
gulp.src('src/app/sass/*.scss')
.pipe(sass().on('error', sass.logError))
.pipe(gulp.dest('./css/'));
});
gulp.task('watch', function () {
gulp.watch('./sass/**/*.scss', ['styles']);
});
And added this command to package.json :
"try": "gulp watch && ng s"
the problem is that if in the cli I run the command npm run try it will never start my application, because the watch is an endless stream.
How can I have the watch and the app running both at the same time?
*Edit
Found the solution using concurrently

Gulp Watching Creates Infinite Loop Without Changing Files

Similar to other questions, in this very watered-down snippet, running the default gulp task (via npm start which runs gulp); this snippet creates an infinite loop running the scripts task over and over. Here is the gulpfile.js (literally the whole thing at the moment):
'use strict';
const gulp = require('gulp');
// COPY SCRIPTS TO BUILD FOLDER
gulp.task('scripts', function() {
return gulp.src('./scripts/**/*.js')
.pipe(gulp.dest('build/scripts'))
});
// WATCH FILES
gulp.task('watch', function() {
gulp.watch('./scripts/**/*.js', ['scripts']);
});
// DEFAULT
gulp.task('default', ['watch']);
The extra odd thing is that whether the build folder is built anew or not, the scripts task will be executed immediately after calling npm start! And the loop begins.
In case you're curious, here is the pasted (and only) scripts object in my package.json:
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "gulp"
},
The only other thing in my directory is a scripts folder with an app.js and an home.js file in it. Obviously once this task is run, the build folder is created (if it wasn't already there yet) and the two aforementioned files are copied into it.
You can see I'm only looking for scripts in the root directory's first level folder called scripts, so I shouldn't have an infinite loop by referencing changes on the same set of scripts. Also, even if I'm explicit, and point to exactly one particular file with a relative path such as ./scripts/home.js this still happens.
I'm anticipating being embarrassed, but I'm utterly confused.
A few things I've picked up on which could be causing some errors.
EDIT -
Try the watch plugin npm install --save-dev gulp-watch
// Try and declare your plugins like this for now.
var gulp = require('gulp'),
watch = require('gulp-watch');
// Provide a callback, cb
gulp.task('scripts', function(cb) {
// Dont use ./ on your src as watch can have a problem with this
return gulp.src('scripts/**/*.js')
.pipe(gulp.dest('./build/scripts'), cb); // call cb and dont forget ;
});
// remove ./ on watch
gulp.task('watch', function() {
gulp.watch('scripts/**/*.js', ['scripts']);
});
gulp.task('default', ['watch']);
So that is pretty weird behaviour but this should do the trick.
The only time I use ./ within gulp is on my dest.
Also just remember that gulpfile is just a JS so remember your semicolon, etc.
I cannot guarantee the resolution here, but I had a two variables that changed when this was resolved:
I upgraded my Parallels VM application (on an Apple PowerBook) from
version 10 -> 11.
I reinstalled Windows 10 using another license for a current version
(the previous one was a licensed dev or early release version).
My code, Node version, devDependencies and versions were identical.

Unable to get connect-livereload to work with express server in gulp task

I am working off of Yeoman's gulp-webapp generator. I have modified my gulp serve task to use my Express server, rather than the default connect server it ships with. My issue is with Livereload functionality. I am trying to simply port the connect-livereload to work with my Express server rather than having to install new dependencies. It's to my understanding that most connect middleware should work fine with Express, so I am assuming connect livereload is compatible with Express 4.
Here are the contents of the relevant tasks in my gulpfile:
gulp.task('express', function() {
var serveStatic = require('serve-static');
var app = require('./server/app');
app.use(require('connect-livereload')({port: 35729}))
.use(serveStatic('.tmp'));
app.listen(3000);
});
gulp.task('watch', ['express'], function () {
$.livereload.listen();
// watch for changes
gulp.watch([
'app/*.ejs',
'.tmp/styles/**/*.css',
'app/scripts/**/*.js',
'app/images/**/*'
]).on('change', $.livereload.changed);
gulp.watch('app/styles/**/*.css', ['styles']);
gulp.watch('bower.json', ['wiredep']);
});
gulp.task('styles', function () {
return gulp.src('app/styles/main.css')
.pipe($.autoprefixer({browsers: ['last 1 version']}))
.pipe(gulp.dest('.tmp/styles'));
});
gulp.task('serve', ['express', 'watch'], function () {
require('opn')('http://localhost:3000');
});
With this simple setup, when I run gulp serve in my cmd everything spins up fine and I can accept requests at http://localhost:3000.
Now if I go and change the body's background color from #fafafa to #f00 in main.css and hit save, my gulp output will respond with main.css was reloaded, as seen in the bottom of this screenshot.
However, my webpage does not update. The background color is still light-grey instead of red.
Is there perhaps a conflict between my express server config and the way gulp handles its files? Is my Express server forcing the use of app/styles/main.css rather than the use of .tmp/styles/main.css? Shouldn't the livereload script handle the injection of the new temporary file?
Thanks for any help.
EDIT:
I was able to move forward a bit by adding livereload.js to the script block of my index file, like so:
<script src="http://localhost:35729/livereload.js"></script>
I am now able to get live changes pushed to the client. Why was this file not getting injected before? How can I ensure this is getting used programatically as opposed to pasting it into my files?
I was able to get past this issue by removing the app.use(require('connect-livereload')({port: 35729})) from my gulpfile, along with a couple of other lines, and having that instantiate in my Express server's app.js file.
My gulpfile's express task now looks like this:
gulp.task('express', function() {
var app = require('./server/app');
app.listen(3000);
});
I added in the connect-livereload just above where I specify my static directory in Express:
if (app.get('env') === 'development') {
app.use(require('connect-livereload')());
}
app.use(express.static(path.join(__dirname, '../app')));
Once I started using this setup, I was getting the livereload.js script injected into my document, and client-side changes are now auto-refreshed just how I wanted.
Hope this helps someone!

huge files size when browserifying angular

I am just trying gulp + angular + browserify app and got a huge browserified file, about 2M. While all it does just require angular and a sample controller.
// setup gulp task
gulp.task('browserify', function() {
gulp.src([util.format('%s/app/main.js', JS_BASE_DIR)])
.pipe(browserify({
insertGlobals: true,
debug: true
}))
// Bundle to a single file
.pipe(concat('bundle.js'))
// Output it to our dist folder
.pipe(gulp.dest(util.format('%s/js/', BUILD_BASE_DIR)));
});
//in the main.js
(function() {
'use strict';
var angular = require('angular');
var indexCtrl = require('./controllers/indexCtrl');
var app = angular.module('wohu.app', []);
app.controller('ctrl', indexCtrl);
})();
angular is installed via
npm install angular
The bundle.js is not minified but it shouldn't be that huge. Wonder what the problem is.
Browserify will include a source map in the bottom of the file which can make it seem HUGE. You can strip this out (and you should) for production. You can use exorcist for this (https://www.npmjs.com/package/exorcist) which pulls the source map into an external file for you and can be hooked up to your build process (I use Grunt but will work for Gulp too).

Resources