| 1 |
const path = require('path'); |
| 2 |
const fs = require('fs'); |
| 3 |
|
| 4 |
/** |
| 5 |
* Standalone webpack config for the Divi 5 module bundle. |
| 6 |
* |
| 7 |
* This build is intentionally NOT run through @wordpress/scripts: it needs its |
| 8 |
* own `externals` (below) that map `@wordpress/hooks` to Divi's own hooks |
| 9 |
* instance at `window.vendor.wp.hooks`. wp-scripts' dependency extraction would |
| 10 |
* instead map it to `window.wp.hooks` — the wrong instance — which breaks the |
| 11 |
* custom module icon registration. So we run plain webpack (already installed at |
| 12 |
* the project root via @wordpress/scripts) against this dedicated config. |
| 13 |
*/ |
| 14 |
|
| 15 |
// Copies module.json into the build output folder after each build. The PHP |
| 16 |
// side (ModuleRegistration::register_module) reads module.json from |
| 17 |
// blocks/build/divi5/ at runtime, and that folder ships in the production zip |
| 18 |
// while src/ does not. Running on afterEmit guarantees the output folder |
| 19 |
// exists (webpack just created it), so this also works on a first-time build. |
| 20 |
const copyModuleJson = { |
| 21 |
apply: (compiler) => { |
| 22 |
compiler.hooks.afterEmit.tap('CopyModuleJson', () => { |
| 23 |
const src = path.resolve(__dirname, 'src/divi-5/module.json'); |
| 24 |
const destDir = path.resolve(__dirname, 'blocks/build/divi5'); |
| 25 |
fs.mkdirSync(destDir, { recursive: true }); |
| 26 |
fs.copyFileSync(src, path.join(destDir, 'module.json')); |
| 27 |
}); |
| 28 |
}, |
| 29 |
}; |
| 30 |
|
| 31 |
module.exports = { |
| 32 |
// Resolve relative paths against this config's directory, not the CWD. |
| 33 |
context: __dirname, |
| 34 |
|
| 35 |
// Webpack starts bundling assets from the following file. |
| 36 |
entry: { |
| 37 |
bundle: './src/divi-5/index.jsx', |
| 38 |
}, |
| 39 |
|
| 40 |
// Divi Visual Builder uses scripts already enqueued by WordPress and available |
| 41 |
// in global scope so those scripts don't need to be included in the bundle. |
| 42 |
// For webpack to recognize those files, the global variable needs to be |
| 43 |
// registered as externals. This allows global variables listed below to be |
| 44 |
// imported into the module. |
| 45 |
externals: { |
| 46 |
// Third party dependencies. |
| 47 |
react: 'React', |
| 48 |
// Divi 5 exposes WordPress packages under window.vendor.*, and its icon |
| 49 |
// library reads the icon map through that same @wordpress/hooks instance. |
| 50 |
// Mapping to window.vendor.wp.hooks ensures our addFilter is picked up. |
| 51 |
'@wordpress/hooks': ['vendor', 'wp', 'hooks'], |
| 52 |
}, |
| 53 |
|
| 54 |
// This option determines how different types of modules within the project will be treated. |
| 55 |
module: { |
| 56 |
// This option sets up loaders for webpack configuration. |
| 57 |
rules: [ |
| 58 |
// Handle `.jsx` files. |
| 59 |
{ |
| 60 |
test: /\.jsx?$/, |
| 61 |
exclude: /node_modules/, |
| 62 |
use: [ |
| 63 |
// Transpiles JavaScript files using Babel. |
| 64 |
{ |
| 65 |
loader: 'babel-loader', |
| 66 |
options: { |
| 67 |
// Isolate from the root .babelrc so this build's babel |
| 68 |
// config is fully self-contained and deterministic. |
| 69 |
babelrc: false, |
| 70 |
configFile: false, |
| 71 |
compact: false, |
| 72 |
presets: [ |
| 73 |
// Preset that adds configuration for handling latest JavaScript syntax. |
| 74 |
[ |
| 75 |
'@babel/preset-env', |
| 76 |
{ |
| 77 |
modules: false, |
| 78 |
targets: '> 5%', |
| 79 |
}, |
| 80 |
], |
| 81 |
|
| 82 |
// Preset that adds configuration for handling React & JSX. |
| 83 |
'@babel/preset-react', |
| 84 |
], |
| 85 |
plugins: [ |
| 86 |
'@babel/plugin-syntax-optional-chaining', |
| 87 |
'@babel/plugin-syntax-nullish-coalescing-operator', |
| 88 |
], |
| 89 |
cacheDirectory: false, |
| 90 |
}, |
| 91 |
}, |
| 92 |
], |
| 93 |
}, |
| 94 |
], |
| 95 |
}, |
| 96 |
|
| 97 |
// Determine how modules are resolved. |
| 98 |
resolve: { |
| 99 |
// Allows extension to be left off when importing. |
| 100 |
extensions: ['.js', '.jsx'], |
| 101 |
}, |
| 102 |
|
| 103 |
// Determine where the created bundles will be outputted. |
| 104 |
output: { |
| 105 |
filename: 'spsp-divi5.js', |
| 106 |
path: path.resolve(__dirname, 'blocks/build/divi5'), |
| 107 |
}, |
| 108 |
|
| 109 |
// Copy module.json into the output folder so PHP can read it at runtime. |
| 110 |
plugins: [copyModuleJson], |
| 111 |
}; |
| 112 |
|