Source maps in uglified requirejs project - requirejs

I have a requirejs project, I'm compiling with grunt-requirejs ("grunt-contrib-requirejs": "~0.4.1") into 1 big file: main.js. This task has source map generation enabled:
requirejs: {
compile: {
options: {
baseUrl: 'source/js',
name: 'main',
optimize: 'none',
generateSourceMaps: true,
out: 'build/js/main.js',
wrap: true,
shim: requireJsConfig.shim,
paths: requireJsConfig.paths
}
}
}
After that I minify this main.js with grunt-uglify ("grunt-contrib-uglify": "~0.2.7") using this configuration:
app: {
options: {
beautify : {
quote_keys: true
},
compress: false,
report: 'min',
sourceMap: 'build/js/main.js.map',
sourceMapIn: 'build/js/main.js.map', // input from requirejs
sourceMapIncludeSources: true
},
files: {
'build/js/main.js': ['build/js/main.js']
}
}
I would like to have a source map that will tell me an error in the source files (the ones requirejs consumes), but instead source map refuses to work at all. Please help me to get there as I'm feeling helpless already.

grunt-require comes with it's own uglify package built in:
eg.
requirejs: {
compile: {
options: {
generateSourceMaps: true,
logLevel: 4,
baseUrl: "common/scripts/",
include: "./main",
out: "common/dist/main.js",
preserveLicenseComments: false,
optimize: "uglify2",
mainConfigFile: "common/scripts/main.js"
}
}
}

Related

Setting a target or multiplefile for a grunt task with sass and autoprefixer?

I'm setting a grunt file for a task. My goal is to create a css file from a sass file (scss) and add an autoprefix to all the proprieties which require so. Initially I used the propriety multifiles but it didn't work, so now I'm using the target propriety that works fine, but my problem is, even if I target the very same file, it will create another file in my folder where I put all my sass files.
So far my file is the following:
module.exports = function (grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
sass: {
dev: {
options: {
style: 'expanded',
sourcemap: 'none',
},
files: {
'../style.css': 'scss/style.scss'
}
},
dist: {
options: {
style: 'compressed',
sourcemap: 'none',
},
files: {
'../style-min.css': 'scss/style.scss'
}
}
},
autoprefixer: {
options: {
browsers: ['last 6 versions']
},
target: {
expand: true,
flatten: true,
src: '../style.css',
dest: ''
}
},
watch: {
css: {
files: '**/*.scss',
tasks: ['sass', 'autoprefixer']
}
},
});
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-autoprefixer');
grunt.registerTask('default', ['watch']);
}
My goal is to set up a global task for all my css files, like so:
target: {
expand: true,
flatten: true,
src: '*.css',
dest: ''
}
but it is not working even if I try something like:
target: {
expand: true,
flatten: true,
src: '../*.css',
dest: ''
}
Does anyone know why?
Use cwd (stands for current working directory) which is the path where grunt looks for the files matching the pattern in src. Also define the dest so that it would create the destination file in the same folder.
target: {
expand: true,
flatten: true,
cwd: '../',
src: [ '**/*.css' ],
dest: '../'
}

How to configure Grunt serve/livereload to combine mustache templates

I'm using Yeoman template to develop a static web site. grunt serve nicely works with the auto reload plugin.
For repeating elements I started to use {{mustache}} partials and it works like a blast. Now I want the auto reload to assemble my page, so I can look at the resulting page when editing one of the mustache files (either a main file or a partial).
I found a grunt task for it, but stitching it together eludes me. My config looks like this:
grunt.initConfig({
sass: {
dev: {
src: ['src/sass/*.sass'],
dest: 'dest/css/index.css',
},
},
watch: {
sass: {
// We watch and compile sass files as normal but don't live reload here
files: ['src/sass/*.sass'],
tasks: ['sass']
},
mustache: {
files: '**/*.mustache',
tasks: ['mustache_render'],
options: {
interrupt: true
},
},
livereload: {
options: { livereload: true },
files: ['dest/**/*']
}
},
mustache_render: {
options: {
{data: 'common-data.json'}
},
your_target: {
files: [
{expand: true,
template: '**/*.mustache',
dest: 'dest/'}
]
}
}
});
I must be missing something since the html files are not updated when I save the file.
You can add the livereload option directly to your mustache target options.
grunt.initConfig({
watch: {
mustache: {
files: '**/*.mustache',
tasks: ['mustache_render'],
options: {
interrupt: true,
livereload: true
},
}
},
mustache_render: {
options: {
{data: 'common-data.json'}
},
main: {
files: [
{expand: true,
template: '**/*.mustache',
dest: 'dest/'}
]
}
}
});
Also, if you're using grunt-contrib-connect to serve your files, don't forget to add the livereload option to it:
connect: {
http: {
options: {
hostname: "*",
port: process.env.PORT || 80,
livereload: true
}
}
}

Wrong CSS Path - Live Reload issue with Grunt

I have this setup in my Gruntfile.js
module.exports = function(grunt) {
grunt.initConfig({
less: {
development: {
options: {
compress: false,
yuicompress: false,
optimization: 0
},
files: {
// target.css file: source.less file
"assets/css/main.css": "assets/css/main.less"
},
}
},
watch: {
styles: {
// Which files to watch (all .less files recursively in the less directory)
files: ['assets/css/*.less', 'assets/less/*.less'],
tasks: ['less'],
},
// Live reload CSS
css: {
files: ['assets/css/*.css'],
options: {
nospawn: true,
interrupt: false,
livereload: true,
},
},
},
});
// Watch
grunt.loadNpmTasks('grunt-contrib-watch');
// Less Complile
grunt.loadNpmTasks('grunt-contrib-less');
grunt.registerTask('default', ['less','watch']);
};
My sylesheet is loaded like this:
<link rel="stylesheet" href="http://project.dev/wp-content/themes/project/style.css">
Whenever I change the css file the I get a 404 error in the browser for this url
http://project.dev/assets/css/main.css?livereload=1392748371895
Which is of course right because the css file lives in:
http://project.dev/wp-content/themes/project/assets/css/main.css
How do I get live reload to get the right URL?
You have to set the base so that Grunt knows where to run the application from. The files the tasks output should be set to reflect the structure Wordpress expects. Its all in the path configuration.
You can achieve a more flexible path structure if you configure it early on Grunt's configuration. Assuming that the Gruntfile.js is in the root of your site (besides the wp-content directory), you could do the following configuration:
grunt.initConfig({
// configurable paths
cfg: {
dist: './wp-content/themes/project'
},
// tasks configurations come here...
});
Then on the watch task, you'd set:
livereload: {
files: ['<%= cfg.dist %>/assets/css/*.css'],
options: {
nospawn: true,
interrupt: false,
livereload: true
}
}
The resulting Gruntfile.js would look like:
module.exports = function(grunt) {
grunt.initConfig({
// configurable paths
cfg: {
dist: './wp-content/themes/project'
},
less: {
development: {
options: {
compress: false,
yuicompress: false,
optimization: 0
},
files: {
'<%= cfg.dist %>/assets/css/main.css': '<%= cfg.dist %>/assets/css/main.less'
}
}
},
watch: {
styles: {
files: ['<%= cfg.dist %>/assets/css/*.less', '<%= cfg.dist %>/assets/less/*.less'],
tasks: ['less']
},
css: {
files: ['<%= cfg.dist %>/assets/css/*.css'],
options: {
nospawn: true,
interrupt: false,
livereload: true
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('default', ['less','watch']);
};
You'd still have to adjust the above to fit your needs, but the principle is there.
I don't have a setup I can test this on, but I think you need to set the base option:
// Project configuration.
grunt.initConfig({
connect: {
server: {
options: {
base: 'www-root'
}
}
}
});
See doc here: https://github.com/gruntjs/grunt-contrib-connect/blob/master/README.md#basic-use
Read down through multiple servers if relevant.

How do I automate the task of compiling front-end frameworks like Twitter Bootstrap in my Node.js project?

How do I automate the task of compiling Twitter Bootstrap in my Node.js project?
I'm editing the LESS files that compile into a custom build of Bootstrap for my Node.js project, so I can't just use the online customizer or the pre-compiled JavaScript/CSS distribution.
How do I use something like Grunt or Bower to automate the process of building and compiling the Twitter Bootstrap front-end framework into my project from source?
Is there a package manager for front-end libraries and frameworks?
I'm using Grunt to compile my LESS. Here are the dependencies which you have to add to your package.json:
"devDependencies": {
"grunt": "0.4.1",
"grunt-contrib-concat": "0.3.0",
"grunt-contrib-watch": "0.4.4",
"assemble-less": "0.4.8"
}
And here is how my Gruntfile.js looks like:
module.exports = function(grunt) {
grunt.initConfig({
less: {
project: {
options: {
paths: ['src/css/less'],
yuicompress: true
},
src: ['src/css/less/index.less'],
dest: 'src/css/styles.css'
}
},
watch: {
css: {
files: ['src/css/less/**/*.less'],
tasks: ['less']
}
}
});
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('assemble-less');
// grunt.registerTask('default', ['concat', 'less']);
grunt.registerTask('default', ['less', 'watch']);
}
And I simply type grunt before to start working. It run a watcher and compiles my less files once something changes.
Edit:
There is also https://github.com/emberfeather/less.js-middleware but you need to add the compilation to the app's flow. This means that you will compile the less files during the run of the nodejs process. This will happen only once and if you make changes in some of the files you will not see the result. Of course you may want to compile on every request, but this will decrease the performance of your app. So, you will end up with some kind of a watcher and compiler. Exactly what Grunt is doing. If you don't want to run grunt every time you may add it to your boot scripts (or startup things under windows).
Depending on your arrangement, you may want to just look into less-middleware. It will compile your LESS into CSS on the fly in development, and in production will do it the first time the CSS is requested, and then serve up the CSS instead of recompiling it every time. Plenty of configuration examples at the included link.
I dont have the settings on hand for grunt-bootstrap and npmjs is offline right now for some reason, try this link for the settings https://npmjs.org/package/grunt-bootstrap
im using the latest version of grunt-bootstrap and grunt-contrib-less like this;
package.json
"devDependencies": {
"grunt": "~0.4.2",
"grunt-cli": "~0.1.11",
"grunt-bootstrap": "~0.1.0",
"grunt-contrib-jade": "~0.8.0",
"grunt-contrib-less": "~0.8.2",
"grunt-contrib-jshint": "~0.7.2",
"grunt-contrib-uglify": "~0.2.7",
"grunt-contrib-watch": "~0.5.3"
//others here
}
Gruntfile.JS less: entry
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
jshint: {
options: {
curly: true,
eqeqeq: true,
immed: true,
latedef: true,
newcap: true,
noarg: true,
sub: true,
undef: true,
boss: true,
eqnull: true,
browser: true,
globals: {
require: true,
define: true,
requirejs: true,
describe: true,
expect: true,
it: true
},
// https://leanpub.com/grunt/read #see 'module' is not defined
node: true
},
// https://leanpub.com/grunt/read #see 'module' is not defined
all: [
'Gruntfile.js',
'src/app/*.js',
'src/config.js',
'tests/app/*.js'
]
},
uglify: {
options: {
banner: '*//*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> *//*\n'
},
build: {
src: 'src/app/<%= pkg.name %>.js',
dest: 'build/app/<%= pkg.name %>.min.js'
}
},
// Run jshint any time a file is added
watch: {
scripts: {
files: [
'Gruntfile.js',
'src/app/*.js',
'tests/app/*.js'
],
tasks: ['jshint'],
options: {
/**
* If you need to dynamically modify your config, the spawn option must be disabled to keep the watch
* running under the same context.
*/
spawn: false
}
},
css: {
files: ['src/assets/css/*.less'],
tasks: ['less']
}
},
less: {
development: {
options: {
paths: ["src/assets/css"],
compress: true,
report: 'gzip',
cleancss: true,
ieCompat: true,
strictImports: true
//dumpLineNumbers
},
files: [{
expand: true,
cwd: "src/assets/css",
src: ['*.less'],
dest: 'build/assets/css',
ext: '.css'
}]
}
/*
production: {
options: {
cleancss: true
},
files: {
}
}*/
},
jade: {
compile: {
options: {
//client: false,
pretty: true,
data: {
debug: false
}
},
files: [ {
cwd: "src/app/views",
src: "**/*.jade",
dest: "build/templates",
expand: true,
ext: ".html"
} ]
}
}
});
// Load task(s)
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-contrib-jade');
grunt.loadNpmTasks('grunt-bootstrap');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-watch');
// Register task(s).
grunt.registerTask('default', [
'jshint',
'uglify',
'less',
'jade',
'bootstrap'
]);
grunt.registerTask('dev', [
'watch'
]);
};
Edit: i found this once again, https://github.com/jgallen23/grunt-bootstrap
i knew it was somewhere out there. there is some of your bootstrap config options your probably looking for that you need to add to the gruntfile.js to complete your task.. Enjoy

Configuring grunt-ts and make it work with LiveReload

I am trying to use TypeScript inside a Yeoman / Grunt project. To compile TypeScript I use a grunt plugin called grunt-ts, the compilation of the .ts files works just fine, but the live reload doesn't works:
When I run grunt server I correctly get this:
Running "ts:dev" (ts) task
Compiling.
Success: 3.37s for 2 typescript files
Watching all Typescript files under : /home/mimo/webroot/tsyong/app/scripts
But then the liveReload task is not loaded.
This is how I configured my Gruntfile.js about grunt-ts.
grunt.initConfig({
...
ts: {
options: { // use to override the default options, http://gruntjs.com/configuring-tasks#options
target: 'es3', // es3 (default) / or es5
module: 'commonjs', // amd , commonjs (default)
sourcemap: true, // true (default) | false
declaration: false, // true | false (default)
nolib: false, // true | false (default)
comments: false // true | false (default)
},
dev: { // a particular target
src: ['<%= yeoman.app %>/scripts/{,*/}*.ts'], // The source typescript files, http://gruntjs.com/configuring-tasks#files
reference: '<%= yeoman.app %>/scripts/reference.ts', // If specified, generate this file that you can use for your reference management
out: '<%= yeoman.app %>/scripts/out.js', // If specified, generate an out.js file which is the merged js file
watch: '<%= yeoman.app %>/scripts/', // If specified, configures this target to watch the specified director for ts changes and reruns itself.
options: { // override the main options, http://gruntjs.com/configuring-tasks#options
sourcemap: true,
declaration: true
},
},
build: { // another target
src: ['<%= yeoman.app %>/scripts/*.ts'],
options: { // overide the main options for this target
sourcemap: false,
}
},
},
...
...
grunt.task.run([
...
'ts',
...
]);
...
grunt.registerTask('build', [
...
'ts',
...
]);
You can have a look at the full Gruntfile.js: https://github.com/mimo84/tsyong/blob/master/Gruntfile.js
Short answer: remove the watch config line https://github.com/mimo84/tsyong/blob/master/Gruntfile.js#L46 and add something like https://github.com/mimo84/tsyong/blob/master/Gruntfile.js#L60
But for ts. i.e.
ts: {
files: ['<%= yeoman.app %>/scripts/{,*/}*.ts'],
tasks: ['ts:dev']
},
Reason: That's because when you ask grunt-ts to watch a folder, grunt-ts marks itself as an async task. This means that then no other tasks can execute afterwards. Its the same with grunt-contrib-watch I think which is why you must have it as the last task:
grunt.task.run([
'clean:server',
'concurrent:server',
'ts',
'connect:livereload',
'open',
'watch' // last task
]);
In short you can only have one task do your watching :) In your case it would have to be grunt-contrib-watch.
I use a very fast and simple way, using browserify & typescriptifier (<2s reload):
module.exports = function (grunt) {
grunt.initConfig({
clean: {
dev: ['dest/**/*.*']
},
browserify: {
dev: {
src: ['src/root.ts'],
dest: 'dest/App.js',
options: {
external: ['angular'],
transform: ['typescriptifier'],
debug: true,
bundleOptions: { debug: true },
browserifyOptions: { debug: true }
}
}
},
express: {
dev: {
options: {
bases: ['src'],
port: 5000,
hostname: '0.0.0.0',
livereload: false
}
}
},
watch: {
ts: {
files: ['src/**/*.ts', '!src/**/*.d.ts'],
tasks: ['dest'],
options: {
livereload: true,
debug: false,
debounceDelay: 100
}
},
html: {
files: ['src/**/*.css', 'src/**/*.html'],
options: {
livereload: true,
debug: false,
debounceDelay: 100,
spawn: false
}
}
}
});
grunt.loadNpmTasks('grunt-express');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-browserify');
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.registerTask('dev', ['rebuild', 'express:dev', 'watch' ]);
grunt.registerTask('build', ['browserify:dev']);
grunt.registerTask('rebuild', ['clean:dev', 'build']);
};
See
https://www.npmjs.org/package/typescriptifier
Not exactly the answer but goes to the underlying point: fast workflow.

Resources