-
Notifications
You must be signed in to change notification settings - Fork 0
/
webpack.config.js
217 lines (198 loc) · 6.42 KB
/
webpack.config.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
const glob = require('glob');
const path = require('path');
const defaultConfig = require('@wordpress/scripts/config/webpack.config');
const { mode } = defaultConfig;
const BrowserSyncPlugin = require('browser-sync-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin'); // eslint-disable-line
const MiniCSSExtractPlugin = require('mini-css-extract-plugin'); // eslint-disable-line
const RemoveEmptyScriptsPlugin = require('webpack-remove-empty-scripts');
// Config settings.
const settings = require(path.resolve(process.cwd(), './webpack.settings.js'));
// Get all assets automatically.
const generateAutomatically = settings.generateAutomatically
? settings.generateAutomatically
: {};
// Generate array of all assets.
const automaticAssets = glob.sync(
`${generateAutomatically.baseFolder}${generateAutomatically.blob}`,
{
ignore: generateAutomatically.ignore,
}
);
// Create entry object from automaticAssets array.
const automaticEntries = automaticAssets.reduce((acc, entryPath) => {
// Get only filename. There is probably easier way.
const entryNew = entryPath
.substring(entryPath.lastIndexOf('/') + 1)
.replace('.js', '')
.replace('.scss', '');
// Start adding as entry.
acc[entryNew] = entryPath;
return acc;
}, {});
// Is production.
const isProduction = mode === 'production';
// Extra plugins.
const extraPlugins = [
// During rebuilds, all webpack assets that are not used anymore will be
// removed automatically. There is an exception added in watch mode for
// fonts and images. It is a known limitation:
// https://github.com/johnagan/clean-webpack-plugin/issues/159
new CleanWebpackPlugin({
cleanAfterEveryBuildPatterns: ['!fonts/**', '!images/**'],
cleanStaleWebpackAssets: false,
}),
new RemoveEmptyScriptsPlugin(),
// MiniCSSExtractPlugin to extract the CSS thats gets imported into JavaScript.
new MiniCSSExtractPlugin({ filename: '[name].css' }),
new BrowserSyncPlugin(settings.browserSyncSettings, {
injectCss: true,
reload: false,
}),
];
// Plugins.
const pluginsConfig = [...extraPlugins];
// Front-end related externals.
// --webpack-no-externals flag is used in package.json to disable Dependency Extraction Webpack Plugin.
const externalConfig = {
jquery: 'jQuery',
};
// Externals for blocks.
const blocksExternalConfig = {
// Utilize notable WordPress bundled scripts via globals.
jquery: 'jQuery',
tinymce: 'tinymce',
moment: 'moment',
react: 'React',
'react-dom': 'ReactDOM',
backbone: 'Backbone',
lodash: 'lodash',
};
// Resolve. `.js` extension added. Not sure if
const resolveConfig = {
alias: {
'lodash-es': 'lodash',
},
extensions: ['.ts', '.tsx', '.js'],
};
// CSS loaders.
const cssLoaders = [
{
loader: MiniCSSExtractPlugin.loader,
},
{
loader: require.resolve('css-loader'),
options: {
sourceMap: !isProduction,
modules: {
auto: true,
},
// We want url() CSS rules as they are, and not do anything about fonts etc.
url: false,
},
},
{
loader: require.resolve('postcss-loader'),
},
];
// Module config.
const moduleConfig = {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: [
{
loader: require.resolve('babel-loader'),
options: {
// Babel uses a directory within local node_modules
// by default. Use the environment variable option
// to enable more persistent caching.
cacheDirectory:
process.env.BABEL_CACHE_DIRECTORY || true,
babelrc: false,
configFile: false,
presets: [
require.resolve('@wordpress/babel-preset-default'),
],
},
},
],
},
{
test: /\.css$/,
use: cssLoaders,
},
{
test: /\.(sc|sa)ss$/,
use: [
...cssLoaders,
{
loader: require.resolve('sass-loader'),
options: {
sourceMap: !isProduction,
},
},
],
},
],
};
// Multiple array configuration from theme and plugin (or even more).
// @link: https://webpack.js.org/configuration/configuration-types/#exporting-multiple-configurations
const config = [];
/**
* Generate config.
*
* @param {string} name Name of the config.
* @param {Object} entries Object for entries.
* @param {string} output Output folder.
* @param {Object} externals Externals object for Webpack.
* @return {Object} Config object.
*/
function setConfig(name, entries, output, externals) {
return {
// Use default config from WP scripts.
// Overwrite needed config after that.
...defaultConfig,
name,
entry: entries,
output: {
path: path.resolve(process.cwd(), output),
},
resolve: resolveConfig,
externals,
module: moduleConfig,
plugins: pluginsConfig,
};
}
// Add project related config if they exists.
const projectEntries = settings.projectEntries ? settings.projectEntries : {};
if (Object.entries(projectEntries).length > 0) {
Object.entries(projectEntries).forEach(([name, value]) => {
// By default use externalConfig.
// But if externalType === 'blocks', use blocksExternalConfig
const external =
value.externalType === 'blocks'
? blocksExternalConfig
: externalConfig;
config.push(
setConfig(name, value.entries, value.outPutFolder, external)
);
});
}
// Add automatic entries config if they exists.
if (Object.entries(automaticEntries).length > 0) {
const externalAutomatic =
generateAutomatically.externalType === 'blocks'
? blocksExternalConfig
: externalConfig;
config.push(
setConfig(
generateAutomatically.name,
automaticEntries,
generateAutomatically.outPutFolder,
externalAutomatic
)
);
}
module.exports = config;