Understanding the mean stack and integrating uglify.js and stylus - node.js

I'm just getting started with the MEAN stack (https://github.com/linnovate/mean), so I'm pretty sure my question is going to look very basic to an expert, so my apologies in advance!
While I think it would be a gread addition to what this stack already has to offer, I cannot manage to integrate Uglify.js and stylus
Also someone already asked this, but it would make sense to me to use Jade template for both server and public views, at least for a matter of standardization.
I have tried playing with the grunt file and server.js, renaming some files, but all I managed to achieve so far, is break the original project...
Thanks in advance!
EDIT: Just found a fork of this project which has just added support for jade templates for public views: https://github.com/tutley/mean

This post explains how to integrate Stylus pre-processing to the MEAN stack: http://to-s.tk/integrate-stylus-to-the-mean-stack/
Short version:
Move public/css to a new assets/stylesheets and rename all the .css files to .styl
Install grunt-contrib-stylus through npm's package.json, as both a dev and runtime dependency.
-Configure stylus compilation in your Gruntfile
// ...
grunt.initConfig({
// ...
watch: {
// ...
stylus: {
files: ['assets/stylesheets/**/*.styl'],
tasks: ['stylus']
},
// ...
},
// ...
stylus: {
compile: {
options: {
paths: ['assets/stylesheets/**']
},
files: [{
dest: 'public/css/',
cwd: 'assets/stylesheets/',
src: '*.styl',
ext: '.css',
expand: true
}]
}
},
// ...
});
//...
//Load NPM tasks
// ...
grunt.loadNpmTasks('grunt-contrib-stylus');
// ...
Import views stylus files (or any substylus) in common.styl using #require statements
Remove references to views or other substylesheets in head.jade.
Then all assets/stylesheets/*.styl files should be automatically compiled into public/css/*.css, as long as grunt is running. To trigger a compile without relying on watch, you can run grunt stylus.

Related

Uglify or concat a JavaScript file conditionallly

I have in my Scripts folder a "Lib" folder and an "App" folder.
The Lib folder contains 3rd part library JavaScript files. Some of these are minified without the original sources, others we have the original sources for.
The App folder contains all of our own JavaScript files, all of which are not minified.
I'm new to Grunt but I have a gruntfile which does the following:
Uglifies all the JS files in the Lib folder and produces minified versions with sourcemaps.
Uglifies all the JS files in the App folder and produces minified versions with sourcemaps.
Obvious problem: some of the files in the Lib folder are minified, so minifying them again/generating source maps is a bad idea and can fail for various reasons.
My solution: I run Uglify only on .js files in the Lib folder into lib-unmin.min.js. I then concat all the already minified files into a lib-min.min.js file, then I concat both those files together to get lib.min.js.
The new problem
What if I can't concat the already minified scripts to the end of the other minififed scripts without it breaking?
I have a dependency issue like this:
scripts/lib/a.js (required for b to run)
scripts/lib/b.min.js (required for c to run)
scripts/lib/c.js (required for the App scripts to run)
If I have an array of these file paths in my gruntfile, in that order, what's the easiest way of uglifying/concating all the files into a single minified JS file in that order, making sure we don't attempt to minify the minified file?
What do other developers do in similar situations?
Thanks!
I like to concat the files then uglify all of them together. This way uglify makes sure there aren't duplicate variable values overriding each other when it compresses the variable names.
You can bundle as many files as you want in the concats. Make different concat groups to uglify together and maintain the 'first, second, third, ...' order like this:
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
uglify: {
app: {
options: {
sourceMap: true,
sourceMapName: 'build/maps/map.map'
},
files: {
'build/app.min.js': ['build/js/app-first-unmin.js', 'build/js/app-second-min.js', 'build/js/app-third-unmin.js']
}
}
},
concat: {
options: {
separator: ';'
},
firstUnminified: {
src: [
'lib/underscore.js'
],
dest: 'build/js/app-first-unmin.js'
},
secondMinified: {
src: [
'lib/moment.min.js'
],
dest: 'build/js/app-second-min.js'
},
thirdUnminified: {
src: [
'lib/favico.js'
],
dest: 'build/js/app-third-unmin.js'
}
},
});
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.registerTask('default', ['concat:firstUnminified', 'concat:secondMinified', 'concat:thirdUnminified','uglify']);
};

Sails.js + apidocjs + grunt - auto generate documentation

I'm new to Sails.js and Node.js and I have problems with creating documentation for my application.
Here's my steps:
installed apidoc by:
npm install apidoc -g
installed grunt module:
npm install grunt-apidoc --save-dev
added grunt.loadNpmTasks('grunt-apidoc'); to Gruntfile.js at the bottom
created grunt.initConfig file and put:
apidoc: {
myapp: {
src: "api/controllers/",
dest: "apidoc/"
}
}
Then I'm trying to run multiple things, and none of them produces my api documentation:
sails lift
grunt
grunt default
node app.js
If I run it manually by apidoc -i api/controllers/ -o apidoc/ it's working properly.
What am I doing wrong? How to do it?
Super late answer!
From my experience modifying the asset pipeline you'd be better off:
Install apidoc and the Grunt module as in the Question
Create a new file in `tasks/config/apidoc.js:
module.exports = function (grunt) {
grunt.config.set('apidoc', {
myapp: {
src: "api/controllers/",
dest: "apidoc/"
}
});
grunt.loadNpmTasks('grunt-apidoc');
};
Edit tasks/register/compileAssets.js (or wherever you want the task to be run):
module.exports = function (grunt) {
grunt.registerTask('compileAssets', [
'clean:dev',
'jst:dev',
'less:dev',
'copy:dev',
'coffee:dev',
'apidoc:myapp' // <-- This will now run every time your assets are compiled
]);
};
Hope this helps someone

Yeoman + Grunt Disable Uglify

Background:
I'm working on a chrome extension. I used the yeoman generator. It worked like a charm. After I deployed the extension, I needed to debug a few issues.
Problem:
The code is uglified. I can't set break points. I can hardly read it. It is also optimized. This makes it hard to read as well. I would like to tell Grunt to skip uglifying the code.
Attempted Solutions:
I tried to comment out the uglify task in the Grunt file. If I do this, not only is uglify not executed, but most of the scripts fail to copy into the "dist" directory.
I can deploy the application from the "app" directory. If I do this, my human written code is loaded rather than the "dist" values. While this works, I wish to learn more about the inner workings of Grunt. It seems likely that there is some mechanism by which uglifying may be disabled while preserving copying.
It's the usemin task that supplies targets to the uglify task. When you comment out the uglify task usemin can't complete its flow (by default concat and uglify) and the scripts never get copied.
So you must configure the flow in useminPrepare options. Like this:
[...]
useminPrepare: {
options: {
stripBanners: true,
dest: '<%= config.dist %>',
flow: {
steps: {
js: ['concat'], css: ['concat', 'cssmin']
},
post: {}
}
},
[...]
This way you can remove the uglify task from the build sequence (you must, as it will complaint that have no targets and fail).
Documentation here: https://github.com/yeoman/grunt-usemin#flow

foundation 5 with compass and nodejs

I am just getting started with nodejs and I'm trying to understand how everything works...and I'm getting trouble. Please forgive me in advance for the number of questions and the confusion it could generate.
What I'd like to set up is a nodejs server using express, mongodb, passeport, jade, foundation5 with sass and compass, socketio and html boilerplate.It seems to me as a "regular" project but for some reason I couldn't find any skeleton or generator like the one's yeoman provide for it. Is there a key problem with this architecture ?
If I got it correctly, compass is a set of tools for sass but if you go to the foundation website. Either you can install compass with foundation or either grunt with foundation and sass but not foundation with compass and grunt.
Is there a logic behind that ?
Another solution is to compile the sass files on the nodejs server like this:
var express = require('express'),
compass = require('node-compass'),
path = require('path'),
app = express();
app.configure(function() {
app.use(compass());
app.use('/', express.static(path.join(__dirname, 'public')));
});
app.listen(3000);
On which cases is it better to compile it on the server using a middleware such as compass or node-sass rather than using a grunt command that generate the client plain css file to be deployed ?
Thanks in advance.
Update:
I misunderstood one thing:
libsass, the C version of the popular stylesheet preprocessor, Sass.
It allows you to natively compile .scss files to css at incredible speed
At the time of writing libsass (and therefore Node-sass and therefore grunt-sass) does not support Compass.
source
It explains why you can rather use libsass or compass.
grunt command is more effective method, if you have a lot of visitors, better for you is to compile all style into css by grunt command
Middleware is more flexibility, you can change your styles on the fly, but for each user request, all styles will compile again and again. so your server will work more slowly
I'm using grunt with compass. Don't forget to install the grunt-contrib-compass nodes module!
npm install grunt-contrib-compass --save-dev
Here's my gruntfile.js:
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
compass: {
dist: {
options: {
specify: 'library/scss/style.scss',
outputStyle: 'compressed',
sassDir: 'library/scss',
cssDir: 'library/css'
},
}
},
watch: {
// grunt: { files: ['Gruntfile.js'] },
css: {
// files: '**/*.scss',
files: 'library/scss/style.scss',
tasks: ['compass']
}
}
});
grunt.loadNpmTasks('grunt-contrib-compass');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('default',['watch']);
}

Building Durandal with Grunt (R.js + Text)

I would like to use Grunt to build a Durandal project, because Weyland remains completely undocumented and isn't as standard as Grunt.
To do this, the grunt task needs to pull in all the js and html files during optimization, but I am unable to get RequireJS to inline the html files via the text module.
It looks like weyland copies the text files manually, but I can't figure out what it's doing to get requirejs (or almond, in this case), to actually use them. I have seeen this question, but it requires the text modules to be referenced in the define call, which isn't done in Durandal.
My gruntfile for require uses this config
requirejs: {
build: {
options: {
name: '../lib/require/almond-custom', //to deploy with require.js, use the build's name here instead
insertRequire: ['main'], //needed for almond, not require
baseUrl: 'src/client/app',
out: 'build/main-built.js',
mainConfigFile: 'src/client/app/main.js', //needed for almond, not require
wrap: true, //needed for almond, not require
paths: {
'text': '../lib/require/text',
'durandal':'../lib/durandal/js',
'plugins' : '../lib/durandal/js/plugins',
'transitions' : '../lib/durandal/js/transitions',
'knockout': '../lib/knockout-2.3.0',
'bootstrap': '../lib/bootstrap.min',
'jquery': '../lib/jquery-1.9.1',
'Q' : '../lib/q.min'
},
inlineText: true,
optimize: 'none',
stubModules: ['text']
}
}
}
You might want to give https://npmjs.org/package/grunt-durandal a try. I'm using this as part of a grunt based build process. See https://github.com/RainerAtSpirit/HTMLStarterKitPro for an example.
durandal: {
main: {
src: ['app/**/*.*', 'lib/durandal/**/*.js'],
options: {
name: '../lib/require/almond-custom',
baseUrl: requireConfig.baseUrl,
mainPath: 'app/main',
paths: mixIn({}, requireConfig.paths, { 'almond': '../lib/require/almond-custom.js' }),
exclude: [],
optimize: 'none',
out: 'build/app/main.js'
}
}
},
As a possible alternative to Grunt I would suggest looking at Mimosa. It's not as widely used as Grunt but is well documented and requires a good deal less configuration and if you start with the durandal skeleton everything is configured for you including inlining html.
Durandal also recommends it and tells you how to get started with it: http://durandaljs.com/pages/get-started/
You can run make start to start developing and make dist to have it package everything up for release.

Resources