mirror of
https://github.com/zoriya/flood.git
synced 2025-12-06 07:16:18 +00:00
server: create production build with webpack directly
This commit is contained in:
@@ -118,7 +118,7 @@ module.exports = {
|
||||
// We don't currently advertise code splitting but Webpack supports it.
|
||||
filename: 'static/js/[name].[chunkhash:8].js',
|
||||
chunkFilename: 'static/js/[name].[chunkhash:8].chunk.js',
|
||||
assetModuleFilename: 'static/media/[name].[hash:8].[ext]',
|
||||
assetModuleFilename: 'static/media/[name].[hash:8][ext]',
|
||||
// Point sourcemap entries to original disk location (format as URL on Windows)
|
||||
devtoolModuleFilenameTemplate: (info) => path.relative(paths.appSrc, info.absoluteResourcePath).replace(/\\/g, '/'),
|
||||
},
|
||||
@@ -147,7 +147,7 @@ module.exports = {
|
||||
new webpack.optimize.MinChunkSizePlugin({
|
||||
minChunkSize: 10000,
|
||||
}),
|
||||
new WebpackBar(),
|
||||
new WebpackBar({name: 'client'}),
|
||||
],
|
||||
optimization: {
|
||||
minimize: true,
|
||||
|
||||
119
package-lock.json
generated
119
package-lock.json
generated
@@ -65,7 +65,7 @@
|
||||
"@types/tar-fs": "^2.0.1",
|
||||
"@typescript-eslint/eslint-plugin": "^5.4.0",
|
||||
"@typescript-eslint/parser": "^5.4.0",
|
||||
"@vercel/ncc": "^0.32.0",
|
||||
"@vercel/webpack-asset-relocator-loader": "^1.7.0",
|
||||
"autoprefixer": "^10.4.0",
|
||||
"axios": "^0.24.0",
|
||||
"axios-mock-adapter": "^1.20.0",
|
||||
@@ -154,6 +154,7 @@
|
||||
"terser-webpack-plugin": "^5.2.5",
|
||||
"tldts": "^5.7.53",
|
||||
"ts-jest": "^27.0.7",
|
||||
"ts-loader": "^9.2.6",
|
||||
"ts-node-dev": "^1.1.8",
|
||||
"tsconfig-paths": "^3.12.0",
|
||||
"typed-emitter": "^1.4.0",
|
||||
@@ -4489,14 +4490,11 @@
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@vercel/ncc": {
|
||||
"version": "0.32.0",
|
||||
"resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.32.0.tgz",
|
||||
"integrity": "sha512-S/SxTHHTbBQSOutpgnqEn+LyTfZcq9xMRAnzY05HpGVjxjmfmvg6SWZZkbW/GJIFznMmHGeGOrI1MEBD7efIkA==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"ncc": "dist/ncc/cli.js"
|
||||
}
|
||||
"node_modules/@vercel/webpack-asset-relocator-loader": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@vercel/webpack-asset-relocator-loader/-/webpack-asset-relocator-loader-1.7.0.tgz",
|
||||
"integrity": "sha512-1Dy3BdOliDwxA7VZSIg55E1d/us2KvsCQOZV25fgufG//CsnZBGiSAL7qewTQf7YVHH0A9PHgzwMmKIZ8aFYVw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@webassemblyjs/ast": {
|
||||
"version": "1.11.1",
|
||||
@@ -17752,6 +17750,62 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/ts-loader": {
|
||||
"version": "9.2.6",
|
||||
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.2.6.tgz",
|
||||
"integrity": "sha512-QMTC4UFzHmu9wU2VHZEmWWE9cUajjfcdcws+Gh7FhiO+Dy0RnR1bNz0YCHqhI0yRowCE9arVnNxYHqELOy9Hjw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"chalk": "^4.1.0",
|
||||
"enhanced-resolve": "^5.0.0",
|
||||
"micromatch": "^4.0.0",
|
||||
"semver": "^7.3.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "*",
|
||||
"webpack": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ts-loader/node_modules/enhanced-resolve": {
|
||||
"version": "5.8.3",
|
||||
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz",
|
||||
"integrity": "sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.2.4",
|
||||
"tapable": "^2.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ts-loader/node_modules/semver": {
|
||||
"version": "7.3.5",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
|
||||
"integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"lru-cache": "^6.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/ts-loader/node_modules/tapable": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
|
||||
"integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/ts-node": {
|
||||
"version": "9.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz",
|
||||
@@ -22271,10 +22325,10 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"@vercel/ncc": {
|
||||
"version": "0.32.0",
|
||||
"resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.32.0.tgz",
|
||||
"integrity": "sha512-S/SxTHHTbBQSOutpgnqEn+LyTfZcq9xMRAnzY05HpGVjxjmfmvg6SWZZkbW/GJIFznMmHGeGOrI1MEBD7efIkA==",
|
||||
"@vercel/webpack-asset-relocator-loader": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@vercel/webpack-asset-relocator-loader/-/webpack-asset-relocator-loader-1.7.0.tgz",
|
||||
"integrity": "sha512-1Dy3BdOliDwxA7VZSIg55E1d/us2KvsCQOZV25fgufG//CsnZBGiSAL7qewTQf7YVHH0A9PHgzwMmKIZ8aFYVw==",
|
||||
"dev": true
|
||||
},
|
||||
"@webassemblyjs/ast": {
|
||||
@@ -32377,6 +32431,45 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"ts-loader": {
|
||||
"version": "9.2.6",
|
||||
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.2.6.tgz",
|
||||
"integrity": "sha512-QMTC4UFzHmu9wU2VHZEmWWE9cUajjfcdcws+Gh7FhiO+Dy0RnR1bNz0YCHqhI0yRowCE9arVnNxYHqELOy9Hjw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"chalk": "^4.1.0",
|
||||
"enhanced-resolve": "^5.0.0",
|
||||
"micromatch": "^4.0.0",
|
||||
"semver": "^7.3.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"enhanced-resolve": {
|
||||
"version": "5.8.3",
|
||||
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz",
|
||||
"integrity": "sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"graceful-fs": "^4.2.4",
|
||||
"tapable": "^2.2.0"
|
||||
}
|
||||
},
|
||||
"semver": {
|
||||
"version": "7.3.5",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
|
||||
"integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lru-cache": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"tapable": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
|
||||
"integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"ts-node": {
|
||||
"version": "9.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz",
|
||||
|
||||
@@ -48,9 +48,7 @@
|
||||
]
|
||||
},
|
||||
"scripts": {
|
||||
"build": "npm run build-assets && npm run build-ts",
|
||||
"build-assets": "node client/scripts/build.js",
|
||||
"build-ts": "ncc build server/bin/start.ts -m -t -e geoip-country",
|
||||
"build": "node scripts/build.js",
|
||||
"build-pkg": "rm -rf dist && npm run build && pkg . --out-path dist-pkg",
|
||||
"format-source": "prettier -w .",
|
||||
"check-source-formatting": "prettier -c .",
|
||||
@@ -116,7 +114,7 @@
|
||||
"@types/tar-fs": "^2.0.1",
|
||||
"@typescript-eslint/eslint-plugin": "^5.4.0",
|
||||
"@typescript-eslint/parser": "^5.4.0",
|
||||
"@vercel/ncc": "^0.32.0",
|
||||
"@vercel/webpack-asset-relocator-loader": "^1.7.0",
|
||||
"autoprefixer": "^10.4.0",
|
||||
"axios": "^0.24.0",
|
||||
"axios-mock-adapter": "^1.20.0",
|
||||
@@ -205,6 +203,7 @@
|
||||
"terser-webpack-plugin": "^5.2.5",
|
||||
"tldts": "^5.7.53",
|
||||
"ts-jest": "^27.0.7",
|
||||
"ts-loader": "^9.2.6",
|
||||
"ts-node-dev": "^1.1.8",
|
||||
"tsconfig-paths": "^3.12.0",
|
||||
"typed-emitter": "^1.4.0",
|
||||
|
||||
@@ -14,8 +14,9 @@ const fs = require('fs-extra');
|
||||
const webpack = require('webpack');
|
||||
const checkRequiredFiles = require('react-dev-utils/checkRequiredFiles');
|
||||
const FileSizeReporter = require('react-dev-utils/FileSizeReporter');
|
||||
const paths = require('../../shared/config/paths');
|
||||
const config = require('../config/webpack.config.prod');
|
||||
const paths = require('../shared/config/paths');
|
||||
const clientConfig = require('../client/config/webpack.config.prod');
|
||||
const serverConfig = require('../server/config/webpack.config.prod');
|
||||
|
||||
const {measureFileSizesBeforeBuild, printFileSizesAfterBuild} = FileSizeReporter;
|
||||
|
||||
@@ -39,7 +40,7 @@ const copyPublicFolder = () => {
|
||||
const build = (previousFileSizes) => {
|
||||
console.log('Creating an optimized production build...');
|
||||
|
||||
const compiler = webpack(config);
|
||||
const compiler = webpack([clientConfig, serverConfig]);
|
||||
return new Promise((resolve, reject) => {
|
||||
compiler.run((err, stats) => {
|
||||
if (err) {
|
||||
@@ -60,7 +61,7 @@ measureFileSizesBeforeBuild(paths.appBuild)
|
||||
.then((previousFileSizes) => {
|
||||
// Remove all content but keep the directory so that
|
||||
// if you're in it, you don't end up in Trash
|
||||
fs.emptyDirSync(paths.appBuild);
|
||||
fs.emptyDirSync(paths.dist);
|
||||
// Merge with the public folder
|
||||
copyPublicFolder();
|
||||
// Start the webpack build
|
||||
@@ -68,25 +69,20 @@ measureFileSizesBeforeBuild(paths.appBuild)
|
||||
})
|
||||
.then(
|
||||
({stats, previousFileSizes}) => {
|
||||
if (stats.hasErrors()) {
|
||||
stats.compilation.errors.forEach((err) => {
|
||||
console.error(err);
|
||||
});
|
||||
console.log(
|
||||
stats.toString({
|
||||
chunks: false,
|
||||
colors: true,
|
||||
}),
|
||||
);
|
||||
|
||||
if (stats.hasErrors()) {
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (stats.hasWarnings()) {
|
||||
console.log(chalk.yellow('Compiled with warnings.\n'));
|
||||
|
||||
stats.compilation.warnings.forEach((warning) => {
|
||||
console.warn(warning);
|
||||
});
|
||||
}
|
||||
|
||||
console.log('File sizes after gzip:\n');
|
||||
console.log('\nClient file sizes after gzip:\n');
|
||||
printFileSizesAfterBuild(
|
||||
stats,
|
||||
stats.stats[0],
|
||||
previousFileSizes,
|
||||
paths.appBuild,
|
||||
WARN_AFTER_BUNDLE_GZIP_SIZE,
|
||||
@@ -5,10 +5,7 @@ import chalk from 'chalk';
|
||||
import enforcePrerequisites from './enforce-prerequisites';
|
||||
import migrateData from './migrations/run';
|
||||
|
||||
if (process.env.NODE_ENV !== 'development') {
|
||||
// Use production mode by default
|
||||
process.env.NODE_ENV = 'production';
|
||||
|
||||
if (process.env.NODE_ENV == 'production') {
|
||||
// Catch unhandled rejections and exceptions
|
||||
// Traces are pretty useless with minimized production codes
|
||||
// This avoids printing a large section of junk
|
||||
|
||||
73
server/config/webpack.config.prod.js
Normal file
73
server/config/webpack.config.prod.js
Normal file
@@ -0,0 +1,73 @@
|
||||
const path = require('path');
|
||||
const TerserPlugin = require('terser-webpack-plugin');
|
||||
const WebpackBar = require('webpackbar');
|
||||
|
||||
const paths = require('../../shared/config/paths');
|
||||
|
||||
// Assert this just to be safe.
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
throw new Error('Production builds must have NODE_ENV=production.');
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
mode: 'production',
|
||||
entry: path.resolve(__dirname, '../bin/start.ts'),
|
||||
externals: {
|
||||
'geoip-country': 'node-commonjs geoip-country',
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.cjs', '.mjs', '.js', '.ts', '.json'],
|
||||
alias: {
|
||||
'@server': path.resolve(__dirname, '..'),
|
||||
'@shared': path.resolve(__dirname, '../../shared'),
|
||||
},
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.ts$/,
|
||||
loader: 'ts-loader',
|
||||
exclude: /node_modules/,
|
||||
options: {
|
||||
context: path.resolve(__dirname, '..'),
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.m?js$/,
|
||||
parser: {amd: false},
|
||||
use: {
|
||||
loader: '@vercel/webpack-asset-relocator-loader',
|
||||
options: {
|
||||
outputAssetBase: 'data',
|
||||
production: true, // optional, default is undefined
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
output: {
|
||||
path: paths.dist,
|
||||
filename: 'index.js',
|
||||
libraryTarget: 'commonjs2',
|
||||
},
|
||||
optimization: {
|
||||
minimize: true,
|
||||
minimizer: [
|
||||
new TerserPlugin({
|
||||
terserOptions: {
|
||||
output: {
|
||||
comments: false,
|
||||
},
|
||||
},
|
||||
extractComments: false,
|
||||
}),
|
||||
],
|
||||
},
|
||||
plugins: [new WebpackBar({name: 'server'})],
|
||||
target: 'node',
|
||||
ignoreWarnings: [
|
||||
{
|
||||
module: /node_modules\/yargs/,
|
||||
},
|
||||
],
|
||||
};
|
||||
5
shared/config/paths.d.ts
vendored
5
shared/config/paths.d.ts
vendored
@@ -4,11 +4,8 @@ declare const PATHS: {
|
||||
appPublic: string;
|
||||
appHtml: string;
|
||||
appIndex: string;
|
||||
appPackageJson: string;
|
||||
appSrc: string;
|
||||
clientSrc: string;
|
||||
testsSetup: string;
|
||||
appNodeModules: string;
|
||||
dist: string;
|
||||
};
|
||||
|
||||
export = PATHS;
|
||||
|
||||
@@ -31,11 +31,8 @@ const PATHS = {
|
||||
appPublic: resolveApp('client/src/public/'),
|
||||
appHtml: resolveApp('client/src/index.html'),
|
||||
appIndex: resolveApp('client/src/javascript/app.tsx'),
|
||||
appPackageJson: resolveApp('package.json'),
|
||||
appSrc: resolveApp('./'),
|
||||
clientSrc: resolveApp('client/src'),
|
||||
testsSetup: resolveApp('tests/setupTests.js'),
|
||||
appNodeModules: resolveApp('node_modules'),
|
||||
dist: resolveApp('dist'),
|
||||
};
|
||||
|
||||
module.exports = PATHS;
|
||||
|
||||
Reference in New Issue
Block a user