I currently have grunt-browserify to build a few js files into a bundle. I'm trying to add css into the bundle via require('./style.css'). I've been researching some options to do this and found the browserify-css library (https://www.npmjs.com/package/browserify-css). However there is no grunt support so I'm not sure how to add this to my existing grunt settings.
It seems that I need to add browserify-css as a transform option. The grunt-browserify says that the transform option takes an array of tasks (see below). However, I don't think browserify-css can be written as a grunt task. What's the best practice in this situation?
browserify: {
dist: {
files: {
'dist/bundle.js': 'js/index.js'
}
},
transform: ['coffeify']
}
I checked the source code of browserify, and I found this solution:
browserify: {
dist: {
src: 'js/index.js',
dest: 'dist/bundle.js'
},
options: {
transform: [['browserify-css', { global: true }]]
}
}
This works for me when I need to copy css files from node_modules folder. For make it work you only need to run:
npm install browserify browserify-css grunt-browserify --save-dev
and that's it!.
Related
I want to use both Browserify and Babel with my JavaScript. For this I created a gulp task
gulp.task('babel', function() {
return gulp.src('_babel/*.js')
.pipe(browserify({ insertGlobals : true }))
.pipe(babel({ presets: ['es2015'] }))
.pipe(gulp.dest('_dev/js'));
});
Unfortunately, when I want to use import within my code, I am getting an error:
ParseError: 'import' and 'export' may only appear at the top level
My main js file is very simple:
import 'directives/toggleClass';
I'm guessing that it is because of Babel (and it's use strict addition), but what can I do?
Babel maintains an official transform for Browserify called babelify and it should be used wherever possible if using babel and browserify.
Drop the use of babel directly and place babelify as a transform plugin for browserify. There are many ways to configure browserify but specifying config in your package.json would probably be easiest.
"browserify": {
"transform": [["babelify", { "presets": ["es2015"] }]]
}
Your gulp task will then be simplified
gulp.task('babel', function() {
return gulp.src('_babel/*.js')
.pipe(browserify({ insertGlobals : true }))
.pipe(gulp.dest('_dev/js'));
});
Browserify also exposes methods to do this programmatically so you will be able to configure the bundler from inside your gulp task (dropping the package config, although using the package is perfectly fine for this), check their documentation and experiment, I've done it before but its been a long time since I used gulp (using gulp here is just a complication you dont need, but I expect you are using it elsewhere in your build pipeline where it might be more helpful).
I'm writing ES6 JavaScript modules and using Babel to transpile them to ES5. Babel generates sourcemaps that point back to the original ES6 code. I then use r.js to take those ES5 AMD modules and combine and uglify them. r.js creates a sourcemap that shows the ES5 files. I want the ES6 ones from the first step. My grunt file looks like this:
module.exports = function(grunt) {
require('load-grunt-tasks')(grunt); // npm install --save-dev load-grunt-tasks
// Project configuration.
grunt.initConfig({
babel: {
options: {
modules: "amd",
sourceMap: true
},
dist: {
files: {
"es5/editor.js": "src/editor.js",
"es5/editor-events.js": "src/editor-events.js"
}
}
},
requirejs: {
production: {
options: {
baseUrl: "es5",
mainConfigFile: "es5/require.config.js",
name: "../node_modules/almond/almond",
include: ["editor"],
out: "dist/ed.js",
optimize: "uglify2",
generateSourceMaps: true,
preserveLicenseComments: false
}
}
}
});
// Default task(s).
grunt.registerTask('default', ['babel', 'requirejs']);
};
It compiles everything perfectly. But it loses the nice ES6 sourcemaps. Any way to keep them? Is there a better build process that'll get me to a single, browser-friendly JavaScript file?
you shouldn't use two different steps for building your app. one for transpiling and an other one for bundling. you should have one step instead.
you could use browserify to bundle them and babelify as transpiler. the command would look like this:
browserify app.js -t babelify -d -o bundle.js
Note: -d (debug) will enable the sourcemaps. they will point to the es6 files.
In my project I would like to use jquery-mobile via bower.
Before I can use it I have to run npm install and grunt subsequently inside of bower_components/jquery-mobile before I can use the minified .js and .css files.
This is quite tedious and if I had to do this for every library that I use, I guess I would fallback to just downlading the files and add them to my project.
So is there a more elegant way to get to those "final" files via bower dependency?
My bower.json
"dependencies": {
...
"jquery-mobile": "latest",
}
The fact of having to run npm/grunt process (or not) is up to each author. In the case of jQuery Mobile, probably some external user has registered it without noticing that it needs to run Grunt tasks; Bower unfortunately allows everyone to register packages (is that bad or good? :S).
Also, there may exist some Grunt task to install bower dependencies and run their Grunt tasks aswell; if there aren't, it's not too complicated to create one.
Anyway, as it seems that you're in a "hurry" for those final, compiled files, there is jquery-mobile-bower, which has been created and registered into Bower a few hours ago.
bower install jquery-mobile-bower
Let's just hope that this gets maintained and up-to-date.
Just so you're aware, there is an official jQuery mobile Bower package available. It can be installed via:
bower install jquery-mobile
Its GitHub endpoint can be found here.
I'm not sure if my solution is optimal, but I removed jquery-mobile from bower.json and I'm installing and building it with Grunt, using grunt-contrib-clean, grunt-git and grunt-run plugins. I came up with this, because I don't want to use jquery-mobile-bower, because it's an unofficial repo.
Here's an example Gruntfile.js:
module.exports = function (grunt) {
grunt.initConfig({
clean: {
jquerymobile: 'bower_components/jquery-mobile'
},
gitclone: {
jquerymobile: {
options: {
repository: 'https://github.com/jquery/jquery-mobile.git',
branch: 'master',
directory: 'bower_components/jquery-mobile'
}
}
},
run: {
options: {
cwd: "bower_components/jquery-mobile"
},
jquerymobile_npm_install: {
cmd: "npm",
args: [
'install'
]
},
jquerymobile_grunt: {
cmd: "grunt"
}
}
});
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-git');
grunt.loadNpmTasks('grunt-run');
grunt.registerTask('default', [
'clean',
'gitclone',
'run'
]);
};
More details can be found here https://github.com/jquery/jquery-mobile/issues/7554
Is there an easy way to reference all js files in an HTML file rather than referencing it one by one?
Instead of this -
<script type="text/javascript" src="js/controllers/mainCtrl.js"></script>
<script type="text/javascript" src="js/controllers/browseCtrl.js"></script>
...
I'm looking for something like this -
<script type="text/javascript" src="js/controllers/*.js"></script>
Or is there a tool out there that copies the contents of these files into one file and reference that one file instead? This will be minimize the HTTP calls.
Is there an easy way to reference all js files in an HTML file rather than referencing it one by one?
For some value of "easy". There is nothing built in to browsers that will do it though.
Or is there a tool out there that copies the contents of these files into one file and reference that one file instead?
There are many. cat is the simplest one.
Call it from your usual build tool.
You can use something like require.js to combine them at runtime during development, and call r.js via Node from your build tool for packaging for your staging and live environments.
You can give Require.js a go. Require.js is the only JavaScript-file that is loaded through the script-tag. When you go out of development you can use Require.js's r.js to minify and concat everything into one file.
I use this tool all the time to minify my JS files:
Online Javascript Compression Tool
You can upload multiple files and it will concatenate them into one for you. It also produces smaller filesizes than YUI compressor, and Google's JS compiler most of the time too.
I am not sure why this hasn't been mentioned yet, but I do suppose this thread is a bit dated. Since I stumbled on this during my search to solve this very problem, I thought I would put a quick write-up about GruntJS here for other newbie JS guys to find.
Essentially, a properly configured Gruntfile.js will be able to perform a variety of tasks around JS including, but not limited to: concatenating files, minifying files, code linting, and much much more.
You can install grunt on Ubuntu with:
$ sudo apt-get install nodejs
$ sudo npm -g install grunt-cli
$ cd /path/to/my/project
--- Assumming you have a package.json file already in place ---
$ npm install grunt --save-dev
--- Install grunt plugins you wish to use ---
$ npm install grunt-contrib-concat --save-dev
$ npm install grunt-contrib-uglify --save-dev
$ npm install grunt-contrib-jshint --save-dev
$ npm install grunt-contrib-watch --save-dev
On the GruntJS site, there is a pretty good write-up for how to use GruntJS, but here is an example Gruntfile.js that will:
Lint all the JS files (app.js in the current directory and all .js files in the ngmodules directory).
Concatenate and save the files to dist/package-name.js.
Minify the concatenated file and save it to dist/package-name.min.js.
Gruntfile.js:
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
concat: {
options: {
separator: ';'
},
dist: {
src: ['app.js', 'ngmodules/**/*.js'],
dest: 'dist/<%= pkg.name %>.js'
}
},
uglify: {
options: {
banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n'
},
dist: {
files: {
'dist/<%= pkg.name %>.min.js': ['<%= concat.dist.dest %>']
}
}
},
jshint: {
files: ['Gruntfile.js', 'app.js', 'ngmodules/**/*.js'],
options: {
// options here to override JSHint defaults
globals: {
jQuery: true,
console: true,
module: true,
document: true
}
}
},
watch: {
files: ['<%= jshint.files %>'],
tasks: ['jshint']
}
});
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.registerTask('default', ['jshint', 'concat', 'uglify']);
};
There is also Gulp (http://gulpjs.com/), which can be used with various plugins. Here's an example that concatenates *.js files in one single file (main.js), then renames the resulting file and finally minifies it:
var gulp = require('gulp'),
rename = require('gulp-rename'),
uglify = require('gulp-uglify'),
concat = require('gulp-concat');
gulp.task('scripts', function(){
return gulp.src('./src/js/*.js')
.pipe(concat('main.js'))
.pipe(rename({suffix: '.min'}))
.pipe(uglify())
.pipe(gulp.dest('./src/js/*.js'));
You can try and combine your javascript files or plugins into one:
<script type="text/javascript" src="js/controllers/plugins.js"></script>
You'll have to do it manually though.
Another option would be to write a server-side script to combine and minify all your javascript files.
I have a node app that includes multiple unpublished modules. My app's package.json includes a few git dependencies:
"module-a": "git+ssh://git#github.com:me/module-a.git",
"module-b": "git+ssh://git#github.com:me/module-b.git"
and each of those have their own grunt config. Eg in node_modules/module-a/grunt.js:
module.exports = function(grunt) {
grunt.initConfig({
lint: {
files: ['server/**/*.js', 'test/**/*.js']
},
jshint: {
options: require('./lint-ci')
}
});
grunt.registerTask('default', 'lint');
};
(they also run tests, etc, but I'm keeping it simple here)
Is there a built-in way to do this with grunt? Note that I want to keep the dependent grunt.js files for convenience when I've only changed something within that dependency.
The only solutions I have found are
build up my main grunt.js programmatically (eg, iterating over my dependencies in package.json to build the lint and test config)
call grunt multiple times using --config node_modules/module-a/grunt.js
Neither seems ideal. Is there a better way?
Just a thought but have you looked at grunt-hub?
https://github.com/shama/grunt-hub