frosty 0.0.147 → 0.0.149
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/package.json +2 -2
- package/packages/frosty-cli/scripts/bin/run.sh +4 -0
- package/packages/frosty-cli/src/server/env.ts +2 -0
- package/packages/frosty-cli/src/server/index.js +43 -27
- package/packages/frosty-cli/webpack.mjs +4 -3
- package/packages/frosty-cli/yarn.lock +3 -3
package/README.md
CHANGED
|
@@ -114,7 +114,7 @@ module.exports = {
|
|
|
114
114
|
client: { // (Optional) Client entry points
|
|
115
115
|
main: {
|
|
116
116
|
entry: 'src/app.js', // Path to client entry file
|
|
117
|
-
|
|
117
|
+
basepath: '/', // (Optional) URL base path for this entry
|
|
118
118
|
}
|
|
119
119
|
},
|
|
120
120
|
moduleSuffixes: { // (Optional) Custom module resolution suffixes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "frosty",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.149",
|
|
4
4
|
"main": "dist/index",
|
|
5
5
|
"module": "dist/index",
|
|
6
6
|
"types": "dist/index",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"@types/lodash": "^4.17.16",
|
|
38
38
|
"csstype": "^3.1.3",
|
|
39
39
|
"jsdom": "^27.0.0",
|
|
40
|
-
"lodash": ">=4.
|
|
40
|
+
"lodash": ">=4.18.1",
|
|
41
41
|
"myers.js": "^0.0.22",
|
|
42
42
|
"nextick": "^0.0.2",
|
|
43
43
|
"postcss": "^8.5.6",
|
|
@@ -43,6 +43,7 @@ print_usage() {
|
|
|
43
43
|
echo " -b, --build-only Only build, do not run the server"
|
|
44
44
|
echo " -B, --no-build Skip build step"
|
|
45
45
|
echo " -p, --port <port> Specify port for the server (default: 8080)"
|
|
46
|
+
echo " -n, --num-workers <count> Specify number of worker processes"
|
|
46
47
|
echo " -c, --configuration <file> Specify configuration file to use (default: server.config.js)"
|
|
47
48
|
echo " -s, --src <dir> Specify source root directory"
|
|
48
49
|
echo " -o, --output <dir> Specify output directory for build artifacts"
|
|
@@ -53,6 +54,7 @@ print_usage() {
|
|
|
53
54
|
echo ""
|
|
54
55
|
echo "Examples:"
|
|
55
56
|
echo " frosty run app.js"
|
|
57
|
+
echo " frosty run -n 4 app.js"
|
|
56
58
|
}
|
|
57
59
|
|
|
58
60
|
POSITIONAL_ARGS=()
|
|
@@ -63,6 +65,7 @@ while [ $# -gt 0 ]; do
|
|
|
63
65
|
-b|--build-only) BUILD_ONLY=true; shift ;;
|
|
64
66
|
-B|--no-build) NO_BUILD=true; shift ;;
|
|
65
67
|
-p|--port) PORT="$2"; shift 2 ;;
|
|
68
|
+
-n|--num-workers) NUM_WORKERS="$2"; shift 2 ;;
|
|
66
69
|
-c|--configuration) CONFIG_FILE="$2"; shift 2 ;;
|
|
67
70
|
-s|--src) SRCROOT="$2"; shift 2 ;;
|
|
68
71
|
-o|--output) OUTPUT_DIR="$2"; shift 2 ;;
|
|
@@ -110,6 +113,7 @@ if [ "$NO_BUILD" != "true" ]; then
|
|
|
110
113
|
fi
|
|
111
114
|
[ -n "$INPUT_FILE" ] && BUILD_OPTS="$BUILD_OPTS --env INPUT_FILE="$INPUT_FILE""
|
|
112
115
|
[ -n "$SRCROOT" ] && BUILD_OPTS="$BUILD_OPTS --env SRCROOT="$SRCROOT""
|
|
116
|
+
[ -n "$NUM_WORKERS" ] && BUILD_OPTS="$BUILD_OPTS --env NUM_WORKERS="$NUM_WORKERS""
|
|
113
117
|
[ -n "$PORT" ] && BUILD_OPTS="$BUILD_OPTS --env PORT="$PORT""
|
|
114
118
|
if [ "$WATCH_MODE" = "true" ]; then
|
|
115
119
|
node "$FROSTY_CLI_ROOT/node_modules/webpack-cli/bin/cli.js" $BUILD_OPTS --watch &
|
|
@@ -24,5 +24,7 @@
|
|
|
24
24
|
//
|
|
25
25
|
|
|
26
26
|
import _ from 'lodash';
|
|
27
|
+
import { availableParallelism } from 'os';
|
|
27
28
|
|
|
28
29
|
export const PORT = process.env.PORT ? parseInt(process.env.PORT) : 8080;
|
|
30
|
+
export const NUM_WORKERS = process.env.NUM_WORKERS ? parseInt(process.env.NUM_WORKERS) : availableParallelism();
|
|
@@ -26,41 +26,57 @@
|
|
|
26
26
|
import _ from 'lodash';
|
|
27
27
|
import fs from 'fs';
|
|
28
28
|
import path from 'path';
|
|
29
|
+
import cluster from 'cluster';
|
|
29
30
|
import { Server } from '@o2ter/server-js';
|
|
30
31
|
import { FrostyRoute } from './route';
|
|
31
32
|
import * as __SERVER__ from '__SERVER__';
|
|
32
33
|
import * as __APPLICATIONS__ from '__APPLICATIONS__';
|
|
33
|
-
import { PORT } from './env';
|
|
34
|
+
import { PORT, NUM_WORKERS } from './env';
|
|
34
35
|
|
|
35
|
-
|
|
36
|
+
if (cluster.isPrimary && NUM_WORKERS > 1) {
|
|
37
|
+
console.log(`Primary ${process.pid} is running`);
|
|
36
38
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
if ('default' in __SERVER__) await __SERVER__.default(app, server_env);
|
|
41
|
-
|
|
42
|
-
for (const [name, { path: pathname }] of _.toPairs(__applications__)) {
|
|
43
|
-
const { default: App } = __APPLICATIONS__[name];
|
|
44
|
-
if (!_.isFunction(App)) {
|
|
45
|
-
throw new Error(
|
|
46
|
-
`Failed to load client app "${name}": default export is not a function.\n` +
|
|
47
|
-
`Please ensure "${name}" exports a valid Frosty component as its default export.`
|
|
48
|
-
);
|
|
39
|
+
// Fork workers.
|
|
40
|
+
for (let i = 0; i < NUM_WORKERS; i++) {
|
|
41
|
+
cluster.fork();
|
|
49
42
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
cssSrc: cssExists ? `/css/${name}_bundle.css` : undefined,
|
|
43
|
+
|
|
44
|
+
cluster.on('exit', (worker, code, signal) => {
|
|
45
|
+
console.log(`Worker ${worker.process.pid} died`);
|
|
54
46
|
});
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
47
|
+
|
|
48
|
+
} else {
|
|
49
|
+
|
|
50
|
+
const app = 'serverOptions' in __SERVER__ ? new Server(__SERVER__.serverOptions) : new Server;
|
|
51
|
+
|
|
52
|
+
app.use(Server.static(path.join(__dirname, 'public'), { cacheControl: true }));
|
|
53
|
+
|
|
54
|
+
const server_env = {};
|
|
55
|
+
if ('default' in __SERVER__) await __SERVER__.default(app, server_env);
|
|
56
|
+
|
|
57
|
+
for (const [name, { path: pathname }] of _.toPairs(__applications__)) {
|
|
58
|
+
const { default: App } = __APPLICATIONS__[name];
|
|
59
|
+
if (!_.isFunction(App)) {
|
|
60
|
+
throw new Error(
|
|
61
|
+
`Failed to load client app "${name}": default export is not a function.\n` +
|
|
62
|
+
`Please ensure "${name}" exports a valid Frosty component as its default export.`
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
const cssExists = fs.existsSync(path.join(__dirname, `public/css/${name}_bundle.css`));
|
|
66
|
+
const route = FrostyRoute(App, {
|
|
67
|
+
jsSrc: `/${name}_bundle.js`,
|
|
68
|
+
cssSrc: cssExists ? `/css/${name}_bundle.css` : undefined,
|
|
69
|
+
});
|
|
70
|
+
if (_.isEmpty(pathname) || pathname === '/') {
|
|
71
|
+
app.use(route);
|
|
72
|
+
} else {
|
|
73
|
+
app.use(pathname, route);
|
|
74
|
+
}
|
|
59
75
|
}
|
|
60
|
-
}
|
|
61
76
|
|
|
62
|
-
app.use((err, req, res, next) => {
|
|
63
|
-
|
|
64
|
-
});
|
|
77
|
+
app.use((err, req, res, next) => {
|
|
78
|
+
res.status(500).json(err instanceof Error ? { message: err.message } : err);
|
|
79
|
+
});
|
|
65
80
|
|
|
66
|
-
app.listen(PORT, () => console.info(`listening on port ${PORT}`));
|
|
81
|
+
app.listen(PORT, () => console.info(`Process ${process.pid} listening on port ${PORT}`));
|
|
82
|
+
}
|
|
@@ -42,6 +42,7 @@ export default async (env, argv) => {
|
|
|
42
42
|
CONFIG_FILE = 'server.config.js',
|
|
43
43
|
INPUT_FILE,
|
|
44
44
|
PORT = 8080,
|
|
45
|
+
NUM_WORKERS,
|
|
45
46
|
} = env;
|
|
46
47
|
|
|
47
48
|
const serverConfig = await (async () => {
|
|
@@ -200,7 +201,7 @@ export default async (env, argv) => {
|
|
|
200
201
|
const random = crypto.randomUUID();
|
|
201
202
|
const tempDir = fs.mkdtempSync(`${os.tmpdir()}${path.sep}`);
|
|
202
203
|
const applications = path.resolve(tempDir, `applications-${random}.js`);
|
|
203
|
-
const inputs = INPUT_FILE ? { main: { entry: path.join(process.cwd(), INPUT_FILE),
|
|
204
|
+
const inputs = INPUT_FILE ? { main: { entry: path.join(process.cwd(), INPUT_FILE), basepath: '/' } } : config.client;
|
|
204
205
|
|
|
205
206
|
fs.writeFileSync(applications, `
|
|
206
207
|
${_.map(inputs, ({ entry }, name) => `import * as ${name} from '${path.resolve(process.cwd(), entry)}';`).join('\n')}
|
|
@@ -253,10 +254,10 @@ export default async (env, argv) => {
|
|
|
253
254
|
optimization: webpackOptimization({ server: true }),
|
|
254
255
|
plugins: _.compact([
|
|
255
256
|
...webpackPlugins,
|
|
256
|
-
new webpack.EnvironmentPlugin({ PORT }),
|
|
257
|
+
new webpack.EnvironmentPlugin({ PORT, NUM_WORKERS }),
|
|
257
258
|
new webpack.DefinePlugin({
|
|
258
259
|
__applications__: JSON.stringify(_.mapValues(inputs, x => ({
|
|
259
|
-
path: x.
|
|
260
|
+
path: x.basepath,
|
|
260
261
|
}))),
|
|
261
262
|
}),
|
|
262
263
|
...config.options?.server?.plugins ?? [],
|
|
@@ -2961,9 +2961,9 @@ lodash.debounce@^4.0.8:
|
|
|
2961
2961
|
integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==
|
|
2962
2962
|
|
|
2963
2963
|
lodash@>=4.17.21, lodash@^4.17.21:
|
|
2964
|
-
version "4.
|
|
2965
|
-
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.
|
|
2966
|
-
integrity sha512-
|
|
2964
|
+
version "4.18.1"
|
|
2965
|
+
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.18.1.tgz#ff2b66c1f6326d59513de2407bf881439812771c"
|
|
2966
|
+
integrity sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==
|
|
2967
2967
|
|
|
2968
2968
|
lru-cache@^5.1.1:
|
|
2969
2969
|
version "5.1.1"
|