From c8e5b49039029d99c612b006bf9468f3b7f3912f Mon Sep 17 00:00:00 2001 From: sebastiandg7 Date: Thu, 22 Apr 2021 16:07:47 -0500 Subject: [PATCH] feat(serve): add local proxy feature --- docs/docs/executors/serve.md | 6 +++++ package.json | 1 + .../local-development-server.ts | 25 ++++++++++++++++++- .../src/executors/serve/schema.d.ts | 1 + .../src/executors/serve/schema.json | 4 +++ .../src/executors/serve/serve.executor.ts | 4 +++ .../generators/theme/files/proxy.conf.json | 6 +++++ .../src/generators/theme/theme.generator.ts | 3 ++- packages/nx-shopify/src/utils/config-utils.ts | 6 +++++ yarn.lock | 23 +++++++++++++++++ 10 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 packages/nx-shopify/src/generators/theme/files/proxy.conf.json create mode 100644 packages/nx-shopify/src/utils/config-utils.ts diff --git a/docs/docs/executors/serve.md b/docs/docs/executors/serve.md index 78d6578..29ee75d 100644 --- a/docs/docs/executors/serve.md +++ b/docs/docs/executors/serve.md @@ -102,3 +102,9 @@ Tell if the first deploy should be skipped. Type: `string` Set the local web server ip address. Valid values are: private (default), public, "interface name", "ip v4/6 address" (default: private) + +### --proxyConfig + +Type: `string` + +Path to the proxy configuration file to be used diff --git a/package.json b/package.json index 56b76b9..a5acd00 100644 --- a/package.json +++ b/package.json @@ -49,6 +49,7 @@ "file-loader": "^6.2.0", "fork-ts-checker-webpack-plugin": "^6.1.1", "html-webpack-plugin": "^4.5.0", + "http-proxy-middleware": "^1.2.0", "https": "^1.0.0", "ip": "^1.1.5", "js-yaml": "^4.0.0", diff --git a/packages/nx-shopify/src/executors/serve/local-development-server/local-development-server.ts b/packages/nx-shopify/src/executors/serve/local-development-server/local-development-server.ts index 50a7a1a..5b819cc 100644 --- a/packages/nx-shopify/src/executors/serve/local-development-server/local-development-server.ts +++ b/packages/nx-shopify/src/executors/serve/local-development-server/local-development-server.ts @@ -3,6 +3,11 @@ import { BrowserSyncInstance, Options as BrowserSyncOptions, } from 'browser-sync'; +import { + createProxyMiddleware, + Options as ProxyOptions, +} from 'http-proxy-middleware'; +import { getProxyConfig } from 'packages/nx-shopify/src/utils/config-utils'; import { getSSLKeyPath, getSSLCertPath } from './ssl/server-ssl'; @@ -13,6 +18,7 @@ export interface LocalDevelopmentServerOptions { port: number; uiPort: number; openBrowser: boolean; + proxyConfig: { [key: string]: ProxyOptions }; } export class LocalDevelopmentServer { @@ -25,9 +31,18 @@ export class LocalDevelopmentServer { browserSyncInstance: BrowserSyncInstance; browserSyncServer: BrowserSyncInstance; openBrowser: boolean; + proxyConfig: { [key: string]: ProxyOptions }; constructor(options: LocalDevelopmentServerOptions) { - const { target, themeId, port, address, uiPort, openBrowser } = options; + const { + target, + themeId, + port, + address, + uiPort, + openBrowser, + proxyConfig, + } = options; this.browserSyncInstance = browserSync.create(); this.target = `https://${target}`; @@ -39,6 +54,7 @@ export class LocalDevelopmentServer { this.target + (this.themeId === 'live' ? '' : `?preview_theme_id=${this.themeId}`); this.openBrowser = openBrowser; + this.proxyConfig = proxyConfig; } start() { @@ -57,6 +73,7 @@ export class LocalDevelopmentServer { next(); }, }, + middleware: [...this.getProxyMiddlewares()], snippetOptions: { rule: { match: /<\/body>/i, @@ -80,4 +97,10 @@ export class LocalDevelopmentServer { this.browserSyncServer = this.browserSyncInstance.init(bsConfig, resolve); }); } + + getProxyMiddlewares() { + return Object.entries(this.proxyConfig).map(([key, config]) => + createProxyMiddleware(key, config) + ); + } } diff --git a/packages/nx-shopify/src/executors/serve/schema.d.ts b/packages/nx-shopify/src/executors/serve/schema.d.ts index 543b1ae..a0b7479 100644 --- a/packages/nx-shopify/src/executors/serve/schema.d.ts +++ b/packages/nx-shopify/src/executors/serve/schema.d.ts @@ -6,4 +6,5 @@ export interface ServeExecutorSchema { analyze?: boolean; skipFirstDeploy: boolean; devServerIpAddress: string; + proxyConfig?: string; } diff --git a/packages/nx-shopify/src/executors/serve/schema.json b/packages/nx-shopify/src/executors/serve/schema.json index 53b805c..b3b20eb 100644 --- a/packages/nx-shopify/src/executors/serve/schema.json +++ b/packages/nx-shopify/src/executors/serve/schema.json @@ -39,6 +39,10 @@ "type": "string", "description": "Set the local web server ip address. Valid values are: private (default), public, , ", "default": "private" + }, + "proxyConfig": { + "type": "string", + "description": "Path to the proxy configuration file to be used" } }, "additionalProperties": false, diff --git a/packages/nx-shopify/src/executors/serve/serve.executor.ts b/packages/nx-shopify/src/executors/serve/serve.executor.ts index f89097b..c4f4426 100644 --- a/packages/nx-shopify/src/executors/serve/serve.executor.ts +++ b/packages/nx-shopify/src/executors/serve/serve.executor.ts @@ -4,6 +4,7 @@ import { readTargetOptions, } from '@nrwl/devkit'; import { BuildExecutorSchema } from '../../executors/build/schema'; +import { getProxyConfig } from '../../utils/config-utils'; import { getAvailablePortSeries, getIpAddress, @@ -73,6 +74,8 @@ export async function serveExecutor( const ipAddress = getIpAddress(options.devServerIpAddress); + const proxyConfig = getProxyConfig(context.root, options.proxyConfig); + const devServer = new LocalDevelopmentServer({ port: devServerPort, uiPort: devServerUIPort, @@ -80,6 +83,7 @@ export async function serveExecutor( themeId, address: ipAddress, openBrowser: open, + proxyConfig, }); const assetServer = new LocalAssetServer({ diff --git a/packages/nx-shopify/src/generators/theme/files/proxy.conf.json b/packages/nx-shopify/src/generators/theme/files/proxy.conf.json new file mode 100644 index 0000000..62a1e7b --- /dev/null +++ b/packages/nx-shopify/src/generators/theme/files/proxy.conf.json @@ -0,0 +1,6 @@ +{ + "/api": { + "target": "http://localhost:3333", + "secure": false + } +} diff --git a/packages/nx-shopify/src/generators/theme/theme.generator.ts b/packages/nx-shopify/src/generators/theme/theme.generator.ts index 1f9eb1e..0563cc5 100644 --- a/packages/nx-shopify/src/generators/theme/theme.generator.ts +++ b/packages/nx-shopify/src/generators/theme/theme.generator.ts @@ -127,12 +127,13 @@ function addServeTarget( project: ProjectConfiguration, options: NormalizedSchema ) { - const { projectName } = options; + const { projectRoot, projectName } = options; const serveTarget: TargetConfiguration = { executor: '@trafilea/nx-shopify:serve', options: { buildTarget: `${projectName}:build`, + proxyConfig: `${projectRoot}/proxy.conf.json`, }, configurations: { production: { diff --git a/packages/nx-shopify/src/utils/config-utils.ts b/packages/nx-shopify/src/utils/config-utils.ts new file mode 100644 index 0000000..eac7af3 --- /dev/null +++ b/packages/nx-shopify/src/utils/config-utils.ts @@ -0,0 +1,6 @@ +import { resolve } from 'path'; + +export function getProxyConfig(root: string, proxyConfigPath: string) { + const proxyPath = resolve(root, proxyConfigPath); + return require(proxyPath); +} diff --git a/yarn.lock b/yarn.lock index 03137f5..68f8bd0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1152,6 +1152,13 @@ resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz#3c9ee980f1a10d6021ae6632ca3e79ca2ec4fb50" integrity sha512-giAlZwstKbmvMk1OO7WXSj4OZ0keXAcl2TQq4LWHiiPH2ByaH7WeUzng+Qej8UPxxv+8lRTuouo0iaNDBuzIBA== +"@types/http-proxy@^1.17.5": + version "1.17.5" + resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.5.tgz#c203c5e6e9dc6820d27a40eb1e511c70a220423d" + integrity sha512-GNkDE7bTv6Sf8JbV2GksknKOsk7OznNYHSdrtvPJXO0qJ9odZig6IZKUi5RFGi6d1bf6dgIAe4uXi3DBc7069Q== + dependencies: + "@types/node" "*" + "@types/ip@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@types/ip/-/ip-1.1.0.tgz#aec4f5bfd49e4a4c53b590d88c36eb078827a7c0" @@ -6700,6 +6707,17 @@ http-proxy-middleware@0.19.1: lodash "^4.17.11" micromatch "^3.1.10" +http-proxy-middleware@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-1.2.0.tgz#87776ea3d4d8dda3dc2594a076787bbc6fe4d995" + integrity sha512-vNw+AxT0+6VTM1rCJw1bpiIaUQ1Ww/vTyIEOUzdW9kNX4yuhhqV3jLSKDJo/Y/lqEIshaKCDujtvEqWiD9Dn6Q== + dependencies: + "@types/http-proxy" "^1.17.5" + http-proxy "^1.18.1" + is-glob "^4.0.1" + is-plain-obj "^3.0.0" + micromatch "^4.0.2" + http-proxy@^1.17.0, http-proxy@^1.18.1: version "1.18.1" resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" @@ -7389,6 +7407,11 @@ is-plain-obj@^2.0.0: resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== +is-plain-obj@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz#af6f2ea14ac5a646183a5bbdb5baabbc156ad9d7" + integrity sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA== + is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677"