Dan Brown

Implemented custom asset versioning to make creating releases easier

1 +<?php
2 +
3 +if (! function_exists('versioned_asset')) {
4 + /**
5 + * Get the path to a versioned file.
6 + *
7 + * @param string $file
8 + * @return string
9 + *
10 + * @throws \InvalidArgumentException
11 + */
12 + function versioned_asset($file)
13 + {
14 + static $manifest = null;
15 +
16 + if (is_null($manifest)) {
17 + $manifest = json_decode(file_get_contents(public_path('build/manifest.json')), true);
18 + }
19 +
20 + if (isset($manifest[$file])) {
21 + return '/' . $manifest[$file];
22 + }
23 +
24 + if (file_exists(public_path($file))) {
25 + return '/' . $file;
26 + }
27 +
28 + throw new InvalidArgumentException("File {$file} not defined in asset manifest.");
29 + }
30 +}
...\ No newline at end of file ...\ No newline at end of file
...@@ -25,7 +25,10 @@ ...@@ -25,7 +25,10 @@
25 ], 25 ],
26 "psr-4": { 26 "psr-4": {
27 "BookStack\\": "app/" 27 "BookStack\\": "app/"
28 - } 28 + },
29 + "files": [
30 + "app/helpers.php"
31 + ]
29 }, 32 },
30 "autoload-dev": { 33 "autoload-dev": {
31 "classmap": [ 34 "classmap": [
......
1 var elixir = require('laravel-elixir'); 1 var elixir = require('laravel-elixir');
2 2
3 +// Custom extensions
4 +var gulp = require('gulp');
5 +var Task = elixir.Task;
6 +var fs = require('fs');
7 +
8 +elixir.extend('queryVersion', function(inputFiles) {
9 + new Task('queryVersion', function() {
10 + var manifestObject = {};
11 + var uidString = Date.now().toString(16).slice(4);
12 + for (var i = 0; i < inputFiles.length; i++) {
13 + var file = inputFiles[i];
14 + manifestObject[file] = file + '?version=' + uidString;
15 + }
16 + var fileContents = JSON.stringify(manifestObject, null, 1);
17 + fs.writeFileSync('public/build/manifest.json', fileContents);
18 + }).watch(['./public/css/*.css', './public/js/*.js']);
19 +});
20 +
3 elixir(function(mix) { 21 elixir(function(mix) {
4 mix.sass('styles.scss') 22 mix.sass('styles.scss')
5 .sass('print-styles.scss') 23 .sass('print-styles.scss')
6 .browserify(['jquery-extensions.js', 'global.js'], 'public/js/common.js') 24 .browserify(['jquery-extensions.js', 'global.js'], 'public/js/common.js')
7 - .version(['css/styles.css', 'css/print-styles.css', 'js/common.js']); 25 + .queryVersion(['css/styles.css', 'css/print-styles.css', 'js/common.js']);
8 }); 26 });
......
1 { 1 {
2 "private": true, 2 "private": true,
3 "devDependencies": { 3 "devDependencies": {
4 - "gulp": "^3.8.8", 4 + "gulp": "^3.9.0",
5 "insert-css": "^0.2.0" 5 "insert-css": "^0.2.0"
6 }, 6 },
7 "dependencies": { 7 "dependencies": {
......
...@@ -9,8 +9,8 @@ ...@@ -9,8 +9,8 @@
9 <meta charset="utf-8"> 9 <meta charset="utf-8">
10 10
11 <!-- Styles and Fonts --> 11 <!-- Styles and Fonts -->
12 - <link rel="stylesheet" href="{{ elixir('css/styles.css') }}"> 12 + <link rel="stylesheet" href="{{ versioned_asset('css/styles.css') }}">
13 - <link rel="stylesheet" media="print" href="{{ elixir('css/print-styles.css') }}"> 13 + <link rel="stylesheet" media="print" href="{{ versioned_asset('css/print-styles.css') }}">
14 <link href='//fonts.googleapis.com/css?family=Roboto:400,400italic,500,500italic,700,700italic,300italic,100,300' rel='stylesheet' type='text/css'> 14 <link href='//fonts.googleapis.com/css?family=Roboto:400,400italic,500,500italic,700,700italic,300italic,100,300' rel='stylesheet' type='text/css'>
15 <link rel="stylesheet" href="/libs/material-design-iconic-font/css/material-design-iconic-font.min.css"> 15 <link rel="stylesheet" href="/libs/material-design-iconic-font/css/material-design-iconic-font.min.css">
16 16
...@@ -79,6 +79,6 @@ ...@@ -79,6 +79,6 @@
79 </section> 79 </section>
80 80
81 @yield('bottom') 81 @yield('bottom')
82 -<script src="{{ elixir('js/common.js') }}"></script> 82 +<script src="{{ versioned_asset('js/common.js') }}"></script>
83 </body> 83 </body>
84 </html> 84 </html>
......