@mainset/cli 0.2.1-rc.2 ā 0.3.0-rc.1
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/dist/esm/commands/web-app.mjs +19 -17
- package/dist/esm/dotenv-config.mjs +9 -0
- package/dist/esm/runtime/index.mjs +1 -0
- package/dist/esm/runtime/parse-cli-options.mjs +13 -0
- package/dist/esm/services/express-base-app/express-base-app.mjs +11 -7
- package/dist/esm/services/serve-static/serve-static-config-loader.mjs +13 -10
- package/dist/esm/services/ssr-server/ssr-server-config-loader.mjs +7 -7
- package/dist/esm/utils/process-runner/process-runner.mjs +2 -5
- package/dist/types/dotenv-config.d.mts +3 -0
- package/dist/types/runtime/index.d.mts +1 -0
- package/dist/types/runtime/parse-cli-options.d.mts +6 -0
- package/dist/types/services/express-base-app/express-base-app.d.mts +3 -0
- package/dist/types/utils/process-runner/process-runner.d.mts +2 -1
- package/package.json +4 -3
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
|
+
import { initDotenv } from '../dotenv-config.mjs';
|
|
3
4
|
import { resolveHostPackageBinForCLICommandPath, runtimePathById, } from '../runtime/index.mjs';
|
|
4
5
|
import { consoleColorize, execImmediateCommand, initProcessCatchErrorLogger, runStreamingCommand, runStreamingInSync, } from '../utils/index.mjs';
|
|
5
6
|
import { execImmediatePurgeDist } from './process-runner-chunks/index.mjs';
|
|
@@ -16,6 +17,9 @@ function registerWebAppCommand(program) {
|
|
|
16
17
|
.option('-c, --config <path>', 'Path to config file')
|
|
17
18
|
.option('--serveMode <mode>', 'Serve mode: ssr or csr (default: ssr)', 'ssr')
|
|
18
19
|
.action((options) => {
|
|
20
|
+
// !IMPORTANT: Load environment variables from .env file ONLY when we are compiling Web Applications
|
|
21
|
+
// as it logs {missing .env file} console error during {course-code} / {node-package} compilation
|
|
22
|
+
initDotenv();
|
|
19
23
|
// Step 0: determinate command params
|
|
20
24
|
const customWebpackConfigPath = path.resolve(runtimePathById.root, options.config || './config/webpack.config.mjs');
|
|
21
25
|
// SSR server path
|
|
@@ -44,7 +48,7 @@ function registerWebAppCommand(program) {
|
|
|
44
48
|
execImmediatePurgeDist();
|
|
45
49
|
// Step 2: build:ssr-webapp source code
|
|
46
50
|
console.log('\nš¦ Compiling SSR WebApp with Webpack ...');
|
|
47
|
-
execImmediateCommand(
|
|
51
|
+
execImmediateCommand(`MS_CLI__WEBPACK_SERVE_MODE=ssr ${webpackCLICommandPath} --config ${webpackSSRConfigPath}`);
|
|
48
52
|
/*
|
|
49
53
|
// Step 3: build:ssr-server source code
|
|
50
54
|
console.log('\nš¦ Compiling SSR Server with Rslib ...');
|
|
@@ -61,7 +65,7 @@ function registerWebAppCommand(program) {
|
|
|
61
65
|
execImmediatePurgeDist();
|
|
62
66
|
// Step 2: build:csr-webapp source code
|
|
63
67
|
console.log('\nš¦ Compiling CSR WebApp with Webpack ...');
|
|
64
|
-
execImmediateCommand(
|
|
68
|
+
execImmediateCommand(`MS_CLI__WEBPACK_SERVE_MODE=csr ${webpackCLICommandPath} --config ${webpackCSRConfigPath}`);
|
|
65
69
|
console.log('\nā
CSR Build completed successfully\n');
|
|
66
70
|
}
|
|
67
71
|
}
|
|
@@ -88,11 +92,9 @@ function registerWebAppCommand(program) {
|
|
|
88
92
|
runStreamingInSync([
|
|
89
93
|
// Step 2: watch:ssr-webapp source code of web app
|
|
90
94
|
{
|
|
91
|
-
runCommand: () => runStreamingCommand(webpackCLICommandPath, [
|
|
92
|
-
'
|
|
93
|
-
|
|
94
|
-
'--watch',
|
|
95
|
-
]),
|
|
95
|
+
runCommand: () => runStreamingCommand(webpackCLICommandPath, ['--config', webpackSSRConfigPath, '--watch'], {
|
|
96
|
+
env: Object.assign(Object.assign({}, process.env), { MS_CLI__WEBPACK_SERVE_MODE: 'ssr' }),
|
|
97
|
+
}),
|
|
96
98
|
waitForOutput: 'compiled successfully',
|
|
97
99
|
},
|
|
98
100
|
// Step 3: start:ssr-server which is compiled web app and ssr-server code
|
|
@@ -112,12 +114,9 @@ function registerWebAppCommand(program) {
|
|
|
112
114
|
? customWebpackConfigPath
|
|
113
115
|
: path.resolve(runtimePathById.root, 'node_modules', '@mainset/bundler-webpack/dist/esm/webpack-config/dev-server.csr.config.mjs');
|
|
114
116
|
// Step 1: watch:csr-server / start:csr-server source code
|
|
115
|
-
runStreamingCommand(webpackCLICommandPath, [
|
|
116
|
-
'
|
|
117
|
-
|
|
118
|
-
webpackDevServerConfigPath,
|
|
119
|
-
'--open',
|
|
120
|
-
]);
|
|
117
|
+
runStreamingCommand(webpackCLICommandPath, ['serve', '--config', webpackDevServerConfigPath, '--open'], {
|
|
118
|
+
env: Object.assign(Object.assign({}, process.env), { MS_CLI__WEBPACK_SERVE_MODE: 'csr' }),
|
|
119
|
+
});
|
|
121
120
|
}
|
|
122
121
|
}
|
|
123
122
|
catch (error) {
|
|
@@ -142,10 +141,13 @@ function registerWebAppCommand(program) {
|
|
|
142
141
|
// ========== [Serve Static] CSR mode ==========
|
|
143
142
|
// Step 1: determinate command params
|
|
144
143
|
const serverEntryPath = path.resolve(runtimePathById.msCLISrc, '../services/serve-static/serve-static.mjs');
|
|
145
|
-
const
|
|
146
|
-
const
|
|
147
|
-
|
|
148
|
-
|
|
144
|
+
const customServeStaticMjsConfigPath = path.resolve(runtimePathById.root, options.config || './config/serve-static.config.mjs');
|
|
145
|
+
const customServeStaticJsonConfigPath = path.resolve(runtimePathById.root, './config/serve-static.config.json');
|
|
146
|
+
const serveStaticConfigPath = (fs.existsSync(customServeStaticMjsConfigPath) &&
|
|
147
|
+
customServeStaticMjsConfigPath) ||
|
|
148
|
+
(fs.existsSync(customServeStaticJsonConfigPath) &&
|
|
149
|
+
customServeStaticJsonConfigPath) ||
|
|
150
|
+
path.resolve(runtimePathById.msCLISrc, '../services/express-base-app/express-base-app.config.json');
|
|
149
151
|
// Step 2: serve static compiled files
|
|
150
152
|
runStreamingCommand('node', [
|
|
151
153
|
serverEntryPath,
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import dotenv from '@dotenvx/dotenvx';
|
|
2
|
+
function initDotenv() {
|
|
3
|
+
// Load environment-specific .env file
|
|
4
|
+
return dotenv.config();
|
|
5
|
+
}
|
|
6
|
+
// REVIEW: investigate if {.env} file need's to be loaded during {course-code} / {node-package} compilation
|
|
7
|
+
// Auto-execute configuration
|
|
8
|
+
// initDotenv();
|
|
9
|
+
export { initDotenv };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export { NODE_ENV } from './constants.mjs';
|
|
2
|
+
export { parseCliOptions } from './parse-cli-options.mjs';
|
|
2
3
|
export { runtimePathById } from './path.mjs';
|
|
3
4
|
export { resolveHostPackageBinForCLICommandPath, resolveHostPackageNodeModulesPath, } from './resolve-host-package.mjs';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
function parseCliOptions(options) {
|
|
3
|
+
const program = new Command();
|
|
4
|
+
options.forEach(({ commanderFlags, description }) => {
|
|
5
|
+
program.option(commanderFlags, description);
|
|
6
|
+
});
|
|
7
|
+
return program
|
|
8
|
+
.allowUnknownOption() // Bypass {error: unknown option '--config'}
|
|
9
|
+
.allowExcessArguments() // Bypass {error: too many arguments. Expected 0 arguments but got 2.}
|
|
10
|
+
.parse(process.argv)
|
|
11
|
+
.opts();
|
|
12
|
+
}
|
|
13
|
+
export { parseCliOptions };
|
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
import express from 'express';
|
|
2
|
+
import { createProxyMiddleware } from 'http-proxy-middleware';
|
|
2
3
|
import path from 'path';
|
|
3
|
-
// Import type { Options } from 'http-proxy-middleware';
|
|
4
4
|
import { runtimePathById } from '../../runtime/index.mjs';
|
|
5
5
|
import defaultExpressConfig from './express-base-app.config.json' with { type: 'json' };
|
|
6
6
|
class ExpressBaseApp {
|
|
7
7
|
// ========== Constructor ==========
|
|
8
8
|
constructor(customExpressConfig = {}) {
|
|
9
|
-
const { listenPort = defaultExpressConfig.listenPort, serveStatics } = customExpressConfig;
|
|
9
|
+
const { listenPort = defaultExpressConfig.listenPort, serveStatics = defaultExpressConfig.serveStatics, proxyConfigByPath, } = customExpressConfig;
|
|
10
10
|
this.listenPort = listenPort;
|
|
11
11
|
this.app = express();
|
|
12
12
|
this.appUseStatic({
|
|
13
13
|
serveStatics,
|
|
14
14
|
});
|
|
15
|
+
this.appUseProxyMiddleware({
|
|
16
|
+
proxyConfigByPath,
|
|
17
|
+
});
|
|
15
18
|
this.startListening = this.startListening.bind(this);
|
|
16
19
|
}
|
|
17
20
|
// ========== Private ==========
|
|
@@ -21,11 +24,12 @@ class ExpressBaseApp {
|
|
|
21
24
|
this.app.use(serveStaticConfig.publicPath, express.static(serveStaticConfig.rootPath));
|
|
22
25
|
});
|
|
23
26
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
appUseProxyMiddleware({ proxyConfigByPath = {}, }) {
|
|
28
|
+
var _a;
|
|
29
|
+
(_a = Object.keys(proxyConfigByPath)) === null || _a === void 0 ? void 0 : _a.forEach((proxyPath) => {
|
|
30
|
+
this.app.use(proxyPath, createProxyMiddleware(proxyConfigByPath[proxyPath]));
|
|
31
|
+
});
|
|
32
|
+
}
|
|
29
33
|
// ========== Public ==========
|
|
30
34
|
startListening() {
|
|
31
35
|
this.app.listen(this.listenPort, async () => {
|
|
@@ -1,14 +1,17 @@
|
|
|
1
|
-
import { Command } from 'commander';
|
|
2
1
|
import fs from 'fs';
|
|
2
|
+
import { parseCliOptions } from '../../runtime/index.mjs';
|
|
3
3
|
// Step-1: parse CLI arguments
|
|
4
|
-
const options =
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
const options = parseCliOptions([
|
|
5
|
+
{
|
|
6
|
+
commanderFlags: '--serveStaticConfig <path>',
|
|
7
|
+
description: 'Path to ./config/serve-static.config.{mjs,json} config file',
|
|
8
|
+
},
|
|
9
|
+
]);
|
|
10
10
|
// Step-2: load Serve Static config from JSON file
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
const isConfigFileJsonWithoutProcessEnvUsage = /\.json$/.test(options.serveStaticConfig);
|
|
12
|
+
const serveStaticConfig = isConfigFileJsonWithoutProcessEnvUsage
|
|
13
|
+
? JSON.parse(fs.readFileSync(options.serveStaticConfig, 'utf-8') ||
|
|
14
|
+
// NOTE: dot not crash in case if {.json} file is empty
|
|
15
|
+
'{}')
|
|
16
|
+
: (await import(options.serveStaticConfig)).default;
|
|
14
17
|
export { serveStaticConfig };
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { parseCliOptions } from '../../runtime/index.mjs';
|
|
2
2
|
// Step-1: parse CLI arguments
|
|
3
|
-
const options =
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
const options = parseCliOptions([
|
|
4
|
+
{
|
|
5
|
+
commanderFlags: '--ssrServerConfig <path>',
|
|
6
|
+
description: 'Path to ./config/ssr-server.config.mts config file',
|
|
7
|
+
},
|
|
8
|
+
]);
|
|
9
9
|
// Step-2: load SSR server config from JSON file
|
|
10
10
|
const ssrServerConfig = (await import(options.ssrServerConfig))
|
|
11
11
|
.default;
|
|
@@ -36,12 +36,9 @@ function execImmediateCommand(fullCommandString) {
|
|
|
36
36
|
*
|
|
37
37
|
* Example: runStreamingCommand('rspack', ['serve', '--config', './config/rspack.config.ts']);
|
|
38
38
|
*/
|
|
39
|
-
function runStreamingCommand(command, args) {
|
|
39
|
+
function runStreamingCommand(command, args, options = {}) {
|
|
40
40
|
try {
|
|
41
|
-
const child = spawn(command, args, {
|
|
42
|
-
stdio: 'inherit',
|
|
43
|
-
shell: true,
|
|
44
|
-
});
|
|
41
|
+
const child = spawn(command, args, Object.assign({ stdio: 'inherit', shell: true }, options));
|
|
45
42
|
// Track the process using ProcessManager as it could live in the background after crashing
|
|
46
43
|
// Examples: server stacks when files removed while server is running
|
|
47
44
|
// 1. rm -rf ./dist
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { NODE_ENV } from './constants.mjs';
|
|
2
2
|
export type { NodeEnv } from './constants.mjs';
|
|
3
|
+
export { parseCliOptions } from './parse-cli-options.mjs';
|
|
3
4
|
export { runtimePathById } from './path.mjs';
|
|
4
5
|
export { resolveHostPackageBinForCLICommandPath, resolveHostPackageNodeModulesPath, } from './resolve-host-package.mjs';
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Express } from 'express';
|
|
2
|
+
import type { Options } from 'http-proxy-middleware';
|
|
2
3
|
interface ServeStaticConfig {
|
|
3
4
|
rootPath?: string;
|
|
4
5
|
publicPath?: string;
|
|
@@ -6,12 +7,14 @@ interface ServeStaticConfig {
|
|
|
6
7
|
interface ExpressBaseAppConfig {
|
|
7
8
|
listenPort?: number;
|
|
8
9
|
serveStatics?: ServeStaticConfig[];
|
|
10
|
+
proxyConfigByPath?: Record<string, Options>;
|
|
9
11
|
}
|
|
10
12
|
declare class ExpressBaseApp {
|
|
11
13
|
private readonly listenPort;
|
|
12
14
|
readonly app: Express;
|
|
13
15
|
constructor(customExpressConfig?: Partial<ExpressBaseAppConfig>);
|
|
14
16
|
private appUseStatic;
|
|
17
|
+
private appUseProxyMiddleware;
|
|
15
18
|
startListening(): void;
|
|
16
19
|
}
|
|
17
20
|
export { ExpressBaseApp };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { SpawnOptions } from 'child_process';
|
|
1
2
|
declare function initProcessCatchErrorLogger(commandName: string, error: Error | unknown, commandParam?: string): void;
|
|
2
3
|
/**
|
|
3
4
|
* Executes a short-lived command synchronously.
|
|
@@ -12,7 +13,7 @@ declare function execImmediateCommand(fullCommandString: string): void;
|
|
|
12
13
|
*
|
|
13
14
|
* Example: runStreamingCommand('rspack', ['serve', '--config', './config/rspack.config.ts']);
|
|
14
15
|
*/
|
|
15
|
-
declare function runStreamingCommand(command: string, args: string[]): import("child_process").ChildProcess | undefined;
|
|
16
|
+
declare function runStreamingCommand(command: string, args: string[], options?: SpawnOptions): import("child_process").ChildProcess | undefined;
|
|
16
17
|
/**
|
|
17
18
|
* Runs a streaming command in sync mode.
|
|
18
19
|
* This is a placeholder function and does not execute any command.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mainset/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0-rc.1",
|
|
4
4
|
"description": "A unified CLI tool for accelerating development, based on mainset vision of front-end infrastructure",
|
|
5
5
|
"homepage": "https://github.com/mainset/dev-stack-fe/tree/main/packages/cli",
|
|
6
6
|
"bugs": {
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
"ms-cli": "./dist/esm/mainset-cli.mjs"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
+
"@dotenvx/dotenvx": "^1.47.2",
|
|
34
35
|
"@types/node": "^24.0.3",
|
|
35
36
|
"commander": "^14.0.0",
|
|
36
37
|
"cors": "^2.8.5",
|
|
@@ -42,10 +43,10 @@
|
|
|
42
43
|
"@types/cors": "^2.8.19",
|
|
43
44
|
"@types/express": "^5.0.3",
|
|
44
45
|
"@types/node": "^24.0.3",
|
|
45
|
-
"@mainset/dev-stack-fe": "^0.
|
|
46
|
+
"@mainset/dev-stack-fe": "^0.2.0-rc.1"
|
|
46
47
|
},
|
|
47
48
|
"peerDependencies": {
|
|
48
|
-
"@mainset/dev-stack-fe": "^0.
|
|
49
|
+
"@mainset/dev-stack-fe": "^0.2.0"
|
|
49
50
|
},
|
|
50
51
|
"scripts": {
|
|
51
52
|
"build:source": "node ./node_modules/@mainset/dev-stack-fe/node_modules/typescript/bin/tsc --project ./tsconfig.json",
|