blob: 3f3b34c741c9640029439e8bf9e024a7f00774b1 [file] [log] [blame]
const CompressionPlugin = require('compression-webpack-plugin');
const webpack = require('webpack');
const LimitChunkCountPlugin = webpack.optimize.LimitChunkCountPlugin;
module.exports = {
css: {
loaderOptions: {
sass: {
additionalData: (() => {
const envName = process.env.VUE_APP_ENV_NAME;
const hasCustomStyles = process.env.CUSTOM_STYLES === 'true';
if (hasCustomStyles && envName !== undefined) {
return `
@import "@/assets/styles/bmc/helpers";
@import "@/env/assets/styles/_${envName}";
@import "@/assets/styles/bootstrap/_helpers";
`;
} else {
return `
@import "@/assets/styles/bmc/helpers";
@import "@/assets/styles/bootstrap/_helpers";
`;
}
})(), // immediately invoked function expression (IIFE)
},
scss: {
additionalData: (() => {
const envName = process.env.VUE_APP_ENV_NAME;
const hasCustomStyles = process.env.CUSTOM_STYLES === 'true';
if (hasCustomStyles && envName !== undefined) {
return `
@import "@/assets/styles/bmc/helpers";
@import "@/env/assets/styles/_${envName}";
@import "@/assets/styles/bootstrap/_helpers";
`;
} else {
return `
@import "@/assets/styles/bmc/helpers";
@import "@/assets/styles/bootstrap/_helpers";
`;
}
})(),
},
},
},
devServer: {
// Set DEV_HTTPS=true to run with HTTPS (helpful for testing secure-only features or with a signed cert)
// ref https://webpack.js.org/configuration/dev-server/#devserverserver
server:
process.env.DEV_HTTPS === 'true' ? { type: 'https' } : { type: 'http' },
proxy: {
'/': {
target: process.env.BASE_URL,
onProxyRes: (proxyRes) => {
delete proxyRes.headers['strict-transport-security'];
},
},
},
port: 8000,
},
productionSourceMap: false,
chainWebpack: (config) => {
config.module
.rule('vue')
.use('vue-svg-inline-loader')
.loader('vue-svg-inline-loader');
config.module
.rule('ico')
.test(/\.ico$/)
.use('file-loader')
.loader('file-loader')
.options({
name: '[name].[contenthash:8].[ext]',
});
config.plugins.delete('preload');
if (process.env.NODE_ENV === 'production') {
config.plugin('html').tap((options) => {
options[0].filename = 'index.[hash:8].html';
return options;
});
}
},
configureWebpack: (config) => {
config.plugins.push(
new LimitChunkCountPlugin({
maxChunks: 1,
}),
);
config.optimization.splitChunks = {
cacheGroups: {
default: false,
},
};
const crypto = require('crypto');
const crypto_orig_createHash = crypto.createHash;
crypto.createHash = (algorithm) =>
crypto_orig_createHash(algorithm == 'md4' ? 'sha256' : algorithm);
const envName = process.env.VUE_APP_ENV_NAME;
const hasCustomStore = process.env.CUSTOM_STORE === 'true';
const hasCustomRouter = process.env.CUSTOM_ROUTER === 'true';
const hasCustomAppNav = process.env.CUSTOM_APP_NAV === 'true';
if (envName !== undefined) {
if (hasCustomStore) {
// If env has custom store, resolve all store modules. Currently found
// in src/router/index.js src/store/api.js and src/main.js
config.resolve.alias['./store$'] = `@/env/store/${envName}.js`;
config.resolve.alias['../store$'] = `@/env/store/${envName}.js`;
}
if (hasCustomRouter) {
// If env has custom router, resolve routes in src/router/index.js
config.resolve.alias['./routes$'] = `@/env/router/${envName}.js`;
}
if (hasCustomAppNav) {
// If env has custom AppNavigation, resolve AppNavigationMixin module in src/components/AppNavigation/AppNavigation.vue
config.resolve.alias['./AppNavigationMixin$'] =
`@/env/components/AppNavigation/${envName}.js`;
}
}
if (process.env.NODE_ENV === 'production') {
config.plugins.push(
new CompressionPlugin({
deleteOriginalAssets: true,
}),
);
}
config.performance = {
hints: 'warning',
maxEntrypointSize: 512000,
maxAssetSize: 512000,
};
config.optimization.runtimeChunk = false;
// Define Vue 3 compile-time feature flags
// These flags must be explicitly defined to avoid Vue warnings and optimize bundle size
config.plugins.push(
new webpack.DefinePlugin({
// Enable Options API support (required - this codebase uses Options API extensively)
// Setting to true includes Options API in the bundle (~3kb gzipped)
// Cannot be disabled until full migration to Composition API
__VUE_OPTIONS_API__: JSON.stringify(true),
// Disable Vue Devtools in production builds for security and performance
// Devtools automatically enabled in development mode regardless of this flag
__VUE_PROD_DEVTOOLS__: JSON.stringify(false),
// Disable detailed hydration mismatch warnings in production
// This is a SPA (not SSR), so hydration warnings don't apply
// Reduces bundle size and eliminates unnecessary runtime checks
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: JSON.stringify(false),
// Expose session storage toggle to client code
'process.env.STORE_SESSION': JSON.stringify(
process.env.STORE_SESSION || '',
),
'process.env.VUE_APP_STORE_SESSION': JSON.stringify(
process.env.VUE_APP_STORE_SESSION || '',
),
}),
);
},
pluginOptions: {
i18n: {
localeDir: 'locales',
enableInSFC: true,
},
},
};