Javascript is by definition the language of browsers, and they are everywhere nowadays. Web pages and web apps, mobile apps, even desktop apps can actually be made using those technologies.
However, as its ecosystem is heterogeneous, the javascript code that runs in those browsers have to be highly compatible with old systems that does not implement new Javascript standards.
It could then be hardly conceivable to write in a language that is interpreted with its latest version and still reach a high level of compatibility. This article explains how it is possible to do so by setting up a build process that will enable you to use the last javascript specifications without hassle, and even to choose to activate manually specific language features.
This build process will also optimize your code, allowing it to be loaded and executed faster.
In this article, we will define a standard project architecture that correspond to most of the use cases, like the following :
root
├── src/ Source code
├── config/ Build configuration
├── dist/ Compiled project
└── package.json Manifest file, containing project metadata
This architecture is very simple, yet extensible. You can find a lot of projects, tutorials or articles that are assuming your project is set up this way.
The src
folder will contain all your source code. You will spend most of your time editing code located here.
What we want to acheive is to automatically compile all the source code into optimized files using the configuration located in the config
folder, and write the output to the dist folder.
With this architecture, all the javascript files located in the src folder can use modern javascript, and the build toolchain will transpile it to the ES5 specification, compatible with most of the existing browsers.
From now on, we will assume that you have node.js installed on your system.
We will also use NPM (Node Package Manager) to manage tools that we will install on the next steps. Everything else needed will be installed directly into the project folder, as relative dependencies.
Nowadays people tend to use an alternative to NPM called yarn, but as this article is not about package managers, we will stick to what's proposed by default in the node environment, NPM.
To initialize your project, you will need to create a manifest for it. it will store informations about the creator, dependencies of the project, where is the project repository located ... Initiate you project with the following command, in your project folder :
npm init
Answer to the asked questions (name of the project, your name...) and your manifest will be created into the package.json
file.
Initialize the three required folders with the following command :
$ mkdir src && mkdir config && mkdir dist
Webpack is a module bundler. let's assume that you have one main javacript file in your project, importing other files from your source code or libraries. Webpack will inspect the code in this main file, and look at those imports, listing all files requirements. Then, it will concatenate all the files into one, and optimize it.
This building process can be triggered manually, running a build command, or automatically, watching your source files for changes.
The power of webpack comes from its modular architecture, that allows to add extra steps into the build process. allowing to handle assets (css files, images, ...) and allowing to transform the files. We will use that file transformation ability to transform modern javascript files into ES5 files.
First, you need to install webpack for your project. Installing webpack can be done globally (once and for all your projects), but I prefer to install it at a project level, to make installation easier in other machines.
We use npm to install it as a dependency of the project, and specify that is is a dependency only if you want to edit the source code (with the --save-dev
option).
$ npm install webpack webpack-cli --save-dev
Webpack is now present in a node_modules
folder, that will contain all the dependencies of the project.
Later on, if you want to reinstall the project somewhere else, you will just need to run $ npm install --only=dev
to reinstall all dependencies (including development tools) in one command.
Now, let's create a config file :
$ touch config/webpack.config.js
https://gist.github.com/9d5912dbb688244f267ef0adde9b0dbf
Now we need to launch Webpack. This is usually done with the Webpack command if you install webpack globally on your system, but as it was installed as a local dependency, an extra set is required : filling the manifest with scripts.
The Webpack script is located to a project subfolder (node_modules/webpack/bin/webpack.js
). Thus, it will be impossible to launch the webpack
command directly, as your operating system won't be able to find it. But Npm is able to find it as it knows the presence of your local node_modules
folder.
The next step consist to fill the manifest with the commands you need to execute, as if they were in the global path, and give them a name. Those named commands have 2 main advantages here :
- As seen before, the path resolution will be done for modules that are installed locally in your project
- It is easy to inspect the manifest and see what commands are useful for this project. People that will need to dive into the code will know easily which commands are useful to them, in a matter of seconds.
Here is how it is possible to fill the manifest to be able to use webpack :
{
"name": "yourproject",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "webpack --config config/webpack.config.js",
"dev": "webpack --watch --progress --config config/webpack.config.js"
},
"author": "yourname",
"license": "ISC",
"devDependencies": {
"webpack": "^4.12.0",
"webpack-cli": "^3.0.3"
}
}
You can now build your project using the build
and the dev
commands.
The build
command will rebuild your project once, into the dist folder.
The dev
command will start a process that will automatically watch for changes in your src
files, and rebuild the project when necessary. Using the second command is more advised : as coding will require less manual steps, you will have less to care about when developing.
Those two commands will generate a bundle.js
file in the dist
folder. Now you need to create an index.html
file that will load this file.
$ touch index.html
https://gist.github.com/cf5435a4fb7bd1b43a16237040269c9a
At this point, everything is ready in your project. Webpack supports ES6 by default, so you have a pretty modern environment to code.
As said before, the src/index.js
file will be the root file of your project.
From this file, you will be able to import other files from your project or external libraries you have installed.
Let's take an example to illustrate how to develop with the environment, and assume you want to implement key bindings for your project.
We will use an external library, Mousetrap, to bind key combinations with actions, that will be javascript functions.
First, create a keyboardHandler.js
file located in src/
:
$ touch src/keyboardHandler.js
Now import this file from your index.js
file :
//index.js
import "./keyboardHandler";
Note the ./
before the name of the file, that implies that keyboardHandler is on the src/
folder
Then, you need to install Mousetrap as a dependency of your project :
$ npm install mousetrap --save
Mousetrap will be located in the node_modules
folder, but you can directly import it with the name of the package, mousetrap
.
Fill your keyboardHandler
file with an import of the library, and the configuration of keyboard bindings :
//keyboardHandler.js
import Mousetrap from 'mousetrap';
Mousetrap.bind('a', function() { alert("A key"); });
Mousetrap.bind('b', function() { alert("B key"); });
You can now open your project in your browser. Hitting the a
and b
key will result in opening popups as defined in the keyboardHandler
file.
This is it! You can follow using this logic for the whole project. Keep in mind that with this environment you should not have global objects that can be used directly without import. This allows Webpack to build an optimized code for your project.
It is fairly easy to use Webpack with Javascript frameworks. They usually provide templates and tools to make the deployement of a development environment easy.
For Vue, you can use the webpack template following these instructions. This template will also provide you Single-File-Component loading, hot-reload, lint-on-save, and unit testing
For React, this guide will cover nearly the same configuration as the one covered in this article.
With this setup you will be able to start any project you want, and cover most of your needs. Webpack is really extensible and you can use it to import and transform a lot of other types of files, such as images, css, templates, and so on.