Feat/427: Serve explicit environments (#433)
* feat: add env specific serve commands where appropriate for apps * fix: typo in command call * feat: add custom executor for serving apps * chore: clean up project files and use the custom executor * chore: patch readmes * chore: split out logs into their own function * fix: prevent overriding env when no flag passed in * fix: add tsc to postinstall to take care of compiling the custom executors * fix: remove the custom serve executor from trading
This commit is contained in:
parent
66c8d195a2
commit
a6a21bed46
1
.gitignore
vendored
1
.gitignore
vendored
@ -4,6 +4,7 @@
|
||||
/dist
|
||||
/tmp
|
||||
/out-tsc
|
||||
/tools/executors/**/*.js
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
|
@ -32,12 +32,18 @@ yarn nx serve explorer
|
||||
Example configurations are provided here:
|
||||
|
||||
- [Mainnet](./.env.mainnet)
|
||||
- [Testnet](./.env.testnet)
|
||||
- [Devnet](./.env.devnet)
|
||||
- [Capsule](./.env.capsule)
|
||||
- [Testnet](./.env.testnet)
|
||||
- [Stagnet1](./.env.stagnet1)
|
||||
- [Stagnet2](./.env.stagnet2)
|
||||
|
||||
For convenience, you can boot the app injecting one of the configurations above by running:
|
||||
|
||||
```bash
|
||||
yarn nx run explorer:serve --env={env} # e.g. stagnet1
|
||||
```
|
||||
|
||||
There are a few different configuration options offered for this app:
|
||||
|
||||
| **Flag** | **Purpose** |
|
||||
|
@ -38,7 +38,7 @@
|
||||
}
|
||||
},
|
||||
"serve": {
|
||||
"executor": "@nrwl/web:dev-server",
|
||||
"executor": "./tools/executors/serve:serve",
|
||||
"options": {
|
||||
"port": 3000,
|
||||
"buildTarget": "explorer:build",
|
||||
|
@ -41,7 +41,7 @@
|
||||
}
|
||||
},
|
||||
"serve": {
|
||||
"executor": "@nrwl/web:dev-server",
|
||||
"executor": "./tools/executors/serve:serve",
|
||||
"options": {
|
||||
"buildTarget": "simple-trading-app:build",
|
||||
"hmr": true,
|
||||
|
@ -36,7 +36,7 @@
|
||||
}
|
||||
},
|
||||
"serve": {
|
||||
"executor": "@nrwl/web:dev-server",
|
||||
"executor": "./tools/executors/serve:serve",
|
||||
"options": {
|
||||
"buildTarget": "static:build"
|
||||
},
|
||||
|
@ -37,7 +37,7 @@
|
||||
}
|
||||
},
|
||||
"serve": {
|
||||
"executor": "@nrwl/web:dev-server",
|
||||
"executor": "./tools/executors/serve:serve",
|
||||
"options": {
|
||||
"port": 3010,
|
||||
"buildTarget": "stats:build",
|
||||
|
@ -16,10 +16,26 @@
|
||||
|
||||
Starting the app:
|
||||
|
||||
`yarn nx serve token`
|
||||
```bash
|
||||
yarn nx serve token
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
Example configurations are provided here:
|
||||
|
||||
- [Mainnet](./.env.mainnet)
|
||||
- [Devnet](./.env.devnet)
|
||||
- [Testnet](./.env.testnet)
|
||||
- [Stagnet1](./.env.stagnet1)
|
||||
- [Stagnet2](./.env.stagnet2)
|
||||
|
||||
For convenience, you can boot the app injecting one of the configurations above by running:
|
||||
|
||||
```bash
|
||||
yarn nx run token:serve --env={env} # e.g. stagnet1
|
||||
```
|
||||
|
||||
There are a few different configuration options offered for this app:
|
||||
|
||||
| **Flag** | **Purpose** |
|
||||
|
@ -38,7 +38,7 @@
|
||||
}
|
||||
},
|
||||
"serve": {
|
||||
"executor": "@nrwl/web:dev-server",
|
||||
"executor": "./tools/executors/serve:serve",
|
||||
"options": {
|
||||
"port": 4210,
|
||||
"buildTarget": "token:build",
|
||||
|
@ -19,7 +19,7 @@ yarn nx serve explorer
|
||||
Example configurations are provided here:
|
||||
|
||||
- [Mainnet](./.env.mainnet)
|
||||
- [Testnet](./.env.testnet)
|
||||
- [Devnet](./.env.devnet)
|
||||
- [Testnet](./.env.testnet)
|
||||
- [Stagnet1](./.env.stagnet1)
|
||||
- [Stagnet2](./.env.stagnet2)
|
||||
|
@ -6,7 +6,7 @@
|
||||
"start": "nx serve",
|
||||
"build": "nx build",
|
||||
"test": "nx test",
|
||||
"postinstall": "husky install"
|
||||
"postinstall": "husky install && yarn tsc -b tools/executors/**"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.14.0"
|
||||
@ -122,6 +122,7 @@
|
||||
"babel-loader": "8.1.0",
|
||||
"cypress": "^9.5.4",
|
||||
"cypress-cucumber-preprocessor": "^4.3.1",
|
||||
"dotenv": "^16.0.1",
|
||||
"eslint": "8.12.0",
|
||||
"eslint-config-next": "12.1.2",
|
||||
"eslint-config-prettier": "8.1.0",
|
||||
@ -138,6 +139,7 @@
|
||||
"jest-canvas-mock": "^2.3.1",
|
||||
"jest-websocket-mock": "^2.3.0",
|
||||
"lint-staged": "^12.3.3",
|
||||
"npmlog": "^6.0.2",
|
||||
"nx": "13.10.1",
|
||||
"prettier": "^2.5.1",
|
||||
"react-test-renderer": "17.0.2",
|
||||
|
9
tools/executors/serve/executor.json
Normal file
9
tools/executors/serve/executor.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"executors": {
|
||||
"serve": {
|
||||
"implementation": "./impl",
|
||||
"schema": "./schema.json",
|
||||
"description": "Starts a dev-server with an optional explicit environment."
|
||||
}
|
||||
}
|
||||
}
|
89
tools/executors/serve/impl.ts
Normal file
89
tools/executors/serve/impl.ts
Normal file
@ -0,0 +1,89 @@
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import * as dotenv from 'dotenv';
|
||||
import * as log from 'npmlog';
|
||||
import type { ExecutorContext } from '@nrwl/devkit';
|
||||
import devServerExecutor, {
|
||||
WebDevServerOptions,
|
||||
} from '@nrwl/web/src/executors/dev-server/dev-server.impl';
|
||||
|
||||
type Schema = WebDevServerOptions & {
|
||||
env?: string;
|
||||
};
|
||||
|
||||
const LOGGER_SCOPE = 'tools/executors/serve';
|
||||
|
||||
const logEnvData = (
|
||||
envMap: Record<string, string>,
|
||||
envFiles: string[],
|
||||
env?: string,
|
||||
defaultEnvFile?: string
|
||||
) => {
|
||||
if (env && !envMap[env]) {
|
||||
log.warn(LOGGER_SCOPE, `No environment called "${env}" found.`);
|
||||
log.info(
|
||||
LOGGER_SCOPE,
|
||||
envFiles.length > 0
|
||||
? `You can create a new environment by putting an ".env.${env}" file in your project root, or you can use the following available ones: ${envFiles.join(
|
||||
', '
|
||||
)}.`
|
||||
: 'To get started with environments, you can create an ".env" file in your project root with the desired variables.'
|
||||
);
|
||||
}
|
||||
|
||||
if (!envMap[env]) {
|
||||
log.info(
|
||||
LOGGER_SCOPE,
|
||||
defaultEnvFile
|
||||
? `Using "${defaultEnvFile}" as the default project environment.`
|
||||
: 'Serving the project only using the environment variables scoped to your CLI.'
|
||||
);
|
||||
} else {
|
||||
log.info(
|
||||
LOGGER_SCOPE,
|
||||
`Using "${envMap[env]}" as the default project environment.`
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const filenameToEnv = (filename: string) => filename.replace('.env.', '');
|
||||
|
||||
const getDefaultEnvFile = (envMap: Record<string, string>) => {
|
||||
return envMap['local'] || envMap['.env'];
|
||||
};
|
||||
|
||||
const getEnvFile = (env: string, envFiles: string[]) => {
|
||||
const envMap = envFiles.reduce(
|
||||
(acc, filename) => ({
|
||||
...acc,
|
||||
[filenameToEnv(filename)]: filename,
|
||||
}),
|
||||
{}
|
||||
);
|
||||
|
||||
const defaultEnvFile = getDefaultEnvFile(envMap);
|
||||
logEnvData(envMap, envFiles, env, defaultEnvFile);
|
||||
|
||||
return envMap[env] || defaultEnvFile;
|
||||
};
|
||||
|
||||
export default async function* serve(
|
||||
options: Schema,
|
||||
context: ExecutorContext
|
||||
): ReturnType<typeof devServerExecutor> {
|
||||
const { env, ...dsOptions } = options;
|
||||
const { root } = context.workspace.projects[context.projectName];
|
||||
const workspacePath = path.join(context.cwd, root);
|
||||
|
||||
const files = await fs.promises.readdir(workspacePath);
|
||||
const envFile = getEnvFile(
|
||||
env,
|
||||
files.filter((f) => f.startsWith('.env'))
|
||||
);
|
||||
|
||||
if (env && envFile) {
|
||||
dotenv.config({ path: path.join(workspacePath, envFile), override: true });
|
||||
}
|
||||
|
||||
return yield* devServerExecutor(dsOptions, context);
|
||||
}
|
3
tools/executors/serve/package.json
Normal file
3
tools/executors/serve/package.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"executors": "./executor.json"
|
||||
}
|
79
tools/executors/serve/schema.json
Normal file
79
tools/executors/serve/schema.json
Normal file
@ -0,0 +1,79 @@
|
||||
{
|
||||
"cli": "nx",
|
||||
"id": "serve",
|
||||
"description": "Serves an app using @nrwl/web:dev-server",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"env": {
|
||||
"type": "string",
|
||||
"description": "Target environment to run the application in. This assumes an .env file present in the project's root in the following format: .env.{envName}"
|
||||
},
|
||||
"buildTarget": {
|
||||
"type": "string",
|
||||
"description": "Target which builds the application."
|
||||
},
|
||||
"port": {
|
||||
"type": "number",
|
||||
"description": "Port to listen on.",
|
||||
"default": 4200
|
||||
},
|
||||
"host": {
|
||||
"type": "string",
|
||||
"description": "Host to listen on.",
|
||||
"default": "localhost"
|
||||
},
|
||||
"ssl": {
|
||||
"type": "boolean",
|
||||
"description": "Serve using `HTTPS`.",
|
||||
"default": false
|
||||
},
|
||||
"sslKey": {
|
||||
"type": "string",
|
||||
"description": "SSL key to use for serving `HTTPS`."
|
||||
},
|
||||
"sslCert": {
|
||||
"type": "string",
|
||||
"description": "SSL certificate to use for serving `HTTPS`."
|
||||
},
|
||||
"watch": {
|
||||
"type": "boolean",
|
||||
"description": "Watches for changes and rebuilds application.",
|
||||
"default": true
|
||||
},
|
||||
"liveReload": {
|
||||
"type": "boolean",
|
||||
"description": "Whether to reload the page on change, using live-reload.",
|
||||
"default": true
|
||||
},
|
||||
"hmr": {
|
||||
"type": "boolean",
|
||||
"description": "Enable hot module replacement.",
|
||||
"default": false
|
||||
},
|
||||
"publicHost": {
|
||||
"type": "string",
|
||||
"description": "Public URL where the application will be served."
|
||||
},
|
||||
"open": {
|
||||
"type": "boolean",
|
||||
"description": "Open the application in the browser.",
|
||||
"default": false
|
||||
},
|
||||
"allowedHosts": {
|
||||
"type": "string",
|
||||
"description": "This option allows you to whitelist services that are allowed to access the dev server."
|
||||
},
|
||||
"memoryLimit": {
|
||||
"type": "number",
|
||||
"description": "Memory limit for type checking service process in `MB`."
|
||||
},
|
||||
"maxWorkers": {
|
||||
"type": "number",
|
||||
"description": "Number of workers to use for type checking."
|
||||
},
|
||||
"baseHref": {
|
||||
"type": "string",
|
||||
"description": "Base url for the application being built."
|
||||
}
|
||||
}
|
||||
}
|
13
tools/executors/serve/tsconfig.json
Normal file
13
tools/executors/serve/tsconfig.json
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "es5",
|
||||
"types": ["node"],
|
||||
"importHelpers": false,
|
||||
"sourceMap": false,
|
||||
"inlineSourceMap": true
|
||||
},
|
||||
"include": ["impl.ts"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
43
yarn.lock
43
yarn.lock
@ -7340,6 +7340,14 @@ are-we-there-yet@^2.0.0:
|
||||
delegates "^1.0.0"
|
||||
readable-stream "^3.6.0"
|
||||
|
||||
are-we-there-yet@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-3.0.0.tgz#ba20bd6b553e31d62fc8c31bd23d22b95734390d"
|
||||
integrity sha512-0GWpv50YSOcLXaN6/FAKY3vfRbllXWV2xvfA/oKJF8pzFhWXPV+yjhJXDBbjscDYowv7Yw1A3uigpzn5iEGTyw==
|
||||
dependencies:
|
||||
delegates "^1.0.0"
|
||||
readable-stream "^3.6.0"
|
||||
|
||||
are-we-there-yet@~1.1.2:
|
||||
version "1.1.7"
|
||||
resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz#b15474a932adab4ff8a50d9adfa7e4e926f21146"
|
||||
@ -9206,7 +9214,7 @@ color-name@^1.1.4, color-name@~1.1.4:
|
||||
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
|
||||
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
||||
|
||||
color-support@^1.1.2:
|
||||
color-support@^1.1.2, color-support@^1.1.3:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2"
|
||||
integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==
|
||||
@ -10670,6 +10678,11 @@ dotenv-expand@^5.1.0:
|
||||
resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-5.1.0.tgz#3fbaf020bfd794884072ea26b1e9791d45a629f0"
|
||||
integrity sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==
|
||||
|
||||
dotenv@^16.0.1:
|
||||
version "16.0.1"
|
||||
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.1.tgz#8f8f9d94876c35dac989876a5d3a82a267fdce1d"
|
||||
integrity sha512-1K6hR6wtk2FviQ4kEiSjFiH5rpzEVi8WW0x96aztHVMhEspNpc4DVOUTEHtEva5VThQ8IaBX1Pe4gSzpVVUsKQ==
|
||||
|
||||
dotenv@^8.0.0:
|
||||
version "8.6.0"
|
||||
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.6.0.tgz#061af664d19f7f4d8fc6e4ff9b584ce237adcb8b"
|
||||
@ -12290,6 +12303,20 @@ gauge@^3.0.0:
|
||||
strip-ansi "^6.0.1"
|
||||
wide-align "^1.1.2"
|
||||
|
||||
gauge@^4.0.3:
|
||||
version "4.0.4"
|
||||
resolved "https://registry.yarnpkg.com/gauge/-/gauge-4.0.4.tgz#52ff0652f2bbf607a989793d53b751bef2328dce"
|
||||
integrity sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==
|
||||
dependencies:
|
||||
aproba "^1.0.3 || ^2.0.0"
|
||||
color-support "^1.1.3"
|
||||
console-control-strings "^1.1.0"
|
||||
has-unicode "^2.0.1"
|
||||
signal-exit "^3.0.7"
|
||||
string-width "^4.2.3"
|
||||
strip-ansi "^6.0.1"
|
||||
wide-align "^1.1.5"
|
||||
|
||||
gauge@~2.7.3:
|
||||
version "2.7.4"
|
||||
resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7"
|
||||
@ -16237,6 +16264,16 @@ npmlog@^5.0.1:
|
||||
gauge "^3.0.0"
|
||||
set-blocking "^2.0.0"
|
||||
|
||||
npmlog@^6.0.2:
|
||||
version "6.0.2"
|
||||
resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-6.0.2.tgz#c8166017a42f2dea92d6453168dd865186a70830"
|
||||
integrity sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==
|
||||
dependencies:
|
||||
are-we-there-yet "^3.0.0"
|
||||
console-control-strings "^1.1.0"
|
||||
gauge "^4.0.3"
|
||||
set-blocking "^2.0.0"
|
||||
|
||||
nth-check@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c"
|
||||
@ -19314,7 +19351,7 @@ side-channel@^1.0.4:
|
||||
get-intrinsic "^1.0.2"
|
||||
object-inspect "^1.9.0"
|
||||
|
||||
signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3:
|
||||
signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7:
|
||||
version "3.0.7"
|
||||
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9"
|
||||
integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==
|
||||
@ -21826,7 +21863,7 @@ which@^2.0.1, which@^2.0.2:
|
||||
dependencies:
|
||||
isexe "^2.0.0"
|
||||
|
||||
wide-align@^1.1.0, wide-align@^1.1.2:
|
||||
wide-align@^1.1.0, wide-align@^1.1.2, wide-align@^1.1.5:
|
||||
version "1.1.5"
|
||||
resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3"
|
||||
integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==
|
||||
|
Loading…
Reference in New Issue
Block a user