generate source map with grunt closure compiler? - javascript

Is there a way to generate source maps with grunt closure compiler?
I tried both grunt-closure-compiler and grunt-closure-tools but I can't seem to get it to generate the source map file.
Here are my settings:
Here I tried both inside options and outside, both with the value true or path/to/src.map. I couldn't find documentation for this.
'closure-compiler': {
lib : {
closurePath: 'closure-compiler',
js: 'path/to/src.js',
jsOutputFile: 'path/to/output.js',
maxBuffer: 10000,
// sourceMap: true / 'path/to/src.map'
options: {
compilation_level: 'ADVANCED_OPTIMIZATIONS',
language_in: 'ECMASCRIPT5',
externs: ['externs/*.js'],
// sourceMap: true / 'path/to/src.map'
}
}
},
Here I followed the docs but could not get it to work.
closureCompiler: {
options: {
compilerFile: 'closure-compiler/build/compiler.jar',
create_source_map: 'path/to/src.map',
compilation_level: 'ADVANCED_OPTIMIZATIONS',
externs: ['externs/*.js']
},
lib : {
src: 'path/to/src.js',
dest: 'path/to/output.js'
}
}
What am I missing?

For grunt-closure-compiler, this works in my project:
'closure-compiler': {
dev: {
js: ['src/**/*.js'],
jsOutputFile: 'dist/js/output.js',
maxBuffer: 500,
noreport: true,
options: {
compilation_level: 'ADVANCED_OPTIMIZATIONS',
language_in: 'ECMASCRIPT5_STRICT',
warning_level: 'VERBOSE',
use_types_for_optimization: undefined,
output_wrapper: '(function(){%output%\n}).call(window)',
create_source_map: 'dist/js/output.js.map'
}
}
}

Related

Karma unit test for ES6 modules with babel

I'm following instructions from karma-babel-preprocessor to set up unit tests in a project I'm currently working, but I always the error
'require is not defined'
My karma.conf.js is as follows:
files: [
{ pattern: './test/unit/*.spec.js', watched: true },
{ pattern: './src/js/es6_modules/*.js', watched: false },
],
preprocessors: {
'./src/js/es6_modules/*.js': ['babel'],
'./test/unit/*.spec.js': ['babel'] //, 'coverage'
},
babelPreprocessor: {
options: {
presets: ['es2015'],
sourceMap: 'inline'
},
filename: function (file) {
return file.originalPath.replace(/\.js$/, '.es5.js');
},
sourceFileName: function (file) {
return file.originalPath;
}
}
The scripts in src/js/es6_modules jave ES6 classes exported. Something like:
export default class MyClass {
}
And my spec file would need to import this
import { MyClass } from "../../src/js/es6_modules/myclass";
I have seen some thread here at SO that said I would need to use browserify, but I can't find any doc (or example) on how to use it together with babel in karma. Does anyone know to configure this properly?
I fixed it using browserify instead of babel, and using a babelify transform
preprocessors: {
'./src/js/es6_modules/*.js': ['browserify'],
'./test/unit/*.spec.js': ['browserify']
},
browserify: {
debug: true,
"transform": [
[
"babelify",
{
presets: ["es2015"]
}
]
]
},

Grunt + Browser sync: no CSS injection or ghost mode

I'm encountering some confusing issues with getting the browser sync plugin for Grunt to work properly. I have thoroughly read the docs and followed examples but there are a couple of things that won't work:
1) I'm not getting any CSS injection. I know I am running the plugin alongside a watch task, but I have watchTask: true set and my terminal is showing that bS is identifying the change to my CSS, it's just not reloading the browser.
2) None of the ghost mode options seem to work for me. I have set them all to true but, much like the livereload feature, I'm not able to make it work.
Here is my current Gruntfile:
'use strict';
module.exports = function (grunt) {
grunt.initConfig({
watch: {
less : {
files: ['static/css/less/*.less'],
tasks: ['less']
},
html : {
files: ['*.html']
},
js : {
files: ['static/js/*.js']
}
},
less: {
development: {
options: {
paths: ["css"],
compress: true,
yuicompress: true,
optimization: 2
},
files: {
"static/css/styles.css": "static/css/less/styles.less"
}
}
},
browserSync: {
default_options: {
bsFiles: {
src: [
"static/css/*.css",
"*.html"
]
},
options: {
watchTask: true,
server: {
baseDir: "./"
},
ghostMode: {
clicks: true,
forms: true,
scroll: true
}
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-browser-sync');
// Launch BrowserSync + watch task
grunt.registerTask('default', ['browserSync', 'watch']);
};
Any help would be really appreciated

Live reload using grunt-contrib-connect and grunt-contrib-watch

I am new to nodeJS and grunt. I have this Gruntfile in this project and I want to do live reload for all the html files in my project, so that I do not have to refresh my browser all the time to detect new changes. Somehow I encounter error with the following code:
module.exports = function (grunt)
{
// Project configuration.
grunt.initConfig(
{
// Task configuration.
jshint:
{
options:
{
curly: true,
eqeqeq: true,
immed: true,
latedef: true,
newcap: true,
noarg: true,
sub: true,
undef: true,
unused: true,
boss: true,
eqnull: true,
browser: true,
globals: {}
},
gruntfile:
{
src: 'Gruntfile.js'
},
lib_test:
{
src: ['lib/**/*.js', 'test/**/*.js']
}
},
connect:
{
server:
{
options:
{
hostname: 'localhost',
port: 80,
base: 'src',
keepalive: true,
livereload: true
}
}
},
watch:
{
options:
{
livereload:true
}
}
});
// These plugins provide necessary tasks.
grunt.loadNpmTasks('grunt-contrib-connect');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-watch');
// Default task.
grunt.registerTask('default', ['connect', 'watch']);
};
It seems that when I start 'grunt default' it would not execute task watch because during connect it is keepalive.
I will be grateful if any1 can explain to me why I have this error when JSHint check my code and suggest a solution to this.
Your watch task does not have any tasks or files. For it to work with grunt-contrib-connect, you need to include more than just the livereload option, like so:
watch: {
options: {
livereload: true
},
taskName: { // You need a task, can be any string
files: [ // Files to livereload on
"app/js/*.js",
"app/templates/*.html"
]
}
}
Or alternately:
watch: {
taskName: {
options: { // Live reload is now specific to this task
livereload: true
},
files: [ // Files to livereload on
"app/js/*.js",
"app/templates/*.html"
]
}
}
All files that match the glob patterns here should then work as you're expecting. You do not need to specify a tasks parameter here if you are just live reloading these for the browser.
Also, if you are going to be using your connect server alongside watch, you should remove the keepalive parameter as it is a blocking task and can prevent executing the watch task:
connect: {
server: {
options: {
port: 8080,
base: 'src',
livereload: true
}
}
}
You need node:true in your jshint config, take a look at this example .jshintrc.
For the watch and livereload, you need to specify which files to watch, and what tasks to execute in your Gruntfile, again, take a look at this sample Gruntfile.
For example like this:
watch: {
coffee: {
files: ['<%%= config.app %>/scripts/{,*/}*.{coffee,litcoffee,coffee.md}'],
tasks: ['coffee:dist']
},
}
In this example, you specify a glob as files option and whenever that files change the according tasks are run.

Conditionally removing DEBUG during uglifyjs task on Grunt

I would like to remove my DEBUG statments at build, and I noticed on http://lisperator.net/uglifyjs/compress I can define global_defs: { DEBUG : false } to remove anything wrapped in a debug clause if (DEBUG) {}
My uglify task doesn't seem to remove any DEBUG section, any thoughts on what I'm doing wrong?
I'm using grunt-contrib-uglify v0.3.3
Here is my grunt task:
...
uglify: {
...
simple: {
options : {
mangle: false,
compress: {
global_defs: {
DEBUG: false
},
dead_code: true
}
},
files: {
'yayMin.js' : [ ..., somefile.js, ... ]
}
},...
...
somefile.js
...
if (DEBUG) {
console.log('epic fail - fix your build');
}
...
Also check out grunt-groundskeeper which removes pragmas written like this:
// <debug>
doSomething();
// </debug>
// <validation>
performSomeValidationOnlyNeededDuringDevelopment();
// </validation>
It also has options to remove calls to console.log() and debugger; statements.
There appears to be a bug in grunt-contrib-uglify that only removes the global_defs from one file. I noticed DEBUG statements would be removed, as requested by options, if I reduced my files to one file
Did not work:
...
files: {
'yayMin.js' : [ ..., anotherfile.js, somefile.js, anotherfile2.js, ... ]
}
...
Worked:
...
files: {
'yayMin.js' : [ somefile.js ]
}
...
Final Grunt Task
uglify: {
'build-minify' : {
options: {
mangle: false,
compress: {
global_defs: {
DEBUG: false
},
dead_code: true
},
wrap: true
},
files : {
'justSayNoToDebug.js' : [
'ahHaveDebugsInMe.js'
]
}
},

How to output two files using grunt durandal

I am having a go at grunt for optimizing my Durandal SPA. It seems to work great but now I would like to output a second file called libs.js which is the merged uglified version of all my required libraries but my first dist is getting ignored and still the only file I get is main-built.js
I only get one file so app/libs.js never gets created. I also have no grunt errors.
Here is my Gruntfile:
module.exports = function (grunt) {
grunt.initConfig({
durandal: {
libs: {
src: [
"../scripts/jquery-1.9.1.js",
"../scripts/typeahead.js",
"../scripts/jquery-ui-1.10.3.js",
"../scripts/knockout-3.0.0rc.js",
"../scripts/toastr.js",
"../scripts/q.js",
"../scripts/breeze.min.js",
"../scripts/bootstrap.js",
"../scripts/moment.js",
"../scripts/lodash.js",
"../scripts/respond.js",
"../scripts/knockout-sortable.js",
"../scripts/knockout-bootstrap.js",
"../scripts/knockout.validation.js",
],
dest: 'scripts/libs.js',
options: {
uglify2: {
compress: {
global_defs: {
DEBUG: false
}
}
}
}
},
dist: {
src: [
"app/**/*.*",
"scripts/durandal/**/*.*"
],
options: {
baseUrl: "app/",
mainPath: "app/main.js",
out: "app/main-built.js",
uglify2: {
compress: {
global_defs: {
DEBUG: false
}
}
}
}
}
}
});
grunt.loadTasks('tasks');
grunt.registerTask('default', ['durandal']);
};
This is JavaScript. If you create an object like { a: 'a', a: 'b' }, the first key will be overwritten by the second by the VM.
Instead of configuring it like this:
dist: {
// config goes here
},
dist: {
// config goes here
}
Try
libs: {
// config goes here
},
main: {
// config goes here
}

Categories