-
Notifications
You must be signed in to change notification settings - Fork 7
/
webpack.config.js
200 lines (185 loc) · 6.76 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
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const CopyPlugin = require('copy-webpack-plugin')
const TerserPlugin = require('terser-webpack-plugin')
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')
const CompressionWebpackPlugin = require('compression-webpack-plugin')
const config = require('./src/assets/config.json')
const BundleAnalyzerPlugin =
require('webpack-bundle-analyzer').BundleAnalyzerPlugin
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const exp = require('constants')
const webpack = require('webpack');
const { execSync } = require('child_process');
const ModuleFederationPlugin =
require('webpack').container.ModuleFederationPlugin
// Bundle dependencies as a separate ES moudule
const isProduction = process.env.NODE_ENV === 'production'
// Extract the common dependencies from the package.json file
const deps = require('./package.json').dependencies
// External Apps
// List of external app properties.
// This is used in both build and runtime to manage the external apps
const appConfig = require('./src/assets/apps.json')
const externalAppsConfig = {}
appConfig.forEach((app) => {
externalAppsConfig[app.name] = `${app.name}@${app.url}`
})
console.log('App config found:', appConfig)
console.log('These apps can be used in this build:', externalAppsConfig)
module.exports = {
// This app is only for web browsers
target: 'web',
mode: isProduction ? 'production' : 'development', // Set mode to production or development
entry: {
cyweb: path.resolve(__dirname, './src/index.tsx'),
},
devtool: isProduction ? false : 'inline-source-map',
stats: 'normal',
module: {
rules: [
// look for tsx files to transform into the bundle
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: [/node_modules/, /dist/, /apps/],
},
// look for css files to transform into the bundle
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, 'css-loader'],
},
// load all other assets using webpacks default loader
{
test: /\.(png|jpg|jpeg|gif|svg|ico)$/i,
type: 'asset/resource',
},
],
},
resolve: {
extensions: ['.tsx', '.ts', '.js', '.jsx'], // need .js and .jsx for dependency files
},
// use content hash for cache busting
output: {
filename: '[name].[contenthash].js',
path: path.resolve(__dirname, 'dist'),
clean: true,
publicPath: config.urlBaseName !== '' ? config.urlBaseName : '/',
// publicPath: 'auto', // Required to use module federation (? Need to double check)
},
// watch the dist file for changes when using the dev server
devServer: {
hot: true,
client: {
overlay: true,
},
static: path.resolve(__dirname, './dist'),
historyApiFallback: {
rewrites: [
{ from: /^\/$/, to: '/index.html' }, // default index route
{ from: /./, to: '/index.html' }, // all other routes
],
},
headers: {
'Access-Control-Allow-Origin': '*', // allow access from any origin
},
port: 5500,
},
plugins: [
new ModuleFederationPlugin({
name: 'cyweb',
filename: 'remoteEntry.js',
remotes: externalAppsConfig,
exposes: {
// Data models to be used by other apps
// './useDataStore': './src/components/AppManager/useDataStore.tsx',
'./CredentialStore': './src/store/CredentialStore.ts',
'./LayoutStore': './src/store/LayoutStore.ts',
'./MessageStore': './src/store/MessageStore.ts',
'./NetworkStore': './src/store/NetworkStore.ts',
'./NetworkSummaryStore': './src/store/NetworkSummaryStore.ts',
'./RendererStore': './src/store/RendererStore.ts',
'./UiStateStore': './src/store/UiStateStore.ts',
'./TableStore': './src/store/TableStore.ts',
'./ViewModelStore': './src/store/ViewModelStore.ts',
'./VisualStyleStore': './src/store/VisualStyleStore.ts',
'./WorkspaceStore': './src/store/WorkspaceStore.ts',
// Tasks
'./CreateNetwork': './src/task/CreateNetwork.tsx',
},
shared: {
react: { singleton: true, requiredVersion: deps.react },
'react-dom': { singleton: true, requiredVersion: deps['react-dom'] },
'@mui/material': {
singleton: true,
requiredVersion: deps['@mui/material'],
},
},
}),
// new BundleAnalyzerPlugin({
// analyzerMode: 'static',
// }),
new CopyPlugin({
patterns: [{ from: './silent-check-sso.html', to: '.' }],
}),
// generate css files from the found css files in the source
new MiniCssExtractPlugin({
filename: '[name].[contenthash].css',
}),
// generate html that points to the bundle with the updated hash
new HtmlWebpackPlugin({
template: './index.html',
favicon: './src/assets/favicon.ico',
}),
new CleanWebpackPlugin(),
// netlify requires a _redirects file in the root of the dist folder to work with react router
...(process.env.BUILD === 'netlify'
? [
new CopyPlugin({
patterns: [{ from: 'netlify/_redirects', to: '.' }],
}),
]
: []),
// ...(isProduction ? [] : [new ESLintPlugin({ extensions: ['ts', 'tsx'] })]),
...(isProduction ? [new CompressionWebpackPlugin()] : []),
new webpack.DefinePlugin({
// Inject Git commit and build date into process.env variables
'process.env.REACT_APP_GIT_COMMIT': JSON.stringify(execSync('git rev-parse --short HEAD').toString().trim()),
'process.env.REACT_APP_BUILD_DATE': JSON.stringify(execSync('git show -s --format=%cI HEAD').toString().trim()), // Use commit date instead of current date
}),
],
// split bundle into two chunks, node modules(vendor code) in one bundle and app source code in the other
// when source code changes, only the source code bundle will need to be updated, not the vendor code
optimization: {
minimize: isProduction, // Only minimize in production
minimizer: [
new TerserPlugin({
// Include your own code to apply the plugin.
include: /\/src/,
// Disable source maps for vendor code by excluding them
exclude: /\/node_modules/,
terserOptions: {
// your custom options for terser
compress: {
drop_console: true,
},
sourceMap: true, // Enable source map
},
extractComments: false, // remove comments from output
}),
new CssMinimizerPlugin(),
],
moduleIds: 'deterministic',
runtimeChunk: 'single',
splitChunks: {
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all',
},
},
},
},
}