# Frontend Setup

The front-end setup is used in all past, current and future projects - static projects and WordPress projects.

For projects based on React or Vue, consult another page in this guide.

The front-end setup (setup) is built using Webpack as module bundler, Babel and SCSS as parsers.

# Short introduction

# Webpack

Webpack is a bundler for JavaScript projects by default. This means that it combines several JavaScript files into one bundle which is then optimized and/or minified based on specified options.

Webpack can be extended to support files different than JavaScript files. This is being done via additional plugins which are called loaders. Such loaders allow Webpack to process any kind of files include CSS, SCSS, TypeScript, images, fonts, etc.

# Babel

Babel is a tool which transpiles (translates) modern JavaScript to JavaScript which current browsers support and execute.

Since most current browsers support almost 90% of the latest ECMAScript spec, it is important to use Babel to provide 100% support to these browsers.

Babel is being extended via plugins and presets which allow support for different ECMAScript proposals and/or specifications.

# SCSS

SCSS is a CSS pre-processor which allows default CSS to be extended via usage of variables, functions, mixins and other non-standard features.

SCSS requires a build step in order to be compiled or translated to CSS that browsers understand and can execute.

# Browserslist

Browserslist is a tool which specifies browser support based on settings and usage data from CanIUse database.

The settings for supported browsers are located in each project's package.json file under browserslist property.

By default the setup support the latest 2 versions of all browsers which are used by more than 1% of the population.

# Used Webpack loaders:

# Babel loader

The Babel loader allow Webpack to use Babel and enables us to use the latest JavaScript features without worrying about browser support.

Babel reads and uses the browserslist setting in package.json file and translates modern JavaScript based on these settings.

The setup uses Babel's Env preset and several Babel plugins which allow usage of features such as decorators, dynamic import, class properties and so on.

It is important to note that if you need to use a feature which is not supported by the current Babel config, you must install its corresponding plugin. For example, if you want to use async/await, you must install the @babel/plugin-transform-runtime plugin.

# Extract Text plugin

ExtractTextPlugin is a Webpack plugin which .... well .... extracts text.

This plugin is used by our setup's Webpack to write the CSS file in an external file.

In order to produce the external CSS file, Webpack uses three loaders:

# SASS loader

SASS loader is the Webpack loader which enables usage of SCSS.

Each SCSS file located in any of the predefined assets/styles folders is auto imported in the _main.scss file. This means that you don't have to worry about adding or removing scss files. This is being done by a PostCSS plugin which will be explained later.

The _main.scss file is being processed by the SASS loader and Node SASS and then is being translated to vanilla CSS.

# PostCSS loader

Then the vanilla CSS is being picked up by PostCSS.

PostCSS is a CSS post-processor which enhances/updates/fixes/manipulates the input CSS in order to produce better CSS.

PostCSS is being configured via plugins. The setup uses several plugins:

  • postcss-easy-import - allows importing of non-scss files.
  • postcss-url - takes care of external files referenced in the stylesheets (images, fonts, etc) and makes sure that these files are correctly copied in the dist folder.
  • postcss-normalize - the PostCSS version of normalize.css which inserts normalization CSS for all browsers based on the browserslist setting.
  • postcss-utilities - a PostCSS plugin which allows usage of predefined mixins.
  • postcss-flexbugs-fixes - fixes common issues with FlexBox on Internet Explorer.
  • autoprefixer - takes care of vendor prefixes so you don't have to.
  • postcss-watch-folder - a plugin which takes care of syncing your styles folder when you delete or add new files. This plugin is used only in development mode.

# CSS loader

CSS loader is the loader which picks up and CSS which is not written in scss file (usually comes from third party libraries located in node_modules).

CSS loader combines the CSS produced by PostCSS and all external CSS files and sends them to ExtractTextPlugin which then bundles them in the main stylesheet in dist folder.

# File loader

File loader takes care of all non-js and non-css/scss files referenced in .js and .scss/.css files.

The setup uses this loader to handle images, fonts and media files.

This loader makes sure that all files are correctly copied in the dist folder.

It is important to note that when copying to dist, the loader adds hashes to the file name.

# BrowserSync

The setup uses BrowserSync when in development mode.

This allows all file modifications to be reflected in the browser without manual refresh.

By default BrowserSync serves the files via localhost and uses port 3000.

All .php, .html files and /dist/app.css and /dist/app.js are being watched for changes.

# SVG Sprite

The setup is enabled to generate SVG sprite out of all .svg files located in /assets/images/svg folder.

In order to use this ability one must follow the rules:

  • put all SVG icons in the /assets/images/svg folder.
  • give them meaningful names (for example arrow.svg, home.svg)
  • run the start npm script
  • insert the following PHP snippet before the closing </body> tag: <?php include_once('assets/dist/sprite.svg'); ?>
  • use the following markup when you want to show a SVG icon:
    <svg class="svg-home">
        <use xlink:href="#svg-home" />
    </svg>
    

# PNG Sprite

The setup uses Webpack SpriteSmith to produce a PNG sprite.

In order to use the PNG sprite, you must follow the rules:

  • put all PNG icons in /assets/images/sprite folder.
  • slice the PNG files in normal and retina resolution (@2x).
  • give the files meaningful names including the ico- prefix (for example ico-arrow.png, ico-home.png). The retina version of the file should have the @2x suffix (for example ico-arrow@2x.png, ico-home@2x.png)
  • use the following markup when you want to show a PNG icon: <i class="ico-arrow"></i>.

# Webpack modes:

# Development mode

During development, BrowserSync is enabled and PostCSS watches for new files in the styles directory.

Also, in this mode, Webpack generates source maps which help during development - the developer can see which file is the source of error right from the browser devtools.

# Production mode

In this mode Webpack optimizes and minifies CSS and JS files.

Also, in this mode, PostCSS attempts to merge similar rules into single rule which reduces the final size of the bundled CSS file.

# NPM Scripts

There are several scripts available for the developer to use. These scripts are located in the package.json file's scripts section:

  • "build": Runs Webpack in production mode.
  • "start": Runs Webpack in development mode.
  • "optisize": Optimizes all images
  • "html": Converts the index.php file to index.html file
  • "critical": Generates critical css out of the index.html file
  • "rm-html": Deletes the index.html file
  • "pwa": Creates boilerplate files for a Progressive Web App,
  • "prod": Builds the application for production environment