Skip to content

Instantly share code, notes, and snippets.

@anechunaev
Last active January 29, 2025 15:43
Show Gist options
  • Save anechunaev/95e077e36d13d53fd9fb473c2f1f56cf to your computer and use it in GitHub Desktop.
Save anechunaev/95e077e36d13d53fd9fb473c2f1f56cf to your computer and use it in GitHub Desktop.
Webpack configuration for a fast build of Node.js application. Does not bundle node_modules. Uses SWC to transform and minimize code.
const path = require("node:path");
const webpack = require("webpack");
const { SwcMinifyWebpackPlugin } = require('swc-minify-webpack-plugin');
module.exports = {
mode: "production",
target: "node22",
context: path.resolve(__dirname),
entry: {
server: path.resolve(__dirname, "../src/server.ts"),
},
output: {
filename: "[name].js",
chunkFilename: "[name].chunk.js",
publicPath: "/dist/",
path: path.resolve(__dirname, "../dist"),
library: {
name: 'app',
type: 'var',
},
strictModuleExceptionHandling: true,
},
resolve: {
extensions: [".js", ".mjs", ".ts", ".json"],
modules: [path.resolve(__dirname, "../src"), "node_modules"],
},
module: {
rules: [
{
test: /\.(m?j|t)s$/,
use: [
{
loader: "swc-loader",
},
],
exclude: /node_modules/,
},
],
},
plugins: [
new webpack.DefinePlugin({
"process.env": {
NODE_ENV: JSON.stringify("production"),
HOST: JSON.stringify(process.env.HOST),
PORT: JSON.stringify(process.env.PORT),
},
}),
new webpack.optimize.LimitChunkCountPlugin({
maxChunks: 1,
}),
],
optimization: {
chunkIds: "deterministic",
moduleIds: "deterministic",
minimize: true,
minimizer: [new SwcMinifyWebpackPlugin()],
mangleExports: true,
concatenateModules: true,
innerGraph: true,
sideEffects: true,
},
stats: {
logging: 'error'
},
infrastructureLogging: {
level: 'error'
},
node: false,
externalsPresets: { node: true },
externals: [
function externals(...args) {
const pkg = require(path.resolve(__dirname, '../package.json'));
const nodeModules = [
...Object.keys(pkg.dependencies ?? {}),
...Object.keys(pkg.devDependencies ?? {}),
...Object.keys(pkg.peerDependencies ?? {}),
...Object.keys(pkg.optionalDependencies ?? {}),
];
const scopedModuleRegex = new RegExp(
'@[a-zA-Z0-9][\\w-.]+/[a-zA-Z0-9][\\w-.]+([a-zA-Z0-9./]+)?',
'g'
);
const [arg1, arg2, arg3] = args;
let request = arg2;
let callback = arg3;
// Webpack 5
if (arg1 && arg1.context && arg1.request) {
request = arg1.request;
callback = arg2;
}
let moduleName = '';
if (scopedModuleRegex.test(request)) {
scopedModuleRegex.lastIndex = 0;
moduleName = request.split('/', 2).join('/');
} else {
moduleName = request.split('/')[0];
}
if (nodeModules && nodeModules.indexOf(moduleName) !== -1) {
return callback(null, 'commonjs' + ' ' + request);
}
callback();
}
]
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment