laravel-elixir-bundler
Version:
Creates separate, customizable, and versioned js and css asset bundles using laravel-elixir
181 lines (148 loc) • 4.92 kB
JavaScript
var _ = require('lodash');
var elix = require('laravel-elixir');
var merger = require('./merger');
var helpers = require('./helpers');
var config = require('./config');
var elixConfig = elix.config;
/**
* Creates separate customizable versioned
* asset bundles using laravel-elixir
*/
var Bundler = function (setup) {
// Check for bundles
if (_.size(Bundler.bundles) === 0) {
throw new Error('Missing bundles. Add your bundles to elixir.json at "elixirBundles".');
}
// Merge defaults into bundles
mergeDefaults.call(Bundler);
// Do any user setup
if (setup) {
setup(Bundler, elix);
}
// Mix!
_.forIn(Bundler.bundles, function (bundle, name) {
mixBundle.call(bundle, name);
});
// Copy the assets
copyAssets.call(Bundler.every);
// Version the bundles
versionBundles.call(Bundler.every, _.keys(Bundler.bundles));
};
Bundler.bundles = elix.config.elixirBundles || {};
Bundler.every = {};
/**
* Merge defaults from elixir.json into the bundles.
*/
var mergeDefaults = function () {
// Remove the 'every' bundle so that we don't loop over it
// Used to merge in 'every' assets into each bundle
this.every = this.bundles.every || {};
_.unset(this.bundles, 'every');
merger.init(this.every, elixConfig, config);
// Merge base
var base = this.every;
_.forIn(this.bundles, function (bundle, name) {
// Check the black/white lists for merging
// the 'every' config in if they're set
if (base.white.length || base.black.length) {
if ((base.white.length && _.includes(base.white, name)) ||
(base.black.length && !_.includes(base.black, name))) {
merger.merge(bundle, base);
}
// Merge in 'every' by default if
// black/white settings not given
} else {
merger.merge(bundle, base);
}
});
};
/**
* Mix the bundle
*
* @param {String} name The name of this bundle
*/
var mixBundle = function (name) {
var bundle = this;
// Copy the current configuation over to the elixir object
elix.config = this.elixConfig;
elix(function(mix) {
bundle.config.before(mix, bundle, name, elix);
// Mix the recipes. Order is set in config.recipes
bundle.config.recipes.forEach(function(recipeType) {
recipe.call(bundle, recipeType, mix, name, elix);
});
bundle.config.after(mix, bundle, name, elix);
});
};
/**
* Copy assets into build. Uses "this"'s configuration.
*/
var copyAssets = function () {
var bundle = this;
if (!_.size(bundle.assets)) {
return;
}
// Copy the current configuation over to the elixir object
elix.config = bundle.elixConfig;
// Copy assets to the build
elix(function(mix) {
bundle.config.assets.before(mix, bundle, '', elix);
_.forIn(bundle.assets, function (asset, path) {
mix.copy(path, asset);
});
bundle.config.assets.after(mix, bundle, '', elix);
});
};
/**
* Version the bundles together. Uses "this"'s configuration.
*
* @param {Array} names The bundles to version
*/
var versionBundles = function (names) {
var bundle = this;
// Copy the current configuation over to the elixir object
elix.config = bundle.elixConfig;
// Make js and css paths for each version
var versions = [];
names.forEach(function (name) {
versions.push(bundle.config.version.css.put(elix, name));
versions.push(bundle.config.version.js.put(elix, name));
});
// Version!
elix(function(mix) {
bundle.config.version.before(mix, bundle, names, elix);
mix.version(versions);
bundle.config.version.after(mix, bundle, names, elix);
});
};
/**
* Run a mixin recipe on the bundle
*
* @param {String} recipeType The type of recipe to run. sass, css, js etc
* @param {Object} mix The elixir mixins
* @param {String} name The name of this bundle
* @param {Elixir} elix The laravel-elixir object
*/
var recipe = function (recipeType, mix, name, elix) {
if (!_.size(this[recipeType])) {
return;
}
// Replace vendor prefixes
var bundle = this;
var paths = this[recipeType].map(function (path) {
return bundle.config.pathReplace(path);
});
this.config[recipeType].before(mix, this, name, elix);
// Append to list of paths if sub-extensioned
var out = this.config[recipeType].put(elix, name);
if (helpers.hasSubExt(out, recipeType)) {
var appendTo = this.config.recipeMap[recipeType];
if (_.indexOf(this[appendTo], out) === -1) {
this[appendTo].push(out);
}
}
// Mix!
mix[this.config[recipeType].mixName](paths, out);
this.config[recipeType].after(mix, this, name, elix);
};
module.exports = Bundler;