laravel-elixir-bundler
v1.1.4
Published
Creates separate, customizable, and versioned js and css asset bundles using laravel-elixir
Downloads
51
Readme
laravel-elixir-bundler
Creates separate, customizable, and versioned js and css asset bundles using laravel-elixir
Configuration
This is built on top of laravel-elixir as a way to control your build(s) just from elixir.json, and to also give the ability to gulp separate builds.
You can continue to use the elixir.json file you already have for laravel-elixir. Configuration for the bundler can be added on top of it.
elixir.json
Add an object, "elixirBundles", to elixir.json
where you will specify your builds.
{
"elixirBundles": {
"app": {
"sass": [
"main.scss"
],
"js": [
"main.js"
]
},
"otherApp": {
"less": [
"main.less"
],
"babel": [
"main.babel"
]
}
}
}
And you're done! The bundler will do the rest.
gulpfile.js
Then, in your gulpfile, you only need to import the package, and call it
var bundler = require('laravel-elixir-bundler');
bundler();
Build Output
Each object in "elixirBundles" will be made into a separate and versioned build by elixir. In the above example, two builds will be created in public/build
with the associated rev-manifest.json
. So, the contents of public/build
will then be
build
├── css
| ├── app-123456789.css
| ├── app.css
| ├── otherApp-123456789.css
| └── otherApp.css
├── js
| ├── app.js
| ├── app-123456789.js
| ├── otherApp.js
| └── otherApp-123456789.js
└── rev-manifest.json
Where you can then call the elixir()
method in blade like normal.
Build Output Configuration
You can control the output of the builds by modifying the laravel-elixir settings from elixir.json. See laravel-elixir for available settings.
Build Sources
Like laravel-elixir, the bundler will look in your resources/assets
directories for each type of recipe specified in your bundles (js, css, sass, etc).
For recipes that produce css or js (sass, less and babel, browserify respectively) the outputs will not be put into the build. Rather, they will be output into their associated resources/assets
directories. In other words, sass and less files will be put into resources/assets/css
and babel and browserify files will be put into resources/assets/js
. The files are saved as the bundle name and sub-extensioned with the recipe type.
So, for a bundle called 'app', sass files will be built and saved in resources/assets/css/app.sass.css
. The bundler will then automatically append app.sass.css
to your source files for css for that bundle. This way, you can keep individual builds of each recipe type in your resources without having to worry about adding the built files yourself.
As mentioned above, the build files for sass, less, babel, and browserify will be appended onto the css, and js builds. If for some reason you need tighter control of the build order, you can explicitly specify where the build file should be placed in elixir.json
. In the below example, the bundler will build the final css build in the specified order.
"app": {
"sass": [
"main.scss"
],
"css": [
"mustGoBeforeApp.css",
"app.sass.css",
"mustGoAfterApp.css"
]
}
Vendor Packages
Since source files are relative to resources/assets
, its annoying to have to prefix each vendor package with a path that backs out, and back into the appropriate directory. By default, the bundler assumes your bower and node packages are stored in the root of your project (this can be changed in configuration). This is syntactic sugar only, but it makes your builds more readable. So instead of
"js": [
"../../../bower_components/jquery/dist/jquery.min.js",
"../../../node_modules/angular/angular.js"
]
You can use
"js": [
"{{bower}}/jquery/dist/jquery.min.js",
"{{node}}/angular/angular.js"
]
Both ways will work.
Adding files to every bundle
The bundler is also equipped to merge in specific files into every build so that it doesn't have to be repeated for each bundle configuration.
The 'every' key in the "elixirBundles" object is a special object used just for this purpose. Put any files into this bundle that you want in every other bundle. This is especially handy for vendor files.
"every": {
"js": [
"{{bower}}/jquery/dist/jquery.min.js",
"{{node}}/angular/angular.js"
]
},
"app1": {
"sass": [
"app1-main.scss"
],
"js": [
"app1-main.js"
]
},
"app2": {
"sass": [
"app2-main.scss"
],
"js": [
"app2-main.js"
]
}
So now each build will get the jQuery and angular packages included in their builds.
White/black
The 'every' object has two other special keys for white-listing and black-listing bundles. You can just put the name(s) of the bundle(s) in each of the objects like so
"every": {
"js": [
"{{bower}}/jquery/dist/jquery.min.js",
"{{node}}/angular/angular.js"
],
"white": [
"app1",
"app2"
]
},
"app1": {
"sass": [
"app1-main.scss"
],
"js": [
"app1-main.js"
]
},
"app2": {
"sass": [
"app2-main.scss"
],
"js": [
"app2-main.js"
]
},
"app3": {
"sass": [
"app3-main.scss"
],
"js": [
"app3-main.js"
]
}
In this example, only the app1
and app2
builds will get the vendor files. On the flipside, doing the following will have the same result
"every": {
"js": [
"{{bower}}/jquery/dist/jquery.min.js",
"{{node}}/angular/angular.js"
],
"black": [
"app3"
]
},
"app1": {
"sass": [
"app1-main.scss"
],
"js": [
"app1-main.js"
]
},
"app2": {
"sass": [
"app2-main.scss"
],
"js": [
"app2-main.js"
]
},
"app3": {
"sass": [
"app3-main.scss"
],
"js": [
"app3-main.js"
]
}
Asset Copying
Vendor packages will often need images, fonts, etc that have relative paths from the source files. In this case, the necessary assets will need to be put in the build. The 'every' object has another special key called 'assets' that will handle this. The 'assets' object is a map that uses the 'copy' mixin from laravel-elixir to map your assets into the build. The keys to this object are the source, and the value is the destination. All files are relative to the root of your project.
"every": {
"css": [
"{{bower}}/bootstrap/dist/css/bootstrap.min.css"
],
"assets": {
"bower_components/bootstrap/fonts": "public/build/fonts/bootstrap"
}
},
"app": {
"sass": [
"main.scss"
],
"js": [
"main.js"
]
}
This will copy all fonts in the bootstrap distro into the relative directory that bootstrap is expecting.
Per bundle configuration
Configuration can also be passed in on a per-bundle level if you have a more complicated build process. You can add custom configuration for laravel-elixir by creating an "elixirConfig" object on the bundle. The configuration for the bundler itself can be added to a "config" object. For each bundle, the bundler will merge the provided configuration onto the defaults.
"app1": {
"elixirConfig": {
"laravel-elixir configuration for the app1 bundle only"
},
"config": {
"laravel-elixir-bundler configuration for the app1 bundle only"
},
"sass": [
"app1-main.scss"
],
"js": [
"app1-main.js"
]
},
Global laravel-elixir settings
For configuring laravel-elixir, the bundler will use the configuration in elixir.json
as its base. So any configuration passed in an individual bundle will be merged into those defaults.
Global laravel-elixir-bundler settings
For configuring the bundler, you can put global settings in the 'every' object. See above for setting up the 'every' object.
Callbacks and runtime configuration
The bundler allows you tap into any part of the build process to add any other logic you may need.
Simply pass a function into the bundler. This function will be called before the recipes are mixed but after the configuration has been merged with the defaults. Here you can override any configuration and place in any callback logic. You will be given the bundler and the laravel-elixir object.
There is a before and after callback for each individual bundle, each of the recipes, the asset copying process, and the versioning process. You can check config.js
in the source to see all available callbacks. Each callback will provide the mixin and the bundle being built.
In elixir.json
"app": {
"sass": [
"main.scss"
],
"js": [
"main.js"
]
}
In gulpfile.js
var bundler = require('laravel-elixir-bundler');
bundler(function (Bundler, elix) {
Bundler.bundles.app.config.sass.before = function (mix, bundle) {
// Do something before sass runs on the 'app' bundle.
};
});