Files
welcome/webpack.config.js
T
2026-10-24 09:52:38 -06:00

234 lines
8.8 KiB
JavaScript

/*
* Copyright (C) 2025 Comunicaciones Productivas Castro y Asociados, S. de R. L. de C.V. - All Rights Reserved
*
* This source code is protected under international copyright law.
* All rights reserved and protected by the copyright holders.
* This file is confidential and only available to authorized individuals with the permission of the copyright holders.
* If you encounter this file and do not have permission, please contact the copyright holders and delete this file.
*/
import {fileURLToPath} from 'node:url';
import path from 'path';
import CssMinimizerPlugin from 'css-minimizer-webpack-plugin';
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
import ChunksWebpackPlugin from 'chunks-webpack-plugin';
import webpack from 'webpack';
import autoprefixer from "autoprefixer";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// Groups node_modules into one cacheable chunk per top-level package, so that
// bumping one dependency does not invalidate the others' [contenthash].
const vendorChunkName = (module) => {
const matched = module.context?.match(/[\\/]node_modules[\\/]((?:@[^\\/]+[\\/])?[^\\/]+)/);
if (!matched) return 'vendor';
return `vendor-${matched[1].replace(/@/g, '').replace(/[\\/]/g, '-')}`;
};
export default(_env, argv) => {
const isProduction = argv.mode === 'production';
return {
entry: {
monitor: './src/main/resources/js/monitor.js',
'login-page': './src/main/resources/js/login-page.js',
download: './src/main/resources/js/download.js',
otp: './src/main/resources/js/otp.js',
enroll: './src/main/resources/js/enroll.js',
welcome: './src/main/resources/js/welcome.js',
done: './src/main/resources/js/done.js',
},
output: {
path: path.resolve(__dirname, './build/resources/main/static/dist'),
publicPath: '/dist/',
// thymepack resolves assets through chunks-manifest.json, so hashed
// filenames are transparent to the templates.
filename: isProduction ? '[name].[contenthash].js' : '[name].js',
chunkFilename: isProduction ? '[name].[contenthash].js' : '[name].js',
assetModuleFilename: isProduction ? '[name].[contenthash][ext]' : '[name][ext]',
clean: true
},
// Emit source maps as separate assets so browser DevTools can request
// them from /dist/ instead of relying on inline eval maps.
devtool: isProduction ? false : 'source-map',
mode: argv.mode,
cache: {
type: 'filesystem',
buildDependencies: {
config: [__filename]
}
},
optimization: {
minimize: isProduction,
// '...' keeps webpack's default JS minimizer (Terser) with its default options.
minimizer: [
'...',
new CssMinimizerPlugin({
minimizerOptions: {
preset: ['default', {
// Bootstrap uses relative-color calc() expressions that
// postcss-calc cannot parse yet. Preserve them for browsers.
calc: false
}]
}
})
],
splitChunks: {
chunks: 'all',
cacheGroups: {
defaultVendors: {
test: /[\\/]node_modules[\\/]/,
name: vendorChunkName,
reuseExistingChunk: true
}
}
}
},
performance: {
// preline's single 388 KiB module cannot be split; warning on every
// build adds no information. Revisit if the payload is trimmed.
hints: false
},
devServer: {
port: 8081,
compress: false,
hot: false,
liveReload: true,
static: {
directory: path.resolve(__dirname, './src/main/resources/static'),
publicPath: '/',
watch: true,
},
devMiddleware: {
writeToDisk: true,
},
watchFiles: [
'./src/main/resources/templates/*.html',
'./src/main/resources/templates/**/*.html',
'./src/main/resources/messages.properties',
'./src/main/resources/messages_*.properties',
'./src/main/resources/js/*.js',
'./src/main/resources/js/**/*.js',
'./src/main/resources/styles/**/*',
'./src/main/resources/static/**/*',
],
proxy: [
{
context: (pathname) => ![
'/dist/',
'/img/',
'/favicon/',
'/.well-known/',
'/site.webmanifest',
].some((path) => pathname.startsWith(path)),
target: "http://localhost:8080",
secure: false,
prependPath: false,
}
],
headers: {
'Cache-Control': 'no-store'
}
},
module: {
rules: [
{
// Consume Bootstrap's shipped maps before webpack creates
// its own bundle map. This prevents DevTools from trying
// to load Bootstrap's relative *.js.map files at /dist/.
test: /\.js$/,
enforce: 'pre',
include: path.resolve(__dirname, 'node_modules/bootstrap/js/dist'),
use: ['source-map-loader']
},
{ // Bootstrap
test: /\.scss$/,
use: [
isProduction ? MiniCssExtractPlugin.loader : 'style-loader',
{ loader: 'css-loader' },
{ loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [
autoprefixer,
// ...(isProduction ? [purgeUnusedCss] : [])
]
}
}
},
{ loader: 'sass-loader' }
]
},
{
test: /\.css$/,
use: [
isProduction ? MiniCssExtractPlugin.loader : 'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 1,
sourceMap: !isProduction
}
},
{
// @tailwindcss/postcss resolves @import/@source/@plugin and
// handles vendor prefixing through Lightning CSS.
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [
autoprefixer
]
},
sourceMap: !isProduction
}
},
{
loader: 'sass-loader'
}
]
},
{
test: /\.woff2?$/,
type: "asset/resource",
},
]
},
resolve: {
// @qr-platform/qr-code.js includes a Node-only dynamic Buffer import.
// Its browser runtime never reaches that path, but Webpack still resolves it.
fallback: {
buffer: false,
},
modules: [
path.resolve(__dirname, 'src/main/resources'),
'node_modules'
],
extensions: [ '...' ],
},
plugins: [
new webpack.ProvidePlugin({
// _: 'lodash',
}),
new ChunksWebpackPlugin({
generateChunksManifest: true,
generateChunksFiles: false
}),
...(isProduction
? [new MiniCssExtractPlugin({
filename: '[name].[contenthash].css',
chunkFilename: '[name].[contenthash].css'
})]
: []),
],
};
};