12-Minify

Minifying or Uglifying as it's also sometimes called, is the process of turning normal Javascript or CSS, into a compressed version, with much shorter variable and function names (for JS), and unnecessary whitespace removed to save on bytes shipped to the browser. Fewer bytes means less time transferring files and less time for the browser to parse the file.

1
yarn add --dev rollup-plugin-uglify@^3.0.0 broccoli-clean-css@^2.0.1

This will install the Rollup Uglify plugin. It is also possible to use the broccoli-uglify-sourcemap Broccoli plugin, and Rollup seems to work just fine with that plugin, however it makes more sense to use the supported Rollup plugin rather than the Broccoli one. We're also installing the broccoli-clean-css plugin that will compress our CSS.

Now update your Brocfile.js to:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
// Brocfile.js
const funnel = require('broccoli-funnel');
const merge = require('broccoli-merge-trees');
const compileSass = require('broccoli-sass-source-maps')(require('sass'));
const esLint = require("broccoli-lint-eslint");
const sassLint = require("broccoli-sass-lint");
const Rollup = require("broccoli-rollup");
const LiveReload = require('broccoli-livereload');
const CleanCss = require('broccoli-clean-css');
const log = require('broccoli-stew').log;
const babel = require("rollup-plugin-babel");
const nodeResolve = require('rollup-plugin-node-resolve');
const commonjs = require('rollup-plugin-commonjs');
const uglify = require('rollup-plugin-uglify').uglify;
const env = require('broccoli-env').getEnv() || 'development';
const isProduction = env === 'production';

// Status
console.log('Environment: ' + env);

const appRoot = "app";

// Copy HTML file from app root to destination
const html = funnel(appRoot, {
files: ["index.html"],
annotation: "Index file",
});

// Lint js files
let js = esLint(appRoot, {
persist: true
});

// Compile JS through rollup
const rollupPlugins = [
nodeResolve({
jsnext: true,
browser: true,
}),
commonjs({
include: 'node_modules/**',
}),
babel({
exclude: 'node_modules/**',
}),
];

// Uglify the output for production
if (isProduction) {
rollupPlugins.push(uglify());
}

js = new Rollup(js, {
inputFiles: ['**/*.js'],
rollup: {
input: 'app.js',
output: {
file: 'assets/app.js',
format: 'es',
sourcemap: !isProduction,
},
plugins: rollupPlugins,
}
});

// Lint css files
let css = sassLint(appRoot + '/styles', {
disableTestGenerator: true,
});

// Copy CSS file into assets
css = compileSass(
[appRoot],
'styles/app.scss',
'assets/app.css',
{
sourceMap: !isProduction,
sourceMapContents: true,
annotation: "Sass files"
}
);

// Compress our CSS
if (isProduction) {
css = new CleanCss(css);
}

// Copy public files into destination
const public = funnel('public', {
annotation: "Public files",
});

// Remove the existing module.exports and replace with:
let tree = merge([html, js, css, public], {annotation: "Final output"});

// Include live reaload server
if (!isProduction) {
// Log the output tree
tree = log(tree, {
output: 'tree',
});

tree = new LiveReload(tree, {
target: 'index.html',
});
}

module.exports = tree;

So what we're doing here is 2 things.

  1. Moving the Rollup plugins into a variable, so we can append the uglify() plugin only for production
  2. Changing the css variable to let so we can overwrite it for production, passing it into CleanCss()

That's it, now try building your prod application: yarn build-prod

Completed Branch: 12-minify

Next: 13-fingerprints