Working with webpack – webpack 3

Last Updated on March 4, 2020 by Neil Murray

All JavaScript & CSS used in the CF7 Skins Visual interface, is built using webpack.

All React development files are contained in ..\cf7skins-visual\src\ which is built to ..\cf7skins-visual\dist\ by webpack.

create-react-app #

We are using an ejected version of create-react-app (CRA). We update our npm package versions in package.json to match updated create-react-app versions.

We have customized the following CRA webpack.config files:

  • webpack.config.dev.js
  • webpack.config.prod.js

We do this to ensure operation of the JavaScript interface at localhost:3000 matches with operation in the wp-admin.

2018-09-05 Right now create-react-app uses Webpack 3

Refer:

webpack build process #

Our Build Scripts #

We adapt the build scripts from create-react-app:

  "scripts": {
    "start": "node scripts/start.js", // local JS development at http://localhost:3000 - changes are reloaded automatically
    "build": "node scripts/build.js", // from create-react-app
    "test": "node scripts/test.js --env=jsdom", // from create-react-app
    "webpack": "webpack" // rebuilds CF7 Skins Visual plugins in wp-admin using local webpack version
  },

Building our WordPress Plugins #

We use webpack to build separate plugin versions (Dev, Lite, Pro + Add-ons) of CF7 Skins Visual from a single Git repo at https://bitbucket.org/cf7skins/cf7skins-dev-cf7skins-visual.

These plugins can be selectively activated in the wp-admin to test how the Visual Editor operates in our different CF7 Skins plugins:

  • Visual Dev – Contact Form 7 Skins + CF7 Skins Pro + Add-ons
  • Visual Lite – Contact Form 7 Skins only
  • Visual Pro – CF7 Skins Pro + Add-ons

We select which React Components are included in each version when we build each plugin.

NOTE: The JS code generated in CF7 Skins Visual is currently copied manually to our CF7 Skins plugins in their individual Git repositories.

Refer:

Code Splitting #

We use webpack for bundling process and 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 individual Add-on plugin.

Configurations #

To build and split several files, we use multiple configurations ↗ with slightly different webpack configurations, entries and output:

  • baseConfig as base configuration contains webpack default module rules and output for merging with other config.
  • visualConfig to generate visual.js file and AddOns files configuration.
  • addonsConfig to export addons.js into window.cf7svisual used by AddOns.

We use Lodash.merge() ↗ for merging the two config object by appending child object properties without overriding source object. Object.assign() ↗ override source object properties with target object.

Entries #

We setup webpack entry as an object that contains entry (file) name and its path relative to current webpack config file path. These entries are built into standalone chunk files:

  • visual.js – common chunk file, contains all required modules, Visual components and functions, a big file size.
      • We use CommonsChunkPlugin to build the chunk.
      • The modules should not be added or repeated into other files because it will generates error – see multiple copies of React loaded ↗ error.
      • This file should be enqueued first before other chunk files.
  • ready.js – AddOns file chunk for Ready plugin .
  • addons.js – used by AddOns to register their component into Visual.

This is the same approach as WordPress filters. Read more about working with AddOns ↘.

Sample webpack entries:

// visualConfig
entry: {
	visual 	: './src/index.js',
	ready 	: './src/visual/Addons/Ready/index.js',
},

// addonsConfig
entry: {
	addons	: './src/visual/Addons/addons.js',
},

Output #

For base configuration baseConfig, we build each entry chunk into dist directory with the entry name as filename.

output: {
    filename: "dist/[name].js",
},

String [name] will be replaced by webpack with respective entry name. Read more about webpack output.filename ↗. The output filename will be merged with other configs.

output: {
    filename: "dist/[name].js", // after merging
    library: [ 'cf7svisual', '[name]' ], // [name] replaced to `addons`
    libraryTarget: 'window',
},

For addons configuration addonsConfig, we use output.library ↗ to output addons.js as a library for other files and output.librarytarget ↗ to exposed it into window. AddOns can used it by accessing window.cf7svisual.addons.

Exposed addons.js into window.cf7svisual

Further Reading:

webpack.config.js #

npm packages used #

webpack plugins used #

  • CommonsChunkPlugin – generate chunk which contains common modules shared between entry points

Loaders #

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).

Further Reading: