Upgradeable collection of Webpack plugins, loaders and configuration for Deloitte Digital projects.
Rather than installing and configuring many different build tools, such as Webpack, React/Vue, Babel, Sass, and PostCSS, you can simply use this single package and get these tools up and running in a flash, in a way that is consistent with other Deloitte Digital FED projects.
Guiding principles:
- Build tools should be consistent across similar projects; this helps maintainability, on-boarding, and knowledge-sharing.
- Build tools should be maintained and continually improved in a central location.
- A workflow should be available to pull build tooling improvements into ongoing projects.
The following project types are supported:
- Web standards projects
- Vue.js projects
- React projects
- Install for a standard js project
- Install for a Vue.js project
- Install for a React project
- Getting Started
- Add the package as a dev dependency, by running:
npm install @deloitte-digital-au/webpack-config --save-dev
- Add a
webpack.config.js
file which importscreateConfig
from Webpack config:
const { createConfig } = require('@deloitte-digital-au/webpack-config');
module.exports = createConfig({
entry: {
main: [
'./src/index.js',
],
},
});
- Complete the Getting Started guide.
- Add the package as a dev dependency, by running:
npm install @deloitte-digital-au/webpack-config-vuejs --save-dev
- Add a
webpack.config.js
file which importscreateConfig
from Webpack Config Vue js:
const { createConfig } = require('@deloitte-digital-au/webpack-config-vuejs');
module.exports = createConfig({
entry: {
main: [
'./src/index.js',
],
},
});
- Complete the Getting Started guide.
- Add the package as a dev dependency, by running:
npm install @deloitte-digital-au/webpack-config-react --save-dev
- Add a
webpack.config.js
file which importscreateConfig
from Webpack Config React:
const { createConfig } = require('@deloitte-digital-au/webpack-config-react');
module.exports = createConfig({
entry: {
main: [
'./src/index.js',
],
},
});
- Complete the Getting Started guide.
Add a browserslist
property to your project's package.json
file to define supported browsers:
"browserslist": [
"last 3 versions",
"IE 11",
"iOS >= 8"
]
Autoprefixer and Babel will refer to this browserslist
property to determine the output format for CSS and JavaScript.
ℹ️ Alternatively you can choose to specify your supported browsers in a
.browserslistrc
file.
First install the Babel cli:
npm install @babel/cli --save-dev
Then add a .babelrc
file to the root of your project.
ℹ️ Alternatively you may set a
babel
property to your project'spackage.json
file to specify Babel options.
When using the presets, please ensure you polyfill Object.assign
for older browsers.
Babel for Non React projects
Define the standard preset in your babel options:
{
"presets": ["@deloitte-digital-au/babel-preset-app"]
}
Babel for React projects
Define the React preset in your babel options:
{
"presets": ["@deloitte-digital-au/babel-preset-app-react"]
}
If you want to use Typescript, install the preset:
npm install @babel/preset-typescript --save-dev
Then define the Typescript preset to your .babelrc
, for example:
{
"presets": [
"@deloitte-digital-au/babel-preset",
"@babel/preset-typescript"
]
}
3.1 Add an ESLint configuration file called .eslintrc.js
to your project:
module.exports = {
extends: [
'@deloitte-digital-au/eslint-config',
],
};
3.2 Add a Stylelint configuration file called .stylelint.js
to your project:
module.exports = {
extends: [
'@deloitte-digital-au/stylelint-config',
],
};
Add build
, start
, watch
and/or lint
scripts to your project's package.json
file:
"scripts": {
"build": "webpack --mode production",
"start": "webpack-dev-server --config webpack.config.js --open",
"watch": "webpack --mode development --watch",
"lint": "lint:js && lint:styles",
"lint:js": "eslint \"**/*.js\"",
"lint:styles": "stylelint \"**/*.scss\"",
}
In the project directory, you can run:
Runs a local development server, rebuilds bundles when the source files change, and live-reload in the browser.
Builds the app for production to the dist folder.
It correctly bundles in production mode and optimizes the build for the best performance.
You may wish to create a variation of this script with --mode development
to include source maps in the bundle.
You can view a visualisation of the size of the Webpack output files in an interactive treemap at dist/reports/webpack-report.html
.
Builds the app for development/testing to the dist folder. It correctly bundles in development mode, including source maps.
Lints the JavaScript and SCSS files in the src directory.
If errors are reported, ESLint may be able to fix them automatically for you. Just run:
./node_modules/.bin/eslint --fix "./src/**/*.js"
ℹ️ Make sure you review the changes ESLint made before you commit them.
You can run the linters individually with: npm run lint:js
and npm run lint:styles
.
@deloitte-digital-au/webpack-config
includes a preconfigured base Webpack configuration.
The createConfig
function allows you extend this base configuration with the customisations required for your project. Behind the scenes, the extension of the base config with the custom config is achieved using Smart Merging.
Here is an example of adding an entry property:
createConfig({
entry: {
main: [
'./src/index.js',
'./src/style.scss',
],
},
});
Adding a plugin:
createConfig({
plugins: [/* NEW PLUGIN HERE*/],
});
Adding a loader:
When adding a loader, modules with matching rules will be merged into a single module.
createConfig({
module: {
rules: [
{
test: /\.js$/,
use: 'custom-js-loader',
},
],
},
});
Accessing environment variables
The createConfig
method will also accept a function that returns a configuration object. The function will be called with an argument containing an object with a mode
property to indicate whether Webpack is running in production
or development
mode.
createConfig(({ mode }) => {
return {
module: {
rules: [
{
test: /\.js$/,
use: {
loader: 'custom-js-loader',
options: {
sourceMap: (mode === 'development'),
},
}
},
],
},
}
});
Source maps are disabled for the performance benifits. Should you wish to build source maps you will need to set the GENERATE_SOURCEMAP
environment variable to true
.
for example
GENERATE_SOURCEMAP=true webpack
Stylesheets will be extracted into standalone CSS files, or embedded into JavaScript files, depending on how you import them. This gives you control over the delivery of your CSS. In general, it is recommended to deliver your CSS as a .css
file, to avoid a flash of unstyled content. However, if the styles relate specifically to a JavaScript component it can make sense to deliver them in the same JavaScript file.
- If a
.css
or.scss
file is added as an entry point inwebpack.config.js
(or imported into another SCSS file that is), the CSS will be extracted to a traditional standalone CSS file. - If a
.css
or.scss
file is imported into a.js
file or a.vue
single file component, the CSS will be embedded in the JavaScript and dynamically injected into the web page with style-loader.
Note that if you import a.css
into b.css
, and b.css
into c.js
, then a.css
will be extracted into a CSS file and b.css
will be embedded in JavaScript, because Webpack's issuer
rule only looks at the file which made the import, not at the original entry point. If a
and b
were SCSS files, they would both be extracted to CSS, because unlike css-loader, sass-loader concatenates files after resolving @import
statements.
Name | Description |
---|---|
webpack | Webpack is the engine that allows us to process files and bundle them into packages according to rules that we specify. |
babel-core | Babel is a JavaScript compiler. We write our JavaScript according to the latest spec (ESNext), and Babel compiles it into a specified format (see babel-preset-env). This package is the core compiler for Babel. |
node-sass | The engine of the popular stylesheet preprocessor, Sass. |
post-css | A tool for applying transformations to CSS, such as adding browser prefixes with Autoprefixer. |
@deloitte-digital-au/eslint-config | Deloitte Digital's JavaScript code standards as an ESLint extensible config. Also includes the ESLint package. |
@deloitte-digital-au/stylelint-config | Deloitte Digital's Sass code standards as a Stylelint extensible config. Also includes the Stylelint package. |
Name | Description |
---|---|
autoprefixer | A PostCSS plugin for adding browser prefixes to CSS. |
babel-loader | The integration between Babel and Webpack. |
babel-preset-env | Presets specify the output format for Babel. This preset allows us to generate ES5 output that will run on whichever browsers we specify. To specify which browsers are supported, add a browserslist entry to your project's package.json file. |
css-loader | A Webpack loader which allows us to load CSS files with @import and url() . |
mini-css-extract-plugin | Webpack's architecture is built around JavaScript. Support has been added for CSS, however it results in CSS being embedded inside JavaScript files. This package allows us to export CSS into standalone files. |
sass-loader | The integration between Sass and Webpack. |
style-loader | Allows us to embed CSS into JavaScript. This is useful for functional CSS that is specifically related to a JavaScript module, for example the .shade-bg rule in DD Shade |
file-loader | The file-loader resolves import/require() on a file into a url and emits the file into the output directory. |
url-loader | A loader for webpack which transforms files smaller than 10000 bytes into base64 URIs. |
webpack-cli | The command line interface for Webpack allows us to enter Webpack commands into our project's package.json file. |
webpack-dev-server | Serves a webpack app. Updates the browser on changes. |
webpack-merge | Provides a merge function that concatenates arrays and merges objects creating a new object. |
webpack-bundle-analyzer | Provides an interface to visualize the size of Webpack output files in an interactive treemap. |
Name | Description |
---|---|
vue-loader | A Webpack loader which allows us to use *.vue files. |
vue-template-compiler | Used to pre-compile Vue templates into render functions |
Name | Description |
---|---|
babel-preset-react | Strip flow types and transform JSX into createElement calls |
Refer to the demo folders in the packages folder.
- Publish to npm
- Add SVG optimisation pipeline with SVGO
- Add prettier.io (first create prettier-config-deloitte package)
Q: What if I want to install a newer version of @deloitte-digital-au/eslint-config
, which has not yet been released in
@deloitte-digital-au/webpack-config
?
A: You can still npm install @deloitte-digital-au/eslint-config
in your project. Then your project will use this version of
@deloitte-digital-au/eslint-config
instead of the version that is installed via @deloitte-digital-au/webpack-config
.
Incorrect URLs in some source maps
Source maps for SCSS files embedded inside JS files have incorrect URLs webpack-contrib/css-loader#652
Webpack generates extraneous JavaScript for CSS files
If you define an entry with CSS but no JavaScript, Webpack will still output a (useless) JavaScript file for the entry along with the CSS. For example if you did this:
createConfig({
entry: {
main: [
'./script.js',
],
style: [
'./style.scss', // Not recommended to have an entry with just CSS
],
},
});
Then three files would be generated:
main.js
(good)style.css
(good)style.js
(useless)
To avoid this it is recommended to attach your CSS to an entry that also has JavaScript. For example:
createConfig({
entry: {
main: [
'./script.js',
'./style.scss',
],
},
});
This will only generate two files:
main.js
(good)main.css
(good)
Part Business. Part Creative. Part Technology. One hundred per cent digital.
Pioneered in Australia, Deloitte Digital is committed to helping clients unlock the business value of emerging technologies. We provide clients with a full suite of digital services, covering digital strategy, user experience, content, creative, engineering and implementation across mobile, web and social media channels.