Yeoman + Grunt Disable Uglify - google-chrome-extension

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

Related

How do I register multiple grunt-exec tasks?

I want to define a tree of shell commands in my Gruntfile.js, using grunt-exec to write shell commands.
I can do this for a single command, but I can't figure out the syntax for writing multiple sets of commands, and being able to call them one-by-one, or in groups.
Could someone please provide a fully fleshed out example Gruntfile.js with the following task structure?
test: `npm test`
lint:
jshint: `jshint .`
csslint: `csslint .`
I'm coming from the world of make, so I really want to shove this workflow into my Node.js projects, damn the Node community conventions.
I want grunt to default to npm test
I want grunt lint to perform both jshint . and csslint .
I want grunt jshint to perform only jshint .
A grunt multi-task supports multiple targets, but they can't be nested. But you can register tasks that run other tasks.
Gruntfile.js:
module.exports = function(grunt) {
grunt.initConfig({
exec: {
test: "npm test",
jshint: "jshint .",
csslint: "csslint ."
}
});
grunt.loadNpmTasks("grunt-exec");
grunt.registerTask("default", ["exec:test"]);
grunt.registerTask("test", ["exec:test"]);
grunt.registerTask("lint", ["exec:jshint", "exec:csslint"]);
};
Note that there are already a lot of grunt tasks available, like grunt-contrib-jshint, which make things much simpler.
Grunt lets you register tasks by name, and tasks of tasks. Easily done via arrays of string literal task names, e.g.:
grunt.registerTask('default', ['test']);
grunt.registerTask('lint', ['jshint', 'csslint']);
jshint should already be registered if you've defined it as jshint inside your grunt.initConfig. Keep in mind that, unusual for a node program, everything is highly synchronous. The tasks will run in the order you give them.
edit: in case you need it later, you can also registerTask a function instead of an array of task names. This is how you could go about writing a task that does async work, or if you have very strict ordering requirements that may use control flow logic. Try to stick with just registering based on task name if you can.

requirejs HTML structure

I know we could use requirejs combine files into one js file.
such like the following config.
module.exports = {
baseUrl: 'js/',
mainConfigFile: 'src/js/common.js',
dir: 'scripts/',
optimize: 'uglify2',
modules: [
{
name: 'common',
include: [
'jquery',
]
}
]
};
my result into one file is
common.js
----------------
jquery.js
modernizr.js
common.js
my question is, do we still need to put a require.js file in scripts folder and to use the following format
<script data-main="scripts/common" src="scripts/require.js"></script>
or we could just use
<script src="scripts/common.js"></script>
as files are compressed into one file?
You still need to load require.js the usual way to actually make use of the module loading benefits that it provides, and especially if you use the asynchronous functionality a lot. However, you can have a look at almond providing your code uses AMD and (from the README):
optimize all the modules into one file -- no dynamic code loading.
all modules have IDs and dependency arrays in their define() calls -- the RequireJS optimizer will take care of this for you.
only have one requirejs.config() or require.config() call.
do not use RequireJS multiversion support/contexts.
do not use require.toUrl() or require.nameToUrl().
do not use packages/packagePaths config. If you need to
use packages that have a main property,
volo can create an adapter module so
that it can work without this config. Use the amdify add command to
add the dependency to your project.
Almond is great because it doesn't need require.js at all; it wraps your own code with itself, which is a very minimal AMD loader skeleton and nowhere near as powerful as the main library. You then get a single optimised file that can be linked directly in your HTML:
<script src="scripts/common.js"></script>
The Gruntfile config for almond could look something like this:
compile: {
options: {
name: 'path/to/almond',
baseUrl: 'js',
include: ['main'],
insertRequire: ['main'],
mainConfigFile: 'scripts/config.js',
out: 'scripts/main.js',
optimizeAllPluginResources: true,
wrap: true
}
}
The above is all standard r.js boilerplate, you can find many more examples at the almond homepage.

Understanding the mean stack and integrating uglify.js and stylus

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.

How to replace requirejs with almondjs with a yeoman Gruntfile.js?

So I created a project using yeoman init and it uses requirejs, I wish to replace requirejs with almondjs to make it load faster. How can I do this?
AlmondJS is here: https://github.com/jrburke/almond
RequireJS is here: http://requirejs.org/
Yeoman: http://yeoman.io/
The only mention of require.js in Gruntfile.js is:
// rjs configuration. You don't necessarily need to specify the typical
// `path` configuration, the rjs task will parse these values from your
// main module, using http://requirejs.org/docs/optimization.html#mainConfigFile
//
// name / out / mainConfig file should be used. You can let it blank if
// you're using usemin-handler to parse rjs config from markup (default
// setup)
rjs: {
// no minification, is done by the min task
optimize: 'none',
baseUrl: './scripts',
wrap: true,
name: 'main'
},
Make sure you are using Yeoman 1.0 and not an earlier version. It uses grunt-requirejs which has almond support. rjs was used in versions before 1.0.
See documentation at https://github.com/asciidisco/grunt-requirejs/blob/master/docs/almondIntegration.md. It appears that all you may need to do is add almond: true to the options for requirejs in your Gruntfile (or not depending on what you want to do--again see the documentation).

Nodejs grunt obfuscate

I'm using Nodejs grunt module. I know grunt min option minifies a files. But now I need to obfuscate files like google closure compiler. Does grunt have that feature?
The grunt min task allows you to set UglifyJS (the grunt min tool) options, which can give you greater control on how the destination file is mangled and compressed.
https://github.com/cowboy/grunt/blob/master/docs/task_min.md#specifying-uglifyjs-options
https://github.com/mishoo/UglifyJS
from the grunt task_min doc:
Specifying UglifyJS options
In this example, custom UglifyJS mangle, squeeze and codegen options are
specified. The listed methods and their expected options are explained in
the API section of the UglifyJS documentation:
The mangle object is passed into the pro.ast_mangle method.
The squeeze object is passed into the pro.ast_squeeze method.
The codegen object is passed into the pro.gen_code method.
// Project configuration.
grunt.initConfig({
min: {
dist: {
src: ['dist/built.js'],
dest: 'dist/built.min.js'
}
},
uglify: {
mangle: {toplevel: true},
squeeze: {dead_code: false},
codegen: {quote_keys: true}
}
});

Resources