The boilerplate provides a custom, easily configured, and very simple, task runner for Node to process assets and test quickly in browsers.
Learn more about the boilerplate's tasks below.
Make sure you have the following installed:
- Node — at least 14.17, the latest LTS is recommended.
- NPM — at least 8.0, the latest LTS is recommended.
💡 You can use NVM to install and use different versions of Node via the command-line.
# Switch to recommended Node version from .nvmrc
nvm use
# Install dependencies from package.json
npm install
# Start development server, watch for changes, and compile assets
npm start
# Compile and minify assets
npm run build
See build.js
and watch.js
for details.
For development, most configuration values for processing front-end assets
are defined in the loconfig.json
file that exists at
the root directory of your project.
If any configuration options vary depending on whether your project is
running on your computer, a collaborator's computer, or on a web server,
these values should be stored in a loconfig.local.json
file.
In fresh copy of the boilerplate, the root directory of your project
will contain a loconfig.example.json
file.
💡 The boilerplate's default example customizes the development server to use a custom SSL certificate.
That file can be copied to loconfig.local.json
and customized to suit
your local environment.
Your loconfig.local.json
should not be committed to your project's
source control.
💡 If you are developing with a team, you may wish to continue including a
loconfig.example.json
file with your project.
The boilerplate provides a few configuration settings to control the behaviour for processing front-end assets.
The paths
option defines URIs and file paths.
It is primarily used for template tags to reference any configuration properties to reduce repetition.
Template tags are specified using {% %}
delimiters. They will be
automatically expanded when tasks process paths.
{
"paths": {
"styles": {
"src": "./assets/styles",
"dest": "./www/assets/styles"
}
},
"tasks": {
"styles": [
{
"infile": "{% paths.styles.src %}/main.scss", // → ./assets/styles/main.scss
"outfile": "{% paths.styles.dest %}/main.css" // → ./www/assets/styles/main.css
}
]
}
}
The paths.url
option defines the base URI of the project.
By default, it is used by the development server as a proxy for an existing virtual host.
{
"paths": {
"url": "locomotive-boilerplate.test"
}
}
The paths.dest
option defines the public web directory of the project.
By default, it is used by the development server as the base directory to serve the website from if a proxy URI is not provided.
{
"paths": {
"dest": "./www"
}
}
Which assets and how they should be processed can be configured via
the tasks
option:
{
"tasks": {
"scripts": [
{
"includes": [
"./assets/scripts/app.js"
],
"outfile": "./www/assets/scripts/app.js"
}
],
"styles": [
{
"infile": "./assets/styles/main.scss",
"outfile": "./www/assets/styles/main.css"
}
]
}
}
See tasks section, below, for details.
The development server (BrowserSync) can be configured via
the server
option:
{
"server": {
"open": true,
"https": {
"key": "~/.config/valet/Certificates/{% paths.url %}.key",
"cert": "~/.config/valet/Certificates/{% paths.url %}.crt"
}
}
}
Visit BrowserSync's documentation for all options.
The boilerplate provides a handful of tasks for handling the most commonly processed assets.
A wrapper around concat (with optional support for globbing) for concatenating multiple files.
By default, tiny-glob is installed with the boilerplate.
Example:
{
"concats": [
{
"label": "Application Vendors",
"includes": [
"{% paths.scripts.src %}/vendors/*.js",
"node_modules/focus-visible/dist/focus-visible.min.js",
"node_modules/vue/dist/vue.min.js",
"node_modules/vuelidate/dist/vuelidate.min.js",
"node_modules/vuelidate/dist/validators.min.js"
],
"outfile": "{% paths.scripts.dest %}/app/vendors.js"
},
{
"label": "Public Site Vendors",
"includes": [
"{% paths.scripts.src %}/vendors/*.js",
"node_modules/focus-visible/dist/focus-visible.min.js"
],
"outfile": "{% paths.scripts.dest %}/site/vendors.js"
}
]
}
See concats.js
for details.
A wrapper around esbuild for bundling and minifying modern JS/ES modules.
Example:
{
"scripts": [
{
"label": "Application Dashboard JS",
"includes": [
"{% paths.scripts.src %}/app/dashboard.js"
],
"outfile": "{% paths.scripts.dest %}/app/dashboard.js"
},
{
"label": "Public Site JS",
"includes": [
"{% paths.scripts.src %}/site/main.js"
],
"outfile": "{% paths.scripts.dest %}/site/main.js"
}
]
}
See scripts.js
for details.
A wrapper around sass (with optional support for Autoprefixer via PostCSS) for compiling and minifying Sass into CSS.
By default, PostCSS and Autoprefixer are installed with the boilerplate.
Example:
{
"styles": [
{
"label": "Text Editor CSS",
"infile": "{% paths.styles.src %}/app/editor.scss",
"outfile": "{% paths.styles.dest %}/app/editor.css"
},
{
"label": "Application Dashboard CSS",
"infile": "{% paths.styles.src %}/app/dashboard.scss",
"outfile": "{% paths.styles.dest %}/app/dashboard.css"
},
{
"label": "Public Site Critical CSS",
"infile": "{% paths.styles.src %}/site/critical.scss",
"outfile": "{% paths.styles.dest %}/site/critical.css"
},
{
"label": "Public Site CSS",
"infile": "{% paths.styles.src %}/site/main.scss",
"outfile": "{% paths.styles.dest %}/site/main.css"
}
]
}
See styles.js
for details.
The task also supports PurgeCSS to remove unused CSS. See the documentation on our Grid System for details.
A wrapper around SVG Mixer for transforming and minifying SVG files and generating spritesheets.
Example:
{
"svgs": [
{
"label": "Application Spritesheet",
"includes": [
"{% paths.images.src %}/app/*.svg"
],
"outfile": "{% paths.svgs.dest %}/app/sprite.svg"
},
{
"label": "Public Site Spritesheet",
"includes": [
"{% paths.images.src %}/site/*.svg"
],
"outfile": "{% paths.svgs.dest %}/site/sprite.svg"
}
]
}
See svgs.js
for details.
A task to create and update values for use in versioning assets.
Can generate a hexadecimal value (using random bytes), use the current timestamp, or increment a number.
Example:
{
"versions": [
{
"format": "timestamp",
"key": "now",
"outfile": "./assets.json"
},
{
"format": "hex:8",
"key": "hex",
"outfile": "./assets.json"
},
{
"format": "inc:semver",
"key": "inc",
"outfile": "./assets.json"
}
]
}
{
"now": 1665071717350,
"hex": "6ef54181c4ba",
"hex": "1.0.2"
}
The task supports replacing the value of a data key in a JSON file or replacing a string in a file using a regular expression.
- Explicit JSON field name:
{ "key": "json:version" }
- Implicit JSON field name:
{ "key": "version" }
The regular expression can be a RegExp
object or a pattern prefixed with regexp:
.
-
{ "key": "regexp:(?<=^const ASSETS_VERSION = ')(?<build>\\d+)(?=';$)" }
-
{ key: new RegExp('(?<=^const ASSETS_VERSION = ')(?<version>\\d+)(?=';$)') }
-
{ key: /^ \* Version: +(?:.+?)\+(.+?)$/ }
The regular expression pattern will match the first occurrence and replace
the first match in the following order: build
(named capture), version
(named capture), 1
(first capture), or 0
(whole match).
See versions.js
for details.