@caweb/webpack 1.6.9 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/utils.js +173 -0
- package/lib/webpack.wp.configurator.js +339 -0
- package/package.json +28 -5
- package/webpack.config.js +13 -21
- package/webpack.wp.config.js +295 -0
- package/lib/webpack.wp.config.js +0 -99
package/lib/utils.js
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { validate } from 'schema-utils';
|
|
5
|
+
import path, { join, sep, dirname } from 'path';
|
|
6
|
+
import { existsSync, realpathSync, readFileSync } from 'fs';
|
|
7
|
+
import { readPackageUp } from 'read-package-up';
|
|
8
|
+
import FastGlob from 'fast-glob';
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Internal dependencies
|
|
13
|
+
*/
|
|
14
|
+
const { sync: glob } = FastGlob;
|
|
15
|
+
|
|
16
|
+
const { warn } = console;
|
|
17
|
+
|
|
18
|
+
const { packageJson, path: pkgPath } = await readPackageUp({cwd: realpathSync( process.cwd() ) });
|
|
19
|
+
|
|
20
|
+
const moduleFields = new Set( [ 'viewScriptModule', 'viewModule' ] );
|
|
21
|
+
|
|
22
|
+
const scriptFields = new Set( [ 'viewScript', 'script', 'editorScript' ] );
|
|
23
|
+
|
|
24
|
+
const hasProjectFile = ( fileName ) =>
|
|
25
|
+
existsSync( fromProjectRoot( fileName ) )
|
|
26
|
+
|
|
27
|
+
const fromProjectRoot = ( fileName ) =>
|
|
28
|
+
path.join( path.dirname( getPackagePath() ), fileName )
|
|
29
|
+
|
|
30
|
+
const getPackagePath = () => pkgPath
|
|
31
|
+
|
|
32
|
+
function getProjectSourcePath() {
|
|
33
|
+
return process.env.WP_SOURCE_PATH || 'src';
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function getBlockJsonScriptFields( blockJson ) {
|
|
37
|
+
let result = null;
|
|
38
|
+
for ( const field of scriptFields ) {
|
|
39
|
+
if ( Object.hasOwn( blockJson, field ) ) {
|
|
40
|
+
if ( ! result ) {
|
|
41
|
+
result = {};
|
|
42
|
+
}
|
|
43
|
+
result[ field ] = blockJson[ field ];
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return result;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function getBlockJsonModuleFields( blockJson ) {
|
|
50
|
+
let result = null;
|
|
51
|
+
for ( const field of moduleFields ) {
|
|
52
|
+
if ( Object.hasOwn( blockJson, field ) ) {
|
|
53
|
+
if ( ! result ) {
|
|
54
|
+
result = {};
|
|
55
|
+
}
|
|
56
|
+
result[ field ] = blockJson[ field ];
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return result;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function getPhpFilePaths( context, props ) {
|
|
63
|
+
// Continue only if the source directory exists.
|
|
64
|
+
if ( ! hasProjectFile( context ) ) {
|
|
65
|
+
return [];
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Checks whether any block metadata files can be detected in the defined source directory.
|
|
69
|
+
const blockMetadataFiles = glob( '**/block.json', {
|
|
70
|
+
absolute: true,
|
|
71
|
+
cwd: fromProjectRoot( context ),
|
|
72
|
+
} );
|
|
73
|
+
|
|
74
|
+
const srcDirectory = fromProjectRoot( context + sep );
|
|
75
|
+
|
|
76
|
+
return blockMetadataFiles.flatMap( ( blockMetadataFile ) => {
|
|
77
|
+
const paths = [];
|
|
78
|
+
let parsedBlockJson;
|
|
79
|
+
try {
|
|
80
|
+
parsedBlockJson = JSON.parse( readFileSync( blockMetadataFile ) );
|
|
81
|
+
} catch ( error ) {
|
|
82
|
+
warn(
|
|
83
|
+
`Not scanning "${ blockMetadataFile.replace(
|
|
84
|
+
fromProjectRoot( sep ),
|
|
85
|
+
''
|
|
86
|
+
) }" due to detect render files due to malformed JSON.`
|
|
87
|
+
);
|
|
88
|
+
return paths;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
for ( const prop of props ) {
|
|
92
|
+
if (
|
|
93
|
+
typeof parsedBlockJson?.[ prop ] !== 'string' ||
|
|
94
|
+
! parsedBlockJson[ prop ]?.startsWith( 'file:' )
|
|
95
|
+
) {
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Removes the `file:` prefix.
|
|
100
|
+
const filepath = join(
|
|
101
|
+
dirname( blockMetadataFile ),
|
|
102
|
+
parsedBlockJson[ prop ].replace( 'file:', '' )
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
// Takes the path without the file extension, and relative to the defined source directory.
|
|
106
|
+
if ( ! filepath.startsWith( srcDirectory ) ) {
|
|
107
|
+
warn(
|
|
108
|
+
`Skipping "${ parsedBlockJson[ prop ].replace(
|
|
109
|
+
'file:',
|
|
110
|
+
''
|
|
111
|
+
) }" listed in "${ blockMetadataFile.replace(
|
|
112
|
+
fromProjectRoot( sep ),
|
|
113
|
+
''
|
|
114
|
+
) }". File is located outside of the "${ context }" directory.`
|
|
115
|
+
);
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
paths.push( filepath.replace( /\\/g, '/' ) );
|
|
119
|
+
}
|
|
120
|
+
return paths;
|
|
121
|
+
} );
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const phpFilePathsPluginSchema = {
|
|
125
|
+
type: 'object',
|
|
126
|
+
properties: {
|
|
127
|
+
context: {
|
|
128
|
+
type: 'string',
|
|
129
|
+
},
|
|
130
|
+
props: {
|
|
131
|
+
type: 'array',
|
|
132
|
+
items: {
|
|
133
|
+
type: 'string',
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* The plugin recomputes PHP file paths once on each compilation. It is necessary to avoid repeating processing
|
|
141
|
+
* when filtering every discovered PHP file in the source folder. This is the most performant way to ensure that
|
|
142
|
+
* changes in `block.json` files are picked up in watch mode.
|
|
143
|
+
*/
|
|
144
|
+
class PhpFilePathsPlugin {
|
|
145
|
+
/**
|
|
146
|
+
* PHP file paths from `render` and `variations` props found in `block.json` files.
|
|
147
|
+
*
|
|
148
|
+
* @type {string[]}
|
|
149
|
+
*/
|
|
150
|
+
static paths;
|
|
151
|
+
|
|
152
|
+
constructor( options = {} ) {
|
|
153
|
+
validate( phpFilePathsPluginSchema, options, {
|
|
154
|
+
name: 'PHP File Paths Plugin',
|
|
155
|
+
baseDataPath: 'options',
|
|
156
|
+
} );
|
|
157
|
+
|
|
158
|
+
this.options = options;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
apply( compiler ) {
|
|
162
|
+
const pluginName = this.constructor.name;
|
|
163
|
+
|
|
164
|
+
compiler.hooks.thisCompilation.tap( pluginName, () => {
|
|
165
|
+
this.constructor.paths = getPhpFilePaths(
|
|
166
|
+
this.options.context,
|
|
167
|
+
this.options.props
|
|
168
|
+
);
|
|
169
|
+
} );
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export { PhpFilePathsPlugin, getBlockJsonScriptFields, getBlockJsonModuleFields, fromProjectRoot, getProjectSourcePath };
|
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Modified WordPress Scripts Webpack Configuration
|
|
3
|
+
*
|
|
4
|
+
* @package CAWebPublishing
|
|
5
|
+
* @link https://webpack.js.org/configuration/
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* External Dependencies
|
|
10
|
+
*/
|
|
11
|
+
import baseConfig from '@wordpress/scripts/config/webpack.config.js';
|
|
12
|
+
import fs from 'fs';
|
|
13
|
+
import path from 'path';
|
|
14
|
+
import * as prettier from 'prettier';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Internal dependencies
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
let output = [];
|
|
21
|
+
|
|
22
|
+
// Update some of the default WordPress webpack rules.
|
|
23
|
+
baseConfig.module.rules.forEach((rule, i) => {
|
|
24
|
+
const r = new RegExp(rule.test).toString();
|
|
25
|
+
|
|
26
|
+
switch(r){
|
|
27
|
+
// WordPress adds a hash to asset file names we remove that hash.
|
|
28
|
+
case new RegExp(/\.(bmp|png|jpe?g|gif|webp)$/i).toString():
|
|
29
|
+
rule.generator.filename = 'images/[name][ext]';
|
|
30
|
+
break;
|
|
31
|
+
case new RegExp(/\.(woff|woff2|eot|ttf|otf)$/i).toString():
|
|
32
|
+
rule.generator.filename = 'fonts/[name][ext]';
|
|
33
|
+
break;
|
|
34
|
+
case new RegExp(/\.svg$/).toString():
|
|
35
|
+
// we don't want SVG to be asset/inline otherwise the resource may not be available.
|
|
36
|
+
// the asset should be an asset/resource we move them to the fonts folder.
|
|
37
|
+
if( 'asset/inline' === rule.type ){
|
|
38
|
+
rule.type = 'asset/resource';
|
|
39
|
+
rule.generator = { filename: 'fonts/[name][ext]' };
|
|
40
|
+
|
|
41
|
+
delete rule.issuer;
|
|
42
|
+
}
|
|
43
|
+
break;
|
|
44
|
+
// silence deprecation warnings from sass
|
|
45
|
+
case new RegExp(/\.(sc|sa)ss$/).toString():
|
|
46
|
+
// The postcss-loader is the 3rd loader
|
|
47
|
+
rule.use[2].options.postcssOptions.plugins = 'postcssPlugins'
|
|
48
|
+
// The sass-loader is last
|
|
49
|
+
rule.use[rule.use.length-1].options.sassOptions = {
|
|
50
|
+
silenceDeprecations: ['global-builtin', 'import', 'color-functions', 'if-function']
|
|
51
|
+
};
|
|
52
|
+
break;
|
|
53
|
+
case new RegExp(/\.m?(j|t)sx?$/).toString():
|
|
54
|
+
// @since @wordpress/scripts@30.20.0 babel-loader is used for js and ts files
|
|
55
|
+
// Added the Transform class properties syntax plugin to the babel-loader.
|
|
56
|
+
// @see https://babeljs.io/docs/en/babel-plugin-proposal-transform-class-properties
|
|
57
|
+
rule.use[0].options.plugins.push('@babel/plugin-transform-class-properties');
|
|
58
|
+
delete rule.use[0].options.cacheDirectory;
|
|
59
|
+
delete rule.use[0].options.configFile;
|
|
60
|
+
delete rule.use[0].options.babelrc;
|
|
61
|
+
|
|
62
|
+
// this one only applies if hasReactFastRefresh and we are serving
|
|
63
|
+
rule.use[0].options.plugins.push('react-refresh/babel');
|
|
64
|
+
|
|
65
|
+
// we add thread-loader before the babel-loader
|
|
66
|
+
// Spawns multiple processes and split work between them. This makes faster build.
|
|
67
|
+
// @see https://webpack.js.org/loaders/thread-loader/
|
|
68
|
+
rule.use = [{
|
|
69
|
+
loader: 'thread-loader',
|
|
70
|
+
options: {
|
|
71
|
+
workers: -1,
|
|
72
|
+
},
|
|
73
|
+
}].concat(rule.use);
|
|
74
|
+
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
// Update some of the default WordPress plugins.
|
|
80
|
+
// when importing the base configuration, the plugins are already instantiated so we have to loop through them and modify the options of the instantiated plugins.
|
|
81
|
+
baseConfig.plugins = baseConfig.plugins.map((plugin, i) => {
|
|
82
|
+
const pluginName = plugin.constructor.name;
|
|
83
|
+
|
|
84
|
+
switch(pluginName){
|
|
85
|
+
case 'MiniCssExtractPlugin':
|
|
86
|
+
// we only need the filename
|
|
87
|
+
delete plugin.options.ignoreOrder;
|
|
88
|
+
delete plugin.options.runtime;
|
|
89
|
+
delete plugin.options.experimental;
|
|
90
|
+
delete plugin.options.experimentalUseImportModule;
|
|
91
|
+
|
|
92
|
+
break;
|
|
93
|
+
case 'DefinePlugin':
|
|
94
|
+
Object.entries(plugin.definitions).forEach( ([d, n]) => {
|
|
95
|
+
// these are booleans but come in as strings, so we set them again so they are boolean
|
|
96
|
+
plugin.definitions[d] = ('true' === n)
|
|
97
|
+
})
|
|
98
|
+
break;
|
|
99
|
+
case 'RtlCssPlugin':
|
|
100
|
+
// we disable the RTL CSS generation we don't need them
|
|
101
|
+
plugin = false;
|
|
102
|
+
break;
|
|
103
|
+
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return plugin;
|
|
107
|
+
}).filter( Boolean );
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* we remove the WordPress devServer declaration since we can only have 1 when exporting multiple configurations
|
|
111
|
+
*
|
|
112
|
+
* @see https://github.com/webpack/webpack-cli/issues/2408#issuecomment-793052542
|
|
113
|
+
*/
|
|
114
|
+
delete baseConfig.devServer;
|
|
115
|
+
|
|
116
|
+
// Serialize all the data from webpack config and saves it to the output array
|
|
117
|
+
// this is the last chance to make any changes and some changes have to be made here otherwise prettier will fail to format the code correctly.
|
|
118
|
+
const serializeData = ( data ) => {
|
|
119
|
+
Object.entries(data).forEach(([k, v]) => {
|
|
120
|
+
// if the key is not a number, set it as the property key
|
|
121
|
+
// if the key has a dash it has to be wrapped in quotes
|
|
122
|
+
let key = Number.isNaN(Number(k)) ? (k.includes('-') || k.includes('.') ? `'${k}':` : `${k}:`) : '';
|
|
123
|
+
|
|
124
|
+
// if the key is blank then the value is being used in an array.
|
|
125
|
+
let isInArray = ! key.length;
|
|
126
|
+
|
|
127
|
+
switch( typeof v ){
|
|
128
|
+
case 'string':
|
|
129
|
+
v = v.match(/(browserslist:)?.*\/node_modules\/(@wordpress\/)?([\w-]+)\/.*/g) ?
|
|
130
|
+
v.replace(/(browserslist:)?.*\/node_modules\/(@wordpress\/)?([\w-]+)\/.*/g, '$1$2$3') : v;
|
|
131
|
+
|
|
132
|
+
if(v.startsWith('browserslist:')){
|
|
133
|
+
v = "browserslist.findConfig( '.' ) ? browserslist.findConfig( '.' ) : 'browserslist:extends @wordpress/browserslist-config'";
|
|
134
|
+
} else if ( 'path' === k ){
|
|
135
|
+
// since we want it to be dynamic based on where the user is running the webpack command
|
|
136
|
+
v = "resolve( process.cwd(), 'build' )";
|
|
137
|
+
// this is the filename for the MiniCssExtractPlugin which needs to be modified to match the mode
|
|
138
|
+
} else if ( 'filename' === k && v.endsWith('.css') ){
|
|
139
|
+
v = 'isProduction ? \'[name].min.css\' : \'[name].css\''
|
|
140
|
+
} else if( 'mini-css-extract-plugin' === v ){
|
|
141
|
+
v = 'MiniCssExtractPlugin.loader';
|
|
142
|
+
// all of these values can be wrapped in a require.resolve since they are all packages that need to be resolved
|
|
143
|
+
} else if(
|
|
144
|
+
'@wordpress/babel-preset-default' === v ||
|
|
145
|
+
'react-refresh/babel' === v ||
|
|
146
|
+
[ 'loader', 'use', 'target' ].includes(k)
|
|
147
|
+
){
|
|
148
|
+
v = `require.resolve( '${v}' )`;
|
|
149
|
+
|
|
150
|
+
} else if ('postcssPlugins' === v ){
|
|
151
|
+
// we don't have to do anything, we just dont need it wrapped in quotes sinces its a constant.
|
|
152
|
+
}else{
|
|
153
|
+
// all other string values should be wrapped in quotes
|
|
154
|
+
v = `'${v}'`;
|
|
155
|
+
|
|
156
|
+
}
|
|
157
|
+
case 'boolean':
|
|
158
|
+
case 'number':
|
|
159
|
+
|
|
160
|
+
// push to output
|
|
161
|
+
output.push(`${ key } ${v}`);
|
|
162
|
+
break;
|
|
163
|
+
case 'object':
|
|
164
|
+
// if the value is a regex
|
|
165
|
+
if( v instanceof RegExp ){
|
|
166
|
+
output.push(`${key}${v}`)
|
|
167
|
+
// if the value is a boolean
|
|
168
|
+
}else if ( v instanceof Boolean ){
|
|
169
|
+
output.push(`${key}${v}`)
|
|
170
|
+
|
|
171
|
+
// if the value is an array
|
|
172
|
+
}else if( v instanceof Array ){
|
|
173
|
+
output.push(`${key}[`)
|
|
174
|
+
serializeData(v);
|
|
175
|
+
output.push(`]`)
|
|
176
|
+
|
|
177
|
+
// if the constructor name is not Object or Array, assume it a class
|
|
178
|
+
// these are usually plugins used in the configurations
|
|
179
|
+
} else if ( ! ['Object', 'Array'].includes( v.constructor.name ) ){
|
|
180
|
+
// the DefinePlugin is part of the webpack package not a standalone plugin
|
|
181
|
+
// so if the plugin is DefinePlugin we prefix the name with webpack.
|
|
182
|
+
let pluginName = 'DefinePlugin' !== v.constructor.name ? v.constructor.name :`webpack.${v.constructor.name}`;
|
|
183
|
+
|
|
184
|
+
let config = {};
|
|
185
|
+
|
|
186
|
+
// each plugin has a different configuration
|
|
187
|
+
switch( pluginName ){
|
|
188
|
+
case 'webpack.DefinePlugin':
|
|
189
|
+
config = v.definitions;
|
|
190
|
+
break;
|
|
191
|
+
case 'TerserPlugin':
|
|
192
|
+
// the terserplugin does not need the minimizer, test option, but is missing the terserOptions
|
|
193
|
+
delete v.options.minimizer;
|
|
194
|
+
delete v.options.test;
|
|
195
|
+
|
|
196
|
+
// add the terserOptions
|
|
197
|
+
v.options.terserOptions = {
|
|
198
|
+
output: {
|
|
199
|
+
comments: /translators:/i,
|
|
200
|
+
},
|
|
201
|
+
compress: {
|
|
202
|
+
passes: 2,
|
|
203
|
+
},
|
|
204
|
+
mangle: {
|
|
205
|
+
reserved: [ '__', '_n', '_nx', '_x' ],
|
|
206
|
+
},
|
|
207
|
+
}
|
|
208
|
+
case 'PhpFilePathsPlugin':
|
|
209
|
+
case 'MiniCssExtractPlugin':
|
|
210
|
+
config = v.options;
|
|
211
|
+
break;
|
|
212
|
+
case 'ReactRefreshPlugin': // this is the ReactRefreshWebpackPlugin
|
|
213
|
+
pluginName = 'ReactRefreshWebpackPlugin';
|
|
214
|
+
break;
|
|
215
|
+
case 'CopyPlugin': // this is the CopyWebpackPlugin
|
|
216
|
+
pluginName = 'CopyWebpackPlugin'
|
|
217
|
+
config = v;
|
|
218
|
+
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// if the plugin has configurations
|
|
222
|
+
if( Object.keys(config).length ){
|
|
223
|
+
|
|
224
|
+
output.push(`new ${pluginName}({`)
|
|
225
|
+
serializeData( config );
|
|
226
|
+
output.push('})')
|
|
227
|
+
}else{
|
|
228
|
+
|
|
229
|
+
// DependencyExtractionWebpackPlugin
|
|
230
|
+
if( 'DependencyExtractionWebpackPlugin' === pluginName ){
|
|
231
|
+
output.push( `externals && new ${pluginName}()` );
|
|
232
|
+
}else {
|
|
233
|
+
output.push(`new ${pluginName}()`)
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
}else{
|
|
239
|
+
output.push(`${key} {`)
|
|
240
|
+
serializeData(v);
|
|
241
|
+
output.push(`}`)
|
|
242
|
+
}
|
|
243
|
+
break;
|
|
244
|
+
case 'function':
|
|
245
|
+
// these functions can just be executed
|
|
246
|
+
if( 'entry' === k ){
|
|
247
|
+
output.push(`${key}${JSON.stringify(v('script'))}`);
|
|
248
|
+
}else if( ['name', 'transform'].includes(k) ) {
|
|
249
|
+
output.push(v.toString());
|
|
250
|
+
}else if( ['implementation', 'filter'].includes(k) ){
|
|
251
|
+
output.push( `${key}${v.toString()}` )
|
|
252
|
+
}
|
|
253
|
+
break;
|
|
254
|
+
}
|
|
255
|
+
})
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// header information for the output file
|
|
259
|
+
let header = `/**\n * This file is autogenerated and should not be modified.
|
|
260
|
+
* Last modified: ${ new Date().toString()}\n */`;
|
|
261
|
+
|
|
262
|
+
// Imports that have to be included
|
|
263
|
+
let imports = Object.entries({
|
|
264
|
+
'CopyWebpackPlugin': 'copy-webpack-plugin',
|
|
265
|
+
'webpack': 'webpack',
|
|
266
|
+
'browserslist': 'browserslist',
|
|
267
|
+
'MiniCssExtractPlugin': 'mini-css-extract-plugin',
|
|
268
|
+
'{basename, dirname, relative, resolve, sep}': 'path',
|
|
269
|
+
'TerserPlugin': 'terser-webpack-plugin',
|
|
270
|
+
'{ realpathSync }': 'fs',
|
|
271
|
+
'DependencyExtractionWebpackPlugin': '@wordpress/dependency-extraction-webpack-plugin',
|
|
272
|
+
'postcssPlugins': '@wordpress/postcss-plugins-preset',
|
|
273
|
+
'{ createRequire }': 'module',
|
|
274
|
+
'{ getArgVal }': './lib/args.js',
|
|
275
|
+
'{PhpFilePathsPlugin, getBlockJsonScriptFields, getBlockJsonModuleFields, fromProjectRoot, getProjectSourcePath}': './lib/utils.js',
|
|
276
|
+
}).map(([p, r]) => `import ${p} from '${r}';`).filter(Boolean).join('\n');
|
|
277
|
+
|
|
278
|
+
let constants = Object.entries({
|
|
279
|
+
'isProduction': "getArgVal('mode', 'development') === 'production'",
|
|
280
|
+
'hasReactFastRefresh': '! isProduction',
|
|
281
|
+
'require': 'createRequire(import.meta.url)',
|
|
282
|
+
'externals': 'getArgVal("externals", true)',
|
|
283
|
+
}).map(([p, r]) => `const ${p} = ${r};`).filter(Boolean).join('\n');
|
|
284
|
+
|
|
285
|
+
// start data serialization
|
|
286
|
+
serializeData( baseConfig );
|
|
287
|
+
|
|
288
|
+
// if an object was created we replace the leading comma that is created when joining the output
|
|
289
|
+
let formattedCode = await prettier.format(
|
|
290
|
+
`${header}
|
|
291
|
+
${imports}\n
|
|
292
|
+
${constants}\n
|
|
293
|
+
export default {${output.join(',').replace(/([{[(]),/g, '$1')}}`,
|
|
294
|
+
{
|
|
295
|
+
filepath: '.prettierrc.js'
|
|
296
|
+
}
|
|
297
|
+
)
|
|
298
|
+
|
|
299
|
+
// we write this modified webpack config to the root
|
|
300
|
+
fs.writeFileSync( path.resolve('.', 'webpack.wp.config.js'), formattedCode );
|
|
301
|
+
|
|
302
|
+
// we create one utility file that will contain only the necessary @wordpress/scripts/utils functions/classes used
|
|
303
|
+
import { getPhpFilePaths, hasProjectFile, fromProjectRoot, getBlockJsonScriptFields, getBlockJsonModuleFields, getProjectSourcePath } from '@wordpress/scripts/utils/index.js';
|
|
304
|
+
import { getPackagePath } from '@wordpress/scripts/utils/package.js';
|
|
305
|
+
|
|
306
|
+
// we read the phpFilePathsPlugin file and replace the require statements into import statements since we want to write it as an ES module
|
|
307
|
+
let phpFilePathsPlugin = fs.readFileSync(
|
|
308
|
+
path.resolve('.', 'node_modules', '@wordpress', 'scripts', 'plugins', 'php-file-paths-plugin', 'index.js')
|
|
309
|
+
)
|
|
310
|
+
.toString()
|
|
311
|
+
.replace("const { validate } = require( 'schema-utils' );",
|
|
312
|
+
[
|
|
313
|
+
"import { validate } from 'schema-utils';",
|
|
314
|
+
"import path, { join, sep, dirname } from 'path';",
|
|
315
|
+
"import { existsSync, realpathSync, readFileSync } from 'fs';",
|
|
316
|
+
"import { readPackageUp } from 'read-package-up';",
|
|
317
|
+
"import FastGlob from 'fast-glob';\n",
|
|
318
|
+
].join('\n')
|
|
319
|
+
)
|
|
320
|
+
.replace("const { getPhpFilePaths } = require( '../../utils' );", [
|
|
321
|
+
'const { sync: glob } = FastGlob;',
|
|
322
|
+
'const { warn } = console;',
|
|
323
|
+
'const { packageJson, path: pkgPath } = await readPackageUp({cwd: realpathSync( process.cwd() ) });',
|
|
324
|
+
"const moduleFields = new Set( [ 'viewScriptModule', 'viewModule' ] );",
|
|
325
|
+
"const scriptFields = new Set( [ 'viewScript', 'script', 'editorScript' ] );",
|
|
326
|
+
`const hasProjectFile = ${hasProjectFile.toString()}`,
|
|
327
|
+
`const fromProjectRoot = ${fromProjectRoot.toString()}`,
|
|
328
|
+
`const getPackagePath = ${getPackagePath.toString()}`,
|
|
329
|
+
getProjectSourcePath.toString(),
|
|
330
|
+
getBlockJsonScriptFields.toString(),
|
|
331
|
+
getBlockJsonModuleFields.toString(),
|
|
332
|
+
getPhpFilePaths.toString(),
|
|
333
|
+
].join('\n\n'))
|
|
334
|
+
.replace("module.exports = PhpFilePathsPlugin", "export { PhpFilePathsPlugin, getBlockJsonScriptFields, getBlockJsonModuleFields, fromProjectRoot, getProjectSourcePath }")
|
|
335
|
+
|
|
336
|
+
// we write this modified plugin to the lib/utils.js folder
|
|
337
|
+
fs.writeFileSync( path.resolve('.', 'lib', 'utils.js' ), phpFilePathsPlugin );
|
|
338
|
+
|
|
339
|
+
export default baseConfig;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@caweb/webpack",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "CAWebPublishing Webpack Configuration",
|
|
5
5
|
"main": "webpack.config.js",
|
|
6
6
|
"files": [
|
|
@@ -8,13 +8,15 @@
|
|
|
8
8
|
"lib",
|
|
9
9
|
"tests",
|
|
10
10
|
"webpack.config.js",
|
|
11
|
+
"webpack.wp.config.js",
|
|
11
12
|
"tsconfig.json"
|
|
12
13
|
],
|
|
13
14
|
"type": "module",
|
|
14
15
|
"scripts": {
|
|
15
16
|
"webpack": "webpack",
|
|
17
|
+
"gen:wp": "node lib/webpack.wp.configurator.js",
|
|
16
18
|
"test:config": "webpack configtest",
|
|
17
|
-
"test:serve": "
|
|
19
|
+
"test:serve": "cross-env CAWEB_NODE_OPTIONS='--template ./patterns/default.html --search-template ./patterns/search.html' webpack serve --config ./webpack.config.js ./tests/webpack.tests.js --merge",
|
|
18
20
|
"test": "echo \\\"Error: run tests from root\\\" && exit 0"
|
|
19
21
|
},
|
|
20
22
|
"repository": {
|
|
@@ -36,15 +38,27 @@
|
|
|
36
38
|
},
|
|
37
39
|
"homepage": "https://github.com/CAWebPublishing/webpack#readme",
|
|
38
40
|
"dependencies": {
|
|
39
|
-
"@babel/plugin-
|
|
40
|
-
"@wordpress/
|
|
41
|
+
"@babel/plugin-transform-class-properties": "^7.28.6",
|
|
42
|
+
"@wordpress/babel-preset-default": "^8.40.0",
|
|
43
|
+
"@wordpress/dependency-extraction-webpack-plugin": "^6.40.0",
|
|
44
|
+
"@wordpress/postcss-plugins-preset": "^5.40.0",
|
|
45
|
+
"babel-loader": "^10.0.0",
|
|
46
|
+
"copy-webpack-plugin": "^13.0.1",
|
|
47
|
+
"css-loader": "^7.1.4",
|
|
41
48
|
"css-minimizer-webpack-plugin": "^7.0.4",
|
|
42
49
|
"deepmerge": "^4.3.1",
|
|
50
|
+
"fast-glob": "^3.3.3",
|
|
43
51
|
"handlebars": "^4.7.8",
|
|
44
52
|
"handlebars-loader": "^1.7.3",
|
|
45
53
|
"html-format": "^1.1.7",
|
|
46
54
|
"html-webpack-plugin": "^5.6.6",
|
|
47
|
-
"
|
|
55
|
+
"mini-css-extract-plugin": "^2.10.0",
|
|
56
|
+
"postcss-loader": "^8.2.1",
|
|
57
|
+
"react-refresh": "^0.18.0",
|
|
58
|
+
"read-package-up": "^12.0.0",
|
|
59
|
+
"sass": "^1.97.3",
|
|
60
|
+
"sass-loader": "^16.0.7",
|
|
61
|
+
"source-map-loader": "^5.0.0",
|
|
48
62
|
"thread-loader": "^4.0.4",
|
|
49
63
|
"ts-loader": "^9.5.4",
|
|
50
64
|
"webpack": "^5.105.2",
|
|
@@ -52,5 +66,14 @@
|
|
|
52
66
|
"webpack-dev-server": "^5.2.3",
|
|
53
67
|
"webpack-merge": "^6.0.1",
|
|
54
68
|
"webpack-remove-empty-scripts": "^1.1.1"
|
|
69
|
+
},
|
|
70
|
+
"devDependencies": {
|
|
71
|
+
"@wordpress/scripts": "^31.5.0",
|
|
72
|
+
"cross-env": "^10.1.0",
|
|
73
|
+
"prettier": "^3.8.1"
|
|
74
|
+
},
|
|
75
|
+
"overrides": {
|
|
76
|
+
"minimatch": "^10.2.4",
|
|
77
|
+
"webpack-dev-server": "^5.2.3"
|
|
55
78
|
}
|
|
56
79
|
}
|
package/webpack.config.js
CHANGED
|
@@ -9,24 +9,16 @@
|
|
|
9
9
|
/**
|
|
10
10
|
* External Dependencies
|
|
11
11
|
*/
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
import baseConfig from './webpack.wp.config.js';
|
|
13
|
+
|
|
14
14
|
import fs from 'fs';
|
|
15
15
|
import path from 'path';
|
|
16
16
|
import { fileURLToPath } from 'url';
|
|
17
17
|
|
|
18
18
|
// webpack plugins
|
|
19
19
|
import { merge } from 'webpack-merge';
|
|
20
|
-
// import MiniCSSExtractPlugin from 'mini-css-extract-plugin';
|
|
21
20
|
import CssMinimizerPlugin from 'css-minimizer-webpack-plugin';
|
|
22
21
|
import RemoveEmptyScriptsPlugin from 'webpack-remove-empty-scripts';
|
|
23
|
-
import {HtmlWebpackSkipAssetsPlugin} from 'html-webpack-skip-assets-plugin';
|
|
24
|
-
// import RtlCssPlugin from 'rtlcss-webpack-plugin';
|
|
25
|
-
// import {HtmlWebpackLinkTypePlugin} from 'html-webpack-link-type-plugin';
|
|
26
|
-
|
|
27
|
-
// import JSHintPlugin from '@caweb/jshint-webpack-plugin';
|
|
28
|
-
// import CSSAuditPlugin from '@caweb/css-audit-webpack-plugin';
|
|
29
|
-
// import A11yPlugin from '@caweb/a11y-webpack-plugin';
|
|
30
22
|
|
|
31
23
|
/**
|
|
32
24
|
* Internal dependencies
|
|
@@ -49,7 +41,7 @@ let caweb = fs.existsSync( path.join(appPath, 'caweb.json') ) ?
|
|
|
49
41
|
JSON.parse(fs.readFileSync(path.join(appPath, 'caweb.json')))
|
|
50
42
|
: {};
|
|
51
43
|
|
|
52
|
-
let mode = getArgVal('
|
|
44
|
+
let mode = getArgVal('mode', 'development');
|
|
53
45
|
let isProduction = mode === 'production';
|
|
54
46
|
let devServer = false;
|
|
55
47
|
|
|
@@ -102,7 +94,8 @@ let webpackConfig = {
|
|
|
102
94
|
filename: isProduction ? '[name].min.js' : '[name].js',
|
|
103
95
|
chunkFilename: isProduction ? '[name].min.js?v=[chunkhash]' : '[name].js?v=[chunkhash]',
|
|
104
96
|
pathinfo: false,
|
|
105
|
-
clean: isProduction
|
|
97
|
+
clean: isProduction,
|
|
98
|
+
path: path.resolve( process.cwd(), 'build' )
|
|
106
99
|
},
|
|
107
100
|
|
|
108
101
|
/**
|
|
@@ -164,7 +157,6 @@ let webpackConfig = {
|
|
|
164
157
|
* Devtool Configuration
|
|
165
158
|
* WordPress by default uses 'source-map' for devtool which affects build and rebuild speed.
|
|
166
159
|
* For development we switch to 'eval' which is much faster.
|
|
167
|
-
* For production we turn off devtool completely.
|
|
168
160
|
* @see https://webpack.js.org/configuration/devtool/#devtool
|
|
169
161
|
*/
|
|
170
162
|
devtool: isProduction ? 'source-map' : 'eval',
|
|
@@ -221,14 +213,14 @@ let webpackConfig = {
|
|
|
221
213
|
new RemoveEmptyScriptsPlugin(),
|
|
222
214
|
|
|
223
215
|
// certain files can be skipped when serving
|
|
224
|
-
new HtmlWebpackSkipAssetsPlugin({
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
}),
|
|
216
|
+
// new HtmlWebpackSkipAssetsPlugin({
|
|
217
|
+
// skipAssets: [
|
|
218
|
+
// /.*-rtl.css/, // we skip the Right-to-Left Styles
|
|
219
|
+
// /css-audit.*/, // we skip the CSSAudit Files
|
|
220
|
+
// /a11y.*/, // we skip the A11y Files
|
|
221
|
+
// /jshint.*/, // we skip the JSHint Files
|
|
222
|
+
// ]
|
|
223
|
+
// }),
|
|
232
224
|
],
|
|
233
225
|
|
|
234
226
|
/**
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is autogenerated and should not be modified.
|
|
3
|
+
* Last modified: Thu Feb 26 2026 08:36:43 GMT-0800 (Pacific Standard Time)
|
|
4
|
+
*/
|
|
5
|
+
import CopyWebpackPlugin from "copy-webpack-plugin";
|
|
6
|
+
import webpack from "webpack";
|
|
7
|
+
import browserslist from "browserslist";
|
|
8
|
+
import MiniCssExtractPlugin from "mini-css-extract-plugin";
|
|
9
|
+
import { basename, dirname, relative, resolve, sep } from "path";
|
|
10
|
+
import TerserPlugin from "terser-webpack-plugin";
|
|
11
|
+
import { realpathSync } from "fs";
|
|
12
|
+
import DependencyExtractionWebpackPlugin from "@wordpress/dependency-extraction-webpack-plugin";
|
|
13
|
+
import postcssPlugins from "@wordpress/postcss-plugins-preset";
|
|
14
|
+
import { createRequire } from "module";
|
|
15
|
+
import { getArgVal } from "./lib/args.js";
|
|
16
|
+
import {
|
|
17
|
+
PhpFilePathsPlugin,
|
|
18
|
+
getBlockJsonScriptFields,
|
|
19
|
+
getBlockJsonModuleFields,
|
|
20
|
+
fromProjectRoot,
|
|
21
|
+
getProjectSourcePath,
|
|
22
|
+
} from "./lib/utils.js";
|
|
23
|
+
|
|
24
|
+
const isProduction = getArgVal("mode", "development") === "production";
|
|
25
|
+
const hasReactFastRefresh = !isProduction;
|
|
26
|
+
const require = createRequire(import.meta.url);
|
|
27
|
+
const externals = getArgVal("externals", true);
|
|
28
|
+
|
|
29
|
+
export default {
|
|
30
|
+
mode: "development",
|
|
31
|
+
target: browserslist.findConfig(".")
|
|
32
|
+
? browserslist.findConfig(".")
|
|
33
|
+
: "browserslist:extends @wordpress/browserslist-config",
|
|
34
|
+
output: {
|
|
35
|
+
filename: "[name].js",
|
|
36
|
+
chunkFilename: "[name].js?ver=[chunkhash]",
|
|
37
|
+
path: resolve(process.cwd(), "build"),
|
|
38
|
+
clean: { keep: /^(fonts|images)\// },
|
|
39
|
+
},
|
|
40
|
+
resolve: {
|
|
41
|
+
alias: { "lodash-es": "lodash" },
|
|
42
|
+
extensions: [".jsx", ".ts", ".tsx", "..."],
|
|
43
|
+
},
|
|
44
|
+
optimization: {
|
|
45
|
+
concatenateModules: false,
|
|
46
|
+
runtimeChunk: false,
|
|
47
|
+
splitChunks: {
|
|
48
|
+
cacheGroups: {
|
|
49
|
+
style: {
|
|
50
|
+
type: "css/mini-extract",
|
|
51
|
+
test: /[\\/]style(\.module)?\.(pc|sc|sa|c)ss$/,
|
|
52
|
+
chunks: "all",
|
|
53
|
+
enforce: true,
|
|
54
|
+
name(_, chunks, cacheGroupKey) {
|
|
55
|
+
const chunkName = chunks[0].name;
|
|
56
|
+
return `${dirname(
|
|
57
|
+
chunkName,
|
|
58
|
+
)}/${cacheGroupKey}-${basename(chunkName)}`;
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
default: false,
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
minimizer: [
|
|
65
|
+
new TerserPlugin({
|
|
66
|
+
extractComments: false,
|
|
67
|
+
parallel: true,
|
|
68
|
+
terserOptions: {
|
|
69
|
+
output: { comments: /translators:/i },
|
|
70
|
+
compress: { passes: 2 },
|
|
71
|
+
mangle: { reserved: ["__", "_n", "_nx", "_x"] },
|
|
72
|
+
},
|
|
73
|
+
}),
|
|
74
|
+
],
|
|
75
|
+
},
|
|
76
|
+
module: {
|
|
77
|
+
rules: [
|
|
78
|
+
{
|
|
79
|
+
test: /\.(j|t)sx?$/,
|
|
80
|
+
exclude: [/node_modules/],
|
|
81
|
+
use: require.resolve("source-map-loader"),
|
|
82
|
+
enforce: "pre",
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
test: /\.m?(j|t)sx?$/,
|
|
86
|
+
exclude: /node_modules/,
|
|
87
|
+
use: [
|
|
88
|
+
{
|
|
89
|
+
loader: require.resolve("thread-loader"),
|
|
90
|
+
options: { workers: -1 },
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
loader: require.resolve("babel-loader"),
|
|
94
|
+
options: {
|
|
95
|
+
presets: [require.resolve("@wordpress/babel-preset-default")],
|
|
96
|
+
plugins: [
|
|
97
|
+
"@babel/plugin-transform-class-properties",
|
|
98
|
+
require.resolve("react-refresh/babel"),
|
|
99
|
+
],
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
],
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
test: /\.css$/,
|
|
106
|
+
use: [
|
|
107
|
+
{ loader: MiniCssExtractPlugin.loader },
|
|
108
|
+
{
|
|
109
|
+
loader: require.resolve("css-loader"),
|
|
110
|
+
options: {
|
|
111
|
+
importLoaders: 1,
|
|
112
|
+
sourceMap: true,
|
|
113
|
+
modules: { auto: true },
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
loader: require.resolve("postcss-loader"),
|
|
118
|
+
options: {
|
|
119
|
+
postcssOptions: {
|
|
120
|
+
ident: "postcss",
|
|
121
|
+
sourceMap: true,
|
|
122
|
+
plugins: postcssPlugins,
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
],
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
test: /\.pcss$/,
|
|
130
|
+
use: [
|
|
131
|
+
{ loader: MiniCssExtractPlugin.loader },
|
|
132
|
+
{
|
|
133
|
+
loader: require.resolve("css-loader"),
|
|
134
|
+
options: {
|
|
135
|
+
importLoaders: 1,
|
|
136
|
+
sourceMap: true,
|
|
137
|
+
modules: { auto: true },
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
loader: require.resolve("postcss-loader"),
|
|
142
|
+
options: {
|
|
143
|
+
postcssOptions: {
|
|
144
|
+
ident: "postcss",
|
|
145
|
+
sourceMap: true,
|
|
146
|
+
plugins: postcssPlugins,
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
],
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
test: /\.(sc|sa)ss$/,
|
|
154
|
+
use: [
|
|
155
|
+
{ loader: MiniCssExtractPlugin.loader },
|
|
156
|
+
{
|
|
157
|
+
loader: require.resolve("css-loader"),
|
|
158
|
+
options: {
|
|
159
|
+
importLoaders: 1,
|
|
160
|
+
sourceMap: true,
|
|
161
|
+
modules: { auto: true },
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
loader: require.resolve("postcss-loader"),
|
|
166
|
+
options: {
|
|
167
|
+
postcssOptions: {
|
|
168
|
+
ident: "postcss",
|
|
169
|
+
sourceMap: true,
|
|
170
|
+
plugins: postcssPlugins,
|
|
171
|
+
},
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
loader: require.resolve("sass-loader"),
|
|
176
|
+
options: {
|
|
177
|
+
sourceMap: true,
|
|
178
|
+
sassOptions: {
|
|
179
|
+
silenceDeprecations: [
|
|
180
|
+
"global-builtin",
|
|
181
|
+
"import",
|
|
182
|
+
"color-functions",
|
|
183
|
+
"if-function",
|
|
184
|
+
],
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
],
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
test: /\.svg$/,
|
|
192
|
+
issuer: /\.(j|t)sx?$/,
|
|
193
|
+
use: ["@svgr/webpack", "url-loader"],
|
|
194
|
+
type: "javascript/auto",
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
test: /\.svg$/,
|
|
198
|
+
type: "asset/resource",
|
|
199
|
+
generator: { filename: "fonts/[name][ext]" },
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
test: /\.(bmp|png|jpe?g|gif|webp)$/i,
|
|
203
|
+
type: "asset/resource",
|
|
204
|
+
generator: { filename: "images/[name][ext]" },
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
test: /\.(woff|woff2|eot|ttf|otf)$/i,
|
|
208
|
+
type: "asset/resource",
|
|
209
|
+
generator: { filename: "fonts/[name][ext]" },
|
|
210
|
+
},
|
|
211
|
+
],
|
|
212
|
+
},
|
|
213
|
+
stats: { children: false },
|
|
214
|
+
devtool: "source-map",
|
|
215
|
+
entry: {},
|
|
216
|
+
plugins: [
|
|
217
|
+
new webpack.DefinePlugin({
|
|
218
|
+
"globalThis.SCRIPT_DEBUG": true,
|
|
219
|
+
SCRIPT_DEBUG: true,
|
|
220
|
+
}),
|
|
221
|
+
new PhpFilePathsPlugin({ context: "src", props: ["render", "variations"] }),
|
|
222
|
+
new CopyWebpackPlugin({
|
|
223
|
+
patterns: [
|
|
224
|
+
{
|
|
225
|
+
from: "**/block.json",
|
|
226
|
+
context: "src",
|
|
227
|
+
noErrorOnMissing: true,
|
|
228
|
+
transform(content, absoluteFrom) {
|
|
229
|
+
const convertExtension = (path) => {
|
|
230
|
+
return path.replace(/\.m?(j|t)sx?$/, ".js");
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
if (basename(absoluteFrom) === "block.json") {
|
|
234
|
+
const blockJson = JSON.parse(content.toString());
|
|
235
|
+
|
|
236
|
+
[
|
|
237
|
+
getBlockJsonScriptFields(blockJson),
|
|
238
|
+
getBlockJsonModuleFields(blockJson),
|
|
239
|
+
].forEach((fields) => {
|
|
240
|
+
if (fields) {
|
|
241
|
+
for (const [key, value] of Object.entries(fields)) {
|
|
242
|
+
if (Array.isArray(value)) {
|
|
243
|
+
blockJson[key] = value.map(convertExtension);
|
|
244
|
+
} else if (typeof value === "string") {
|
|
245
|
+
blockJson[key] = convertExtension(value);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
if (hasReactFastRefresh) {
|
|
252
|
+
// Prepends the file reference to the shared runtime chunk to every script type defined for the block.
|
|
253
|
+
const runtimePath = relative(
|
|
254
|
+
dirname(absoluteFrom),
|
|
255
|
+
fromProjectRoot(getProjectSourcePath() + sep + "runtime.js"),
|
|
256
|
+
);
|
|
257
|
+
const fields = getBlockJsonScriptFields(blockJson);
|
|
258
|
+
for (const [fieldName] of Object.entries(fields)) {
|
|
259
|
+
blockJson[fieldName] = [
|
|
260
|
+
`file:${runtimePath}`,
|
|
261
|
+
...(Array.isArray(blockJson[fieldName])
|
|
262
|
+
? blockJson[fieldName]
|
|
263
|
+
: [blockJson[fieldName]]),
|
|
264
|
+
];
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
return JSON.stringify(blockJson, null, 2);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
return content;
|
|
272
|
+
},
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
from: "**/*.php",
|
|
276
|
+
context: "src",
|
|
277
|
+
noErrorOnMissing: true,
|
|
278
|
+
filter: (filepath) => {
|
|
279
|
+
return (
|
|
280
|
+
process.env.WP_COPY_PHP_FILES_TO_DIST ||
|
|
281
|
+
PhpFilePathsPlugin.paths.includes(
|
|
282
|
+
realpathSync(filepath).replace(/\\/g, "/"),
|
|
283
|
+
)
|
|
284
|
+
);
|
|
285
|
+
},
|
|
286
|
+
},
|
|
287
|
+
],
|
|
288
|
+
options: {},
|
|
289
|
+
}),
|
|
290
|
+
new MiniCssExtractPlugin({
|
|
291
|
+
filename: isProduction ? "[name].min.css" : "[name].css",
|
|
292
|
+
}),
|
|
293
|
+
externals && new DependencyExtractionWebpackPlugin(),
|
|
294
|
+
],
|
|
295
|
+
};
|
package/lib/webpack.wp.config.js
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Modified WordPress Scripts Webpack Configuration
|
|
3
|
-
*
|
|
4
|
-
* @package CAWebPublishing
|
|
5
|
-
* @link https://webpack.js.org/configuration/
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* External Dependencies
|
|
10
|
-
*/
|
|
11
|
-
import baseConfig from '@wordpress/scripts/config/webpack.config.js';
|
|
12
|
-
import { getArgVal } from './args.js';
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Internal dependencies
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
// Wordpress ignores the webpack --mode flag
|
|
19
|
-
// if the flag is passed we use that mode
|
|
20
|
-
// otherwise use whatever Wordpress is using
|
|
21
|
-
let mode = getArgVal('mode') ? getArgVal('mode') : baseConfig.mode;
|
|
22
|
-
let isProduction = mode === 'production';
|
|
23
|
-
|
|
24
|
-
// Update some of the default WordPress webpack rules.
|
|
25
|
-
baseConfig.module.rules.forEach((rule, i) => {
|
|
26
|
-
const r = new RegExp(rule.test).toString();
|
|
27
|
-
|
|
28
|
-
switch(r){
|
|
29
|
-
// WordPress adds a hash to asset file names we remove that hash.
|
|
30
|
-
case new RegExp(/\.(bmp|png|jpe?g|gif|webp)$/i).toString():
|
|
31
|
-
rule.generator.filename = 'images/[name][ext]';
|
|
32
|
-
break;
|
|
33
|
-
case new RegExp(/\.(woff|woff2|eot|ttf|otf)$/i).toString():
|
|
34
|
-
rule.generator.filename = 'fonts/[name][ext]';
|
|
35
|
-
break;
|
|
36
|
-
case new RegExp(/\.svg$/).toString():
|
|
37
|
-
// we don't want SVG to be asset/inline otherwise the resource may not be available.
|
|
38
|
-
// the asset should be an asset/resource we move them to the fonts folder.
|
|
39
|
-
if( 'asset/inline' === rule.type ){
|
|
40
|
-
rule.type = 'asset/resource';
|
|
41
|
-
rule.generator = { filename: 'fonts/[name][ext]' };
|
|
42
|
-
|
|
43
|
-
delete rule.issuer;
|
|
44
|
-
}
|
|
45
|
-
break;
|
|
46
|
-
// silence deprecation warnings from sass
|
|
47
|
-
case new RegExp(/\.(sc|sa)ss$/).toString():
|
|
48
|
-
rule.use[rule.use.length-1].options.sassOptions = {
|
|
49
|
-
silenceDeprecations: ['global-builtin', 'import', 'color-functions', 'if-function']
|
|
50
|
-
};
|
|
51
|
-
break;
|
|
52
|
-
case new RegExp(/\.m?(j|t)sx?$/).toString():
|
|
53
|
-
// @since @wordpress/scripts@30.20.0 babel-loader is used for js and ts files
|
|
54
|
-
|
|
55
|
-
// Added the Transform class properties syntax plugin to the babel-loader.
|
|
56
|
-
// @see https://babeljs.io/docs/en/babel-plugin-proposal-class-properties
|
|
57
|
-
rule.use[0].options.plugins.push('@babel/plugin-proposal-class-properties');
|
|
58
|
-
|
|
59
|
-
// we add thread-loader before the babel-loader
|
|
60
|
-
// Spawns multiple processes and split work between them. This makes faster build.
|
|
61
|
-
// @see https://webpack.js.org/loaders/thread-loader/
|
|
62
|
-
rule.use = [{
|
|
63
|
-
loader: 'thread-loader',
|
|
64
|
-
options: {
|
|
65
|
-
workers: -1,
|
|
66
|
-
},
|
|
67
|
-
}].concat(rule.use);
|
|
68
|
-
|
|
69
|
-
break;
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
// Update some of the default WordPress plugins.
|
|
74
|
-
baseConfig.plugins = baseConfig.plugins.map((plugin, i) => {
|
|
75
|
-
const pluginName = plugin.constructor.name;
|
|
76
|
-
|
|
77
|
-
switch(pluginName){
|
|
78
|
-
case 'MiniCssExtractPlugin':
|
|
79
|
-
// we change the default naming of the CSS files
|
|
80
|
-
plugin.options.filename = isProduction ? '[name].min.css' : '[name].css';
|
|
81
|
-
break;
|
|
82
|
-
case 'RtlCssPlugin':
|
|
83
|
-
// we disable the RTL CSS generation
|
|
84
|
-
plugin = false;
|
|
85
|
-
break;
|
|
86
|
-
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
return plugin;
|
|
90
|
-
}).filter( Boolean );
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* we remove the WordPress devServer declaration since we can only have 1 when exporting multiple configurations
|
|
94
|
-
*
|
|
95
|
-
* @see https://github.com/webpack/webpack-cli/issues/2408#issuecomment-793052542
|
|
96
|
-
*/
|
|
97
|
-
delete baseConfig.devServer;
|
|
98
|
-
|
|
99
|
-
export default baseConfig;
|