Instantly share code, notes, and snippets.

Embed
What would you like to do?
Grunt + Browserify + alias/external = common module bundles

By defining an alias as part of the main.js manifest definition for those modules and files, their contents will be included in the compiled www/js/main.js file. The main.js source file does not even need to reference the modules for this to work, the Browserify configuration handles the inclusion of the module contents. Couple the alias option with the external option and each of the other manifests will be compiled without the modules, instead Browserify merely references the modules already part of www/js/main.js.

At first blush this looks obnoxious to have to maintain all of your external definitions, but keep in mind that you can always define external entries for modules that aren't even used by the manifest and Browserify won't care. This means we can automate the heck out of this. Checkout Gruntfile.automated.js for an example of what this might look like.

// source/js/about.js
import Promise from 'es6-promise'
import { query, queryAll } from 'dom-helpers'
import Slider from 'slider'
// Do stuff with imported modules
const path = require('path')
module.exports = function(grunt) {
const config = {
browserify: {
options: {
transform: [
['babelify', { presets: ['es2015', 'es2016'] }]
]
},
main: {
src: ['source/js/main.js'],
dest: ['www/js/main.js'],
options: {
alias: [
'es6-promise:',
'./source/js/helpers/dom-helpers.js:dom-helpers',
'./source/js/lib/slider.js:slider'
]
}
}
}
}
grunt.file.expand(['source/js/*.js', '!source/js/main.js']).forEach((filepath) => {
const slug = path.basename(filepath, '.js')
const dest = `www/js/${slug}.js`
config.browserify[slug] = {
src: [filepath],
dest: dest,
options: {
external: config.browserify.main.options.alias.map((alias) => {
const [ module, name ] = alias.split(':')
// Return the alias 'name' if its set or the module name
return name || module
})
}
}
})
grunt.initConfig(config)
}
module.exports = function(grunt) {
const config = {
browserify: {
options: {
transform: [
['babelify', { presets: ['es2015', 'es2016'] }]
]
},
main: {
src: ['source/js/main.js'],
dest: ['www/js/main.js'],
options: {
alias: [
'es6-promise:', // The trailing : is required because of the way Browserify handles the naming with alias
'./source/js/helpers/dom-helpers.js:dom-helpers', // Alias as 'dom-helpers'
'./source/js/lib/slider.js:slider' // Alias as 'slider'
]
}
},
about: {
src: ['source/js/main.js'],
dest: ['www/js/main.js'],
options: {
// External definitions must be set at the manifest level and won't
// inherit from the 'common' Browserify options
external: [
'es6-promise',
'dom-helpers',
'slider'
]
}
},
home: {
src: ['source/js/home.js'],
dest: ['www/js/home.js'],
options: {
external: [
'slider'
]
}
}
}
}
grunt.initConfig(config)
}
// source/js/home.js
import Slider from 'slider'
// Do stuff with imported modules
<!DOCTYPE html>
<html lang="en">
<body>
<script src="js/main.js"></script>
<script src="js/home.js"></script>
</body>
</html>
// source/js/main.js
import { query, queryAll } from 'dom-helpers'
// Do stuff with imported modules
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment