mirror of
https://github.com/Graylog2/graylog2-server.git
synced 2026-03-13 09:32:21 +08:00
* Making use of React Compiler for auto-memoization.
* Passing formik context into custom command.
* Adjusting test.
* Migrating parts of webpack config to TS.
* Revert "Migrating parts of webpack config to TS."
This reverts commit 4cd7d933e5.
* Improving type.
* Asserting type.
* Fixing `react-hooks/preserve-manual-memoization` by removing `useMemo`/`useCallback` where applicable.
* Updating lockfile.
* Fixing linter hint.
242 lines
6.2 KiB
JavaScript
242 lines
6.2 KiB
JavaScript
/*
|
|
* Copyright (C) 2020 Graylog, Inc.
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the Server Side Public License, version 1,
|
|
* as published by MongoDB, Inc.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* Server Side Public License for more details.
|
|
*
|
|
* You should have received a copy of the Server Side Public License
|
|
* along with this program. If not, see
|
|
* <http://www.mongodb.com/licensing/server-side-public-license>.
|
|
*/
|
|
const path = require('path');
|
|
|
|
const webpack = require('webpack');
|
|
const { merge } = require('webpack-merge');
|
|
const { EsbuildPlugin } = require('esbuild-loader');
|
|
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
|
|
const { CycloneDxWebpackPlugin } = require('@cyclonedx/webpack-plugin');
|
|
const { defineReactCompilerLoaderOption, reactCompilerLoader } = require('react-compiler-webpack');
|
|
|
|
const UniqueChunkIdPlugin = require('./UniqueChunkIdPlugin');
|
|
|
|
const disableTsc = process.env.disable_tsc === 'true';
|
|
|
|
const getCssLoaderOptions = (target) => {
|
|
// Development
|
|
if (target === 'start') {
|
|
return {
|
|
modules: {
|
|
localIdentName: '[name]__[local]--[hash:base64:5]',
|
|
mode: 'global',
|
|
},
|
|
};
|
|
}
|
|
|
|
return {
|
|
modules: {
|
|
mode: 'global',
|
|
},
|
|
};
|
|
};
|
|
|
|
const sortChunks = (c1, c2) => {
|
|
// Render the polyfill chunk first
|
|
if (c1 === 'polyfill') {
|
|
return -1;
|
|
}
|
|
|
|
if (c2 === 'polyfill') {
|
|
return 1;
|
|
}
|
|
|
|
if (c1 === 'app') {
|
|
return 1;
|
|
}
|
|
|
|
if (c2 === 'app') {
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
};
|
|
|
|
const esbuildLoader = (supportedBrowsers) => ({
|
|
loader: 'esbuild-loader',
|
|
options: {
|
|
target: supportedBrowsers,
|
|
},
|
|
});
|
|
|
|
const reactCompiler = {
|
|
loader: reactCompilerLoader,
|
|
options: defineReactCompilerLoaderOption({
|
|
target: '18',
|
|
}),
|
|
};
|
|
|
|
const rules = (target, supportedBrowsers) => [
|
|
{
|
|
test: /\.[jt]s(x)?$/,
|
|
use: [reactCompiler, esbuildLoader(supportedBrowsers)],
|
|
exclude: /node_modules\/(?!(@react-hook|uuid|@?react-leaflet|graylog-web-plugin))|\.node_cache/,
|
|
},
|
|
{
|
|
test: /\.(svg)(\?.+)?$/,
|
|
type: 'asset/resource',
|
|
},
|
|
{
|
|
test: /\.(woff(2)?|ttf|eot)(\?.+)?$/,
|
|
type: 'asset/resource',
|
|
},
|
|
{
|
|
test: /\.(png|gif|jpg|jpeg)(\?.+)?$/,
|
|
type: 'asset',
|
|
},
|
|
{
|
|
test: /\.css$/,
|
|
exclude: /(\.lazy|leaflet)\.css$/,
|
|
use: [
|
|
'style-loader',
|
|
{
|
|
loader: 'css-loader',
|
|
options: getCssLoaderOptions(target),
|
|
},
|
|
],
|
|
},
|
|
{
|
|
test: /(\.lazy|leaflet)\.css$/,
|
|
use: [
|
|
{ loader: 'style-loader', options: { injectType: 'lazyStyleTag' } },
|
|
{
|
|
loader: 'css-loader',
|
|
options: getCssLoaderOptions(target),
|
|
},
|
|
],
|
|
},
|
|
];
|
|
|
|
const config = (target, appPath, rootPath, webInterfaceRoot, supportedBrowsers) => {
|
|
const MANIFESTS_PATH = path.resolve(webInterfaceRoot, 'manifests');
|
|
const VENDOR_MANIFEST_PATH = path.resolve(MANIFESTS_PATH, 'vendor-manifest.json');
|
|
const BUILD_PATH = path.resolve(rootPath, 'target/web/build');
|
|
|
|
const baseConfig = {
|
|
output: {
|
|
path: BUILD_PATH,
|
|
filename: '[name].[chunkhash].js',
|
|
},
|
|
resolve: {
|
|
// you can now require('file') instead of require('file.coffee')
|
|
extensions: ['.js', '.json', '.jsx', '.ts', '.tsx'],
|
|
modules: [appPath, path.resolve(rootPath, 'node_modules'), path.resolve(rootPath, 'public')],
|
|
alias: {
|
|
'@graylog/server-api': path.resolve(webInterfaceRoot, 'target', 'api'),
|
|
},
|
|
},
|
|
module: {
|
|
rules: rules(target, supportedBrowsers),
|
|
},
|
|
resolveLoader: { modules: [path.join(webInterfaceRoot, 'node_modules')] },
|
|
devtool: 'source-map',
|
|
plugins: [
|
|
new webpack.ProvidePlugin({
|
|
Buffer: ['buffer', 'Buffer'],
|
|
}),
|
|
new UniqueChunkIdPlugin(),
|
|
new webpack.ids.HashedModuleIdsPlugin({
|
|
hashFunction: 'sha256',
|
|
hashDigestLength: 8,
|
|
}),
|
|
new webpack.DllReferencePlugin({ manifest: VENDOR_MANIFEST_PATH, context: webInterfaceRoot }),
|
|
new webpack.DefinePlugin({
|
|
FEATURES: JSON.stringify(process.env.FEATURES),
|
|
}),
|
|
],
|
|
};
|
|
|
|
if (target === 'start') {
|
|
return merge(baseConfig, {
|
|
mode: 'development',
|
|
devtool: 'cheap-module-source-map',
|
|
output: {
|
|
filename: '[name].js',
|
|
publicPath: '/',
|
|
},
|
|
plugins: [
|
|
new webpack.DefinePlugin({
|
|
DEVELOPMENT: true,
|
|
}),
|
|
...(disableTsc
|
|
? []
|
|
: [
|
|
new ForkTsCheckerWebpackPlugin({
|
|
typescript: {
|
|
memoryLimit: 4096,
|
|
},
|
|
}),
|
|
]),
|
|
],
|
|
});
|
|
}
|
|
|
|
if (target.startsWith('build')) {
|
|
return merge(baseConfig, {
|
|
mode: 'production',
|
|
optimization: {
|
|
splitChunks: {
|
|
chunks: 'all',
|
|
minSize: 20000,
|
|
minRemainingSize: 0,
|
|
minChunks: 1,
|
|
maxAsyncRequests: 30,
|
|
maxInitialRequests: 30,
|
|
enforceSizeThreshold: 50000,
|
|
usedExports: true,
|
|
cacheGroups: {
|
|
defaultVendors: {
|
|
test: /[\\/]node_modules[\\/]/,
|
|
priority: -10,
|
|
reuseExistingChunk: true,
|
|
},
|
|
default: {
|
|
minChunks: 2,
|
|
priority: -20,
|
|
reuseExistingChunk: true,
|
|
},
|
|
},
|
|
},
|
|
moduleIds: 'deterministic',
|
|
minimizer: [
|
|
new EsbuildPlugin({
|
|
target: supportedBrowsers,
|
|
}),
|
|
],
|
|
},
|
|
plugins: [
|
|
new webpack.DefinePlugin({
|
|
'process.env.NODE_ENV': JSON.stringify('production'),
|
|
}),
|
|
// Create SBOM files for graylog-server frontend dependencies.
|
|
new CycloneDxWebpackPlugin({
|
|
specVersion: '1.5',
|
|
rootComponentAutodetect: false,
|
|
rootComponentType: 'application',
|
|
rootComponentName: 'graylog-server',
|
|
outputLocation: '../cyclonedx-core',
|
|
includeWellknown: false,
|
|
}),
|
|
],
|
|
});
|
|
}
|
|
|
|
return baseConfig;
|
|
};
|
|
|
|
module.exports = { rules, config, sortChunks };
|