forked from jesec/flood
-
Notifications
You must be signed in to change notification settings - Fork 1
/
build.js
110 lines (97 loc) · 3.22 KB
/
build.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
// Do this as the first thing so that any code reading it knows the right env.
process.env.BABEL_ENV = 'production';
process.env.NODE_ENV = 'production';
// Makes the script crash on unhandled rejections instead of silently
// ignoring them. In the future, promise rejections that are not handled will
// terminate the Node.js process with a non-zero exit code.
process.on('unhandledRejection', (err) => {
throw err;
});
const path = require('node:path');
const esbuild = require('esbuild');
const chalk = require('chalk');
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 clientConfig = require('../client/config/webpack.config.prod');
const {measureFileSizesBeforeBuild, printFileSizesAfterBuild} = FileSizeReporter;
// These sizes are pretty large. We'll warn for bundles exceeding them.
const WARN_AFTER_BUNDLE_GZIP_SIZE = 512 * 1024;
const WARN_AFTER_CHUNK_GZIP_SIZE = 1024 * 1024;
// Warn and crash if required files are missing
if (!checkRequiredFiles([paths.appHtml, paths.appIndex])) {
process.exit(1);
}
const copyPublicFolder = () => {
fs.copySync(paths.appPublic, paths.appBuild, {
dereference: true,
filter: (file) => file !== paths.appHtml,
});
};
// Create the production build and print the deployment instructions.
const build = async (previousFileSizes) => {
console.log('Creating an optimized production build...');
console.log('building server...');
await esbuild.build({
entryPoints: [path.resolve(__dirname, '..', 'server/bin/start.ts')],
outfile: path.resolve(__dirname, '..', 'dist/index.js'),
platform: 'node',
target: 'node12',
bundle: true,
external: ['geoip-country'],
sourcemap: 'inline',
});
console.log('building client...');
const compiler = webpack([clientConfig]);
return new Promise((resolve, reject) => {
compiler.run((err, stats) => {
if (err) {
return reject(err);
}
return resolve({
stats,
previousFileSizes,
});
});
});
};
// First, read the current file sizes in build directory.
// This lets us display how much they changed later.
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.dist);
// Merge with the public folder
copyPublicFolder();
// Start the webpack build
return build(previousFileSizes);
})
.then(
({stats, previousFileSizes}) => {
console.log(
stats.toString({
chunks: false,
colors: true,
}),
);
if (stats.hasErrors()) {
process.exit(1);
}
console.log('\nClient file sizes after gzip:\n');
printFileSizesAfterBuild(
stats.stats[0],
previousFileSizes,
paths.appBuild,
WARN_AFTER_BUNDLE_GZIP_SIZE,
WARN_AFTER_CHUNK_GZIP_SIZE,
);
},
(err) => {
console.log(chalk.red('Failed to compile.\n'));
console.log(`${err.message || err}\n`);
process.exit(1);
},
);