In series so far:
Intro to this series
I have been doing programming, both front-end and back-end for a good while (over a decade), but recently I realized I need to pay more attention to what I am doing, and what I should be doing on the front-end side of things. It’s not the same JavaScript I started writing in 2006 anymore, and things are moving super fast. I am taking some notes for myself and others like me. I hope you find this series useful!
Random awesome Polish thing #01: Pierogi (photo credit: Freeimages.com/Agnieszka Stach)
The war of asset builders
There’s been a war going on for years now in the front-end ecosystem. You would not know which asset builder to pick, and the currently trendy one was already obsolete in months.
There’s been a galore of tools with similar - but not precisely exact - set of features to choose from: Gulp, Brunch, Browserify, Grunt, Parcel… You could also use framework-invented tools, like Rails Assets Pipeline or there’s been people advocating on simply using GNU Make or NPM scripts directly… Oh, what a mess!
Luckily, I think* the war is over, and we have a winner: Webpack, version 4. It looks like we are going to stick with it for a while, and many frameworks like Ruby on rails and Phoenix now use Webpack by default.
Let’s get our hands dirty and set up our development front-end stack.
* this is my personal opinion! Surely lots of people disagree…
Create project
$ mkdir my_app
$ cd my_app
$ echo "node_modules/" > .gitignore
$ git init
$ git add .
$ git commit -m "Initial commit"
We are adding top-level node_modules
folder to .gitignore
here, so
that the libraries we use will not be added to git. Every time you clone
your repository to new machine, you will need to run npm install
to
populate your node_modules
directory.
Setting up Node.js
To avoid problems in the future, I strongly advise you, to lock your Node.js version. I use asdf-vm to manage multiple versions of my development tools like Elixir, Ruby, but it also has excellent asdf-nodejs plugin that takes care of having multiple Node.js versions installed on your system. Grab it and install according to instructions from links above.
To lock your project to use given Node.js version, you need to pick this
version (do pick most recent LTS version from:
https://nodejs.org/en/) and then create your .tool-versions
file:
$ echo "nodejs 10.13.0" > .tool-versions
And install it:
$ asdf install
That is going to give you consistent results when coming back to project after several months, when Node.js versions already change. Your build environment will force installation and usage of older Node.js until you manually upgrade.
After Node.js is installed, you can generate a JavaScript project’s
package.json
file with:
$ npm init -y
Edit your package.json
to change author, name, keywords, description,
but leave out dependencies
and devDependencies
fields since these
will be managed by npm
when we install our dependencies.
devDependencies
We want to install number of tools that will help us with development. I prepared handy one-liner for you:
$ npm install --save-dev webpack webpack-cli webpack-dev-server @babel/core babel-loader @babel/preset-env html-webpack-plugin html-loader css-loader node-sass sass-loader style-loader
At the moment of writing, this will result in package.json
’s
devDependencies
as follows:
"devDependencies": {
"@babel/core": "^7.1.6",
"@babel/preset-env": "^7.1.6",
"babel-loader": "^8.0.4",
"css-loader": "^1.0.1",
"html-loader": "^0.5.5",
"html-webpack-plugin": "^3.2.0",
"node-sass": "^4.10.0",
"sass-loader": "^7.1.0",
"style-loader": "^0.23.1",
"webpack": "^4.26.0",
"webpack-cli": "^3.1.2",
"webpack-dev-server": "^3.1.10"
},
If you are person from the distant future, reading this article long time from now (months!), you will need to update the versions according to the above file more than likely in order to reproduce working set up. But then, the set up will be out of date anyway ;). Welcome to JavaScript :D.
I am installing Webpack and it’s addons, Babel (JS6 to JS5 transpiler), and plugins you likely need and things we’ll need to compile SASS to CSS.
You can adjust the lines above to remove SASS if you do not intend to use it, or replace with LESS (or something else) if you prefer.
devDependencies vs. dependencies, —save-dev vs. —save
Webpack, transpilers, loaders, plugins & development web server are some
of the things you don’t want to be loaded to your compiled JavaScript
bundle. This would blow up the size of the bundle significantly.
NPM projects have two sections in their package.js
file to separate
these from the libraries you otherwise want to have included in the
bundle. You want to make sure you install your development tools
passing --save-dev
switch (like above), and --save
for libraries
you will need at run time.
Babel configuration
You can configure Babel (remember: ES6+/next/whatever transpiler to ES5)
in two ways: a) using separate .babelrc
b) via webpack.config.js
.
Using .babelrc
has this advantage that it will be picked up by scripts
that don’t even use Webpack in your project, so I’d opt in for going
with this.
Create your .babelrc
file in root directory of your project (next to
package.json
):
{
"presets": ["@babel/preset-env"]
}
For now, we are just instructing Babel to compile ES6 to ES5. We will add more presets, enhancing the ES6 syntax with more funky features later in this series.
Webpack configuration
Create webpack.config.js
file in root of your project:
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.scss$/,
use: [
"style-loader",
"css-loader",
"sass-loader"
]
}
]
},
plugins: [
new HtmlWebpackPlugin()
]
};
This is the simplest configuration you need to start your application
development with ES6 & SASS (.scss
files to be precise as this is what
we’ll use and what is configured to be compiled).
Start building your application
Once you have functioning Babel & Webpack in your project, you can start coding!
Since we are using HtmlWebpackPlugin
- we will not have to write any
HTML template, it will be generated for us. Later we can decide to use
own template, or configure the generated HTML with available
options.
The generated HTML will be pretty much empty, but will include our JavaScript bundle, and JavaScript bundle will include the stylesheets compiled to JavaScript*.
* You have read it right, but please feel free to re-read the above paragraph as many times as you need to. In near future we will drop this pattern, but since it’s default let’s give it a try for now!
Alright, we need to create two files, let’s start with our stylesheet.
Place your styles in src/index.scss
:
html {
body {
background-color: cyan;
}
}
That will give us some nice retro background color for our HTML.
Then, you need to create your JavaScript (ES6) in src/index.js
:
import "./index.scss"
(() => alert("Hello, ES6 world!"))()
What are we doing here is:
- we instruct Webpack to compile & load our stylesheets as JavaScript module. This stylesheet will be automatically applied to our document when JavaScript executes.
- we create alert window in an arrow function - to test if ES6 compilation works.
Development server
We have installed webpack-dev-server
already, and it should be in our
devDependencies
. Next thing we need is a means of starting it. We can
do it by editing our package.json
file to include a script that will
start it for us:
...
"scripts": {
"start": "webpack-dev-server --open --mode development",
},
...
The development server will not write any resulting files to disk. We will tweak our configuration to support building to files in production mode shortly, but now we just want to focus on simplest development flow.
We can start our simple application by issuing the command:
$ npm run start
The command above should start development server for us on port 8080, and open default system browser to point it there. You should see our “Hello, ES6 world!” alert, and once you accept it the background of HTML page will turn cyan. If the browser does not open, and you don’t see anything suspicious on the console, manually visit http://localhost:8080/ to see your beautiful application.
You can play with your stylesheet and JavaScript sources and
webpack-dev-server
will take care of updating these and reloading page
for us. Pretty sweet!
Sources for this blog post
You can find the project’s source files for this blog post on our GitHub under https://github.com/amberbit/polish-up-your-javascript/tree/master/polish-up-your-javascript-1
What’s next?
In blog post #02, we will install React and write our first component. In next posts we will discuss building assets for production, explore React & ES6 features that you may not be familiar with, start using MobX for our state. Stay tuned!
Post by Hubert Łępicki
Hubert is partner at AmberBit. Rails, Elixir and functional programming are his areas of expertise.