force-orange-2022/webpack/base.config.ts
ChatonDeAru 42c7410bfe
🚧 WIP
2024-03-23 18:53:24 +01:00

153 lines
4.9 KiB
TypeScript

import path from "path"
import webpack, { Configuration, WebpackPluginInstance, RuleSetUseItem } from "webpack"
import { WebpackManifestPlugin } from "webpack-manifest-plugin"
import TerserPlugin from "terser-webpack-plugin"
import MiniCssExtractPlugin from "mini-css-extract-plugin"
import ForkTsCheckerWebpackPlugin from "fork-ts-checker-webpack-plugin"
import LoadablePlugin from "@loadable/webpack-plugin"
import { BundleAnalyzerPlugin } from "webpack-bundle-analyzer"
export const isDev = process.env.NODE_ENV === "development"
const getStyleLoaders = (isWeb: boolean, isSass?: boolean) => {
let loaders: RuleSetUseItem[] = [
{
loader: "css-loader",
options: {
importLoaders: isSass ? 2 : 1,
modules: {
auto: true,
localIdentName: "[path][name]__[local]", // Don't use hash:base64, a bug makes it generate different hashes in the .js and the .css files
exportOnlyLocals: !isWeb,
},
},
},
{ loader: "postcss-loader" },
]
if (isWeb) loaders = [MiniCssExtractPlugin.loader, ...loaders]
if (isSass) loaders = [...loaders, { loader: "sass-loader" }]
return loaders
}
const getPlugins = (isWeb: boolean) => {
let plugins = [
new webpack.ProgressPlugin(),
new WebpackManifestPlugin({
fileName: path.resolve(process.cwd(), "public/webpack-assets.json"),
filter: (file) => file.isInitial,
}),
new LoadablePlugin({
writeToDisk: true,
filename: "../loadable-stats.json",
}),
// Setting global variables
new webpack.DefinePlugin({
SSR: !isWeb,
DEV: isDev,
REGISTER_DISCORD_COMMANDS: Boolean(process.env.REGISTER_DISCORD_COMMANDS),
API_URL: JSON.stringify(process.env.API_URL),
}),
]
if (isDev)
plugins = [
...plugins,
// Runs TypeScript type checker on a separate process
new ForkTsCheckerWebpackPlugin({
// (Required) Same as eslint command
eslint: { files: "./src/**/*.{js,jsx,ts,tsx}" },
}),
]
if (!isDev)
plugins = [
...plugins,
// Visualize size of webpack output files, see: https://github.com/webpack-contrib/webpack-bundle-analyzer
new BundleAnalyzerPlugin({
analyzerMode: process.env.NODE_ENV === "analyze" ? "server" : "disabled",
}),
]
return plugins
}
const config = (isWeb = false): Configuration => ({
mode: isDev ? "development" : "production",
stats: "minimal",
context: path.resolve(process.cwd()),
output: { clean: true },
optimization: {
minimizer: [
new TerserPlugin({
// See more options: https://github.com/webpack-contrib/terser-webpack-plugin#terseroptions
terserOptions: { compress: { drop_console: false } },
}),
],
},
plugins: getPlugins(isWeb) as WebpackPluginInstance[],
module: {
rules: [
{
test: /\.(t|j)sx?$/,
exclude: /node_modules/,
loader: "babel-loader",
options: {
caller: { target: isWeb ? "web" : "node" },
cacheDirectory: isDev,
},
},
{
test: /\.css$/,
use: getStyleLoaders(isWeb),
},
{
test: /\.(scss|sass)$/,
use: getStyleLoaders(isWeb, true),
},
{
test: /\.(woff2?|eot|ttf|otf)$/i,
type: "asset",
generator: { emit: isWeb },
},
{
test: /\.(png|svg|jpe?g|gif)$/i,
type: "asset",
generator: { emit: isWeb },
},
],
},
resolve: {
modules: ["src", "node_modules"],
extensions: [".ts", ".tsx", ".js", ".jsx", ".json"],
},
})
export function getClientEnvironment(allowedKeys: string[]): any {
const raw = Object.keys(process.env)
// Custom regex to allow only a certain category of variables available to the application
.filter((key) => allowedKeys.indexOf(key) >= 0)
.reduce(
(env: any, key: string) => {
env[key] = process.env[key]
return env
},
{
NODE_ENV: process.env.NODE_ENV || "development",
}
)
// Stringify all values so we can feed into Webpack DefinePlugin
const stringified = {
"process.env": Object.keys(raw).reduce((env: any, key: string) => {
env[key] = JSON.stringify(raw[key])
return env
}, {}),
}
return stringified
}
export default config