Last Updated on March 4, 2020 by Neil Murray
With CF7 Skins Visual, all JavaScript & CSS used in the CF7 Skins Visual interface, is built using webpack.
webpack build process #
All React development files are contained in ..\cf7skins-visual\src\ which is built to ..\cf7skins-visual\dist\ by webpack.
We are using an ejected version of create-react-app.
Our Build Scripts #
We have adapted the build scripts from create-react-app:
"scripts": {
"start": "node scripts/start.js", // from create-react-app
// ADD EXPLANATION
"init-dev": "browser-sync start --proxy 'localhost/wordpress' --no-notify",
// ADD EXPLANATION
"dev": "nodemon -w ./src/visual - --exec 'webpack && browser-sync reload --port 3000 --files='./src/**.js''",
"clean": "rm -r build", // NO LONGER USED
"build": "node scripts/build.js", // from create-react-app - NO LONGER USED
"test": "node scripts/test.js --env=jsdom" // from create-react-app
},
Build WordPress Plugins #
[EXPLAIN zip files]
Code Splitting – Dynamic Imports #
We use webpack code splitting to ensure that no Add-on code is included in the free version of CF7 Skins – refer Separating Add-on files.
All the JS code for each Add-on is created as a chunk which can be added as a standalone file in the Add-on plugin.
We use dynamic Importing so that all Add-on JS is loaded dynamically as needed.
/cf7skins-visual/webpack.config.js
output: {
..
chunkFilename: 'dist/ready.js',
..
},
chunkFilename: 'dist/ready.js', – name of non-entry chunk file
/cf7skins-visual/src/visual/index.js
import( /* webpackChunkName: "ready" */ './AddOns/Ready' )
.then( (module) => { this.ReadyAddon = module.ReadyAddon } )
import ( /* webpackChunkName: "ready" */ './AddOns/Ready' )
– import ‘./AddOns/Ready’ as ready.js – see import()
The spec for import doesn’t allow control over the chunk’s name or other properties as “chunks” are only a concept within webpack. Luckily webpack allows some special parameters via comments so as to not break the spec.
.then( (module) => { this.ReadyAddon = module.ReadyAddon } )
– each Add-on needs to export as module
– ‘ReadyAddon’ exported at ./src/visual/AddOns/Ready/index.js
Further Reading:
webpack.config.js #
npm packages used #
- autoprefixer – add vendor prefixes to CSS rules
- path – Node.js path module – utilities for working with file and directory paths
- extract-text-webpack-plugin – extract text from bundle into a separate file
- webpack-shell-plugin – run shell commands before or after webpack builds
- whatwg-fetch – polyfill for fetch()
- postcss – tool for transforming styles
- ncp – copy files programmatically
webpack plugins used #
- CommonsChunkPlugin – generate chunk which contains common modules shared between entry points – common JS modules used by all entry points – creates file of common modules shared between multiple entry points
Entry #
entry: {
- 'visual': ['whatwg-fetch',"./src/index.js"] // dist/visual.js
- 'addons': './src/visual/addons.js' // dist/addons.js
},
– Load ‘whatwg-fetch’ polyfill before entry point. Defaults to XMLHttpRequest-based AJAX requests for older browsers that don’t support ‘fetch’.
– addons.js is separated from visual.js so that it can be added to the CF7 Skins Pro plugin
Output #
/cf7skins-visual/webpack.config.js
output: {
filename: "dist/[name].js",
chunkFilename: 'dist/ready.js',
library: [ 'cf7svisual', '[name]' ],
libraryTarget: 'this',
},
chunkFilename: 'dist/ready.js', – name of non-entry chunk file
library: [ 'cf7svisual', '[name]' ], – make file available via it’s entry name
* 'cf7svisual' added here .. [ADD EXPLANATION]
* [name] is ‘entry’ name
libraryTarget: 'this', – makes library available through ‘this’ object
Further Reading:
Loaders #
- babel-loader – transpile JavaScript files
- style-loader – add CSS to the DOM by injecting a “style“ tag
- css-loader – translates CSS into CommonJS
- less-loader – uses css-loader to turn it into a JS module and ExtractTextPlugin to extract it into a separate file (NO LONGER USED)
- sass-loader – loads SASS/SCSS file and compiles it to CSS (NO LONGER USED?)
- postcss-loader – process CSS with PostCSS
- postcss-flexbugs-fixes – tries to fix all of flexbug’s issues
- html-loader – Exports HTML as string
- url-loader – Loads files as `base64` encoded URL (NO LONGER USED?)
Tests:
- .js –
- .css –
- .scss –
- .less –
- .html –
- (woff|ttf|eot|svg) – ?
Plugins #
In order to use a plugin, you need to require() it and add it to the plugins array. You need to create an instance of it by calling it with the new operator (since you can use a plugin multiple times in a config for different purposes).
- ExtractTextPlugin – used by ‘less-loader’ to extract CSS into a separate file
- WebpackShellPlugin – runs commands before & after webpack build
Further Reading:
From – Working with CF7 Skins Add-ons
Code Splitting – Dynamic Imports #
We use webpack Code Splitting & Dynamic Imports to ensure:
- no Add-on code is included in the free version of CF7 Skins
- all the JS code for each Add-on is created as a chunk which can be added as a standalone file in the Add-on plugin
- Add-on JS is loaded dynamically as needed
Refer Code Splitting – Dynamic Imports
Add-on folders #
Each Add-on:
- needs to export as module
- folder needs to contain all the code for that Add-on
- needs their own webpack chunk file
All the JS code for the Add-on is created as a webpack chunk which can be added as a standalone file in the Add-on plugin.