Skip to content

Instantly share code, notes, and snippets.

@kynatro
Last active May 24, 2017 04:56
Show Gist options
  • Save kynatro/d37fc350b641bb5bb52b4031276d8935 to your computer and use it in GitHub Desktop.
Save kynatro/d37fc350b641bb5bb52b4031276d8935 to your computer and use it in GitHub Desktop.
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