-
Notifications
You must be signed in to change notification settings - Fork 5
/
webpack.config.js
143 lines (136 loc) · 4.58 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
require('dotenv').config();
const fs = require('fs').promises; // Use promises for async operations (not the default)
const path = require('path');
const webpack = require('webpack');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CopyPlugin = require('copy-webpack-plugin');
const generateRevManifestPlugin = require('./scripts/webpack/GenerateRevManifestPlugin');
const outputDir = path.resolve(__dirname, 'public', 'dist');
// Async delete any directories passed in and wait for all deletions to complete
async function cleanDirectories(dirs) {
const deletePromises = dirs.map(async (dir) => {
const dirPath = path.resolve(outputDir, dir);
try {
const stat = await fs.stat(dirPath);
if (stat.isDirectory()) {
await fs.rm(dirPath, { recursive: true, force: true });
console.log(`Deleted directory: ${dirPath}`);
}
} catch (err) {
// n.b. ENOENT is expected if the directory doesn't exist
if (err.code !== 'ENOENT') {
console.error(`Failed to delete ${dirPath}:`, err);
}
}
});
await Promise.all(deletePromises);
}
// Use async function to trigger webpack to wait for the promise to resolve
module.exports = async () => {
// Clean scripts and styles directories before the build process starts
await cleanDirectories(['scripts', 'styles', 'images']);
// Define if the environment is production
const isProd = process.env.NODE_ENV === 'production';
const isCI = process.env.CI === '1'; // Set in GitHub Action
// Use content hash and generate manifest in production or when explicitly set
const useContentHash = process.env.USE_COMPILED_REVASSETS === 'true' || isProd;
// Resolve implicit promise with the Webpack configuration object
return {
mode: isProd ? 'production' : 'development',
entry: {
app: ['./frontend/scss/app.scss', './frontend/js/app.js'],
blocks3D: ['./frontend/js/blocks3D.js'],
blocks360: ['./frontend/js/blocks360.js'],
collectionSearch: ['./frontend/js/collectionSearch.js'],
head: ['./frontend/js/head.js'],
interactiveFeatures: ['./frontend/js/interactiveFeatures.js'],
layeredImageViewer: ['./frontend/js/layeredImageViewer.js'],
mirador: ['./frontend/js/mirador.js'],
myMuseumTourBuilder: ['./frontend/js/myMuseumTourBuilder.js'],
recaptcha: ['./frontend/js/recaptcha.js'],
videojs: ['./frontend/js/videojs.js'],
virtualTour: ['./frontend/js/virtualTour.js'],
html4css: ['./frontend/scss/html4css.scss'],
'mirador-kiosk': ['./frontend/scss/mirador-kiosk.scss'],
'my-museum-tour-pdf': ['./frontend/scss/my-museum-tour-pdf.scss'],
print: ['./frontend/scss/print.scss'],
setup: ['./frontend/scss/setup.scss'],
},
output: {
filename: `./scripts/[name]${useContentHash ? '-[contenthash]' : ''}.js`,
path: outputDir,
publicPath: '/dist/',
},
devtool: 'source-map',
optimization: {
minimize: isProd && !isCI,
},
resolve: {
extensions: ['.js', '.jsx', '.scss'],
fallback: {
url: false,
},
},
plugins: [
// Ignore unused libraries if CI is detected
new webpack.IgnorePlugin({
resourceRegExp: /@blueprintjs\/(core|icons)/,
}),
...(isCI
? [
new webpack.IgnorePlugin({
resourceRegExp: /closer-look/,
}),
]
: []),
new MiniCssExtractPlugin({
filename: `styles/[name]${useContentHash ? '-[contenthash]' : ''}.css`,
}),
new CopyPlugin({
patterns: [
{
from: 'frontend/images/**/*',
to: `images/[name]${useContentHash ? '-[contenthash]' : ''}[ext]`,
},
],
}),
// Only generate manifest if contentHashes are used
...(useContentHash
? [
new generateRevManifestPlugin({
manifestPath: path.resolve(outputDir, 'rev-manifest.json'),
}),
] : []
)
],
module: {
rules: [
// Transpile JavaScript files using Babel
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: ['babel-loader'],
},
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
url: false,
sourceMap: true,
},
},
{
loader: 'sass-loader',
options: {
sourceMap: true,
},
},
],
},
],
},
};
};