OpenMetadata/openmetadata-ui/src/main/resources/ui/webpack.config.prod.js
Chirag Madlani 94e3b548bc
chore(ui): remove deprecated image-webpack-loader (#18923)
* remove gif support

* remove image-webpack-loader

* do not print file name to save build time
2024-12-04 23:21:33 +05:30

253 lines
6.9 KiB
JavaScript

/*
* Copyright 2022 Collate.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const CompressionPlugin = require('compression-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
const outputPath = path.join(__dirname, 'dist/assets');
const subPath = process.env.APP_SUB_PATH ?? '';
module.exports = {
cache: {
type: 'filesystem', // Use filesystem for cache
buildDependencies: {
config: [__filename], // Cache invalidation on config file changes
},
},
// Production mode
mode: 'production',
// Input configuration
entry: path.join(__dirname, 'src/index.tsx'),
// Output configuration
output: {
path: outputPath,
filename: '[name].[contenthash].js', // Use contenthash for unique filenames
chunkFilename: '[name].[contenthash].js', // Ensure unique chunk filenames
clean: true, // Clean the output directory before emit
publicPath: `${subPath ?? ''}/`,
},
// Loaders
module: {
rules: [
// .mjs files to be handled
{
test: /\.m?js/,
include: path.resolve(__dirname, 'node_modules/kleur'),
resolve: {
fullySpecified: false,
},
},
// .ts and .tsx files to be handled by ts-loader
{
test: /\.(ts|tsx)$/,
exclude: [/node_modules/, /dist/],
include: path.resolve(__dirname, 'src'),
use: [
{
loader: 'thread-loader',
options: {
workers: require('os').cpus().length - 1, // Use all available CPU cores minus one
},
},
{
loader: 'ts-loader',
options: {
configFile: 'tsconfig.json',
happyPackMode: true, // Enable faster builds with HappyPack compatibility
transpileOnly: true, // Speed up compilation in development mode
},
},
],
},
// .css files to be handled by style-loader & css-loader
{
test: /\.(css)$/,
use: ['style-loader', 'css-loader'],
},
// .less files to be handled by less-loader
{
test: /\.less$/,
use: [
'style-loader',
'css-loader',
'postcss-loader',
{
loader: 'less-loader',
options: {
lessOptions: {
javascriptEnabled: true,
},
},
},
],
},
// .svg files to be handled by @svgr/webpack
{
test: /\.svg$/,
use: ['@svgr/webpack', 'url-loader'],
include: path.resolve(__dirname, 'src'),
},
// Images to be handled by file-loader + image-webpack-loader
{
test: /\.(png|jpe?g)$/i,
use: [
{
loader: 'file-loader',
options: {
name: 'images/[name].[contenthash].[ext]', // Output file naming
outputPath: 'images/', // Directory in the output folder
},
},
],
},
],
},
// Module resolution
resolve: {
extensions: ['.ts', '.tsx', '.js', '.css', '.less', '.svg'],
fallback: {
https: require.resolve('https-browserify'),
fs: false,
'process/browser': require.resolve('process/browser'),
},
alias: {
process: 'process/browser',
Quill: path.resolve(__dirname, 'node_modules/quill'),
},
},
// Optimizations
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
parallel: true,
terserOptions: {
compress: {
drop_console: true, // Remove console logs for production
},
},
}),
],
splitChunks: {
chunks: 'all', // Split all types of chunks
maxSize: 240000, // Maximum size for chunks
cacheGroups: {
default: {
reuseExistingChunk: true, // Reuse existing chunks
priority: -10,
},
vendors: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all',
priority: -20,
},
},
},
runtimeChunk: 'single', // Separate runtime code into its own chunk
chunkIds: 'deterministic', // Use stable and unique chunk IDs
},
// Plugins
plugins: [
// Clean webpack output directory
new CleanWebpackPlugin(),
// Generate index.html from template
new HtmlWebpackPlugin({
favicon: path.join(__dirname, 'public/favicon.png'),
hash: true,
cache: false,
template: path.join(__dirname, 'public/index.html'),
scriptLoading: 'defer',
}),
// Copy favicon, logo, manifest, and other assets
new CopyWebpackPlugin({
patterns: [
{
from: path.join(__dirname, 'public/favicon.png'),
to: outputPath,
},
{
from: path.join(__dirname, 'public/favicons/favicon-16x16.png'),
to: outputPath,
},
{
from: path.join(__dirname, 'public/favicons/favicon-32x32.png'),
to: outputPath,
},
{
from: path.join(__dirname, 'public/logo192.png'),
to: outputPath,
},
{
from: path.join(__dirname, 'public/manifest.json'),
to: outputPath,
},
{
from: path.join(__dirname, 'public/swagger.html'),
to: outputPath,
},
{
from: path.join(__dirname, 'public/locales'),
to: outputPath,
},
{
from: path.join(__dirname, 'public/BronzeCertification.svg'),
to: outputPath,
},
{
from: path.join(__dirname, 'public/SilverCertification.svg'),
to: outputPath,
},
{
from: path.join(__dirname, 'public/GoldCertification.svg'),
to: outputPath,
},
],
}),
// Compress output files
new CompressionPlugin({
algorithm: 'gzip',
test: /\.(js|css|html|svg)$/,
}),
// Bundle analyzer (optional, for debugging)
new BundleAnalyzerPlugin({
analyzerMode: 'static', // Outputs an HTML report
openAnalyzer: false, // Set to true to open report automatically
}),
],
// Disable source maps for production
devtool: false,
};