From 2959334230dc6e00a8704c954e197552b0eec94d Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Tue, 6 Dec 2022 09:52:58 +0000 Subject: [PATCH 01/27] Add cosmiconfig --- packages/modular-scripts/package.json | 1 + yarn.lock | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/packages/modular-scripts/package.json b/packages/modular-scripts/package.json index b16943cd4..c835eb81f 100644 --- a/packages/modular-scripts/package.json +++ b/packages/modular-scripts/package.json @@ -49,6 +49,7 @@ "chalk": "4.1.2", "change-case": "4.1.2", "commander": "9.4.0", + "cosmiconfig": "^8.0.0", "cross-spawn": "7.0.3", "css-loader": "6.7.1", "css-minimizer-webpack-plugin": "3.4.1", diff --git a/yarn.lock b/yarn.lock index b2c5811c7..3f35dd93a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4842,6 +4842,16 @@ cosmiconfig@^7.0.0, cosmiconfig@^7.0.1: path-type "^4.0.0" yaml "^1.10.0" +cosmiconfig@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-8.0.0.tgz#e9feae014eab580f858f8a0288f38997a7bebe97" + integrity sha512-da1EafcpH6b/TD8vDRaWV7xFINlHlF6zKsGwS1TsuVJTZRkquaS5HTMq7uq6h31619QjbsYl21gVDOm32KM1vQ== + dependencies: + import-fresh "^3.2.1" + js-yaml "^4.1.0" + parse-json "^5.0.0" + path-type "^4.0.0" + create-jest-runner@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/create-jest-runner/-/create-jest-runner-0.6.0.tgz#9ca6583d969acc15cdc21cd07d430945daf83de6" From e1571dd789598c70472d71aa64e87a95022742f2 Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Wed, 7 Dec 2022 13:48:03 +0000 Subject: [PATCH 02/27] Allow use esbuild to be configured by a modular configuration file --- __fixtures__/test-config/.modular.js | 3 + .../src/__tests__/utils/config.test.ts | 51 +++++++++++ packages/modular-scripts/src/build/index.ts | 17 +--- packages/modular-scripts/src/start.ts | 13 +-- packages/modular-scripts/src/test/utils.ts | 4 + packages/modular-scripts/src/utils/config.ts | 91 +++++++++++++++++++ 6 files changed, 155 insertions(+), 24 deletions(-) create mode 100644 __fixtures__/test-config/.modular.js create mode 100644 packages/modular-scripts/src/__tests__/utils/config.test.ts create mode 100644 packages/modular-scripts/src/utils/config.ts diff --git a/__fixtures__/test-config/.modular.js b/__fixtures__/test-config/.modular.js new file mode 100644 index 000000000..6ae251fac --- /dev/null +++ b/__fixtures__/test-config/.modular.js @@ -0,0 +1,3 @@ +module.exports = { + useModularEsbuild: true, +}; diff --git a/packages/modular-scripts/src/__tests__/utils/config.test.ts b/packages/modular-scripts/src/__tests__/utils/config.test.ts new file mode 100644 index 000000000..a64697f6c --- /dev/null +++ b/packages/modular-scripts/src/__tests__/utils/config.test.ts @@ -0,0 +1,51 @@ +import execa from 'execa'; +import { copyFileSync } from 'fs'; +import path from 'path'; +import { createModularTestContext } from '../../test/utils'; +import getModularRoot from '../../utils/getModularRoot'; + +const modularRoot = getModularRoot(); +const configFixtures = path.join(modularRoot, '__fixtures__', 'test-config'); + +/** + * Run modular with provided arguments in specified directory + */ +function modular( + args: string, + cwd: string, + opts: Record = {}, +) { + return execa('yarnpkg', ['modular', ...args.split(' ')], { + cwd, + cleanup: true, + ...opts, + }); +} + +// Temporary test context paths set by createTempModularRepoWithTemplate() +let tempModularRepo: string; + +describe('A simple modular repo with a .modular.js config file', () => { + beforeEach(async () => { + tempModularRepo = createModularTestContext(); + await modular('add test-app --unstable-type app', tempModularRepo); + copyFileSync( + path.join(configFixtures, '.modular.js'), + path.join(tempModularRepo, '.modular.js'), + ); + }); + it('builds using esbuild as specified in config file', async () => { + const result = await modular(`build test-app --verbose`, tempModularRepo); + expect(result.stdout).toContain('Building with esbuild'); + expect(result.exitCode).toBe(0); + }); + it('builds using webpack if the environment variable is provided as it overrides the config', async () => { + const result = await modular(`build test-app --verbose`, tempModularRepo, { + env: { + USE_MODULAR_WEBPACK: 'true', + }, + }); + expect(result.stdout).toContain('Building with Webpack'); + expect(result.exitCode).toBe(0); + }); +}); diff --git a/packages/modular-scripts/src/build/index.ts b/packages/modular-scripts/src/build/index.ts index e6b0bc72f..4c7a4f14e 100644 --- a/packages/modular-scripts/src/build/index.ts +++ b/packages/modular-scripts/src/build/index.ts @@ -37,24 +37,13 @@ import { } from './esbuildFileSizeReporter'; import { getDependencyInfo } from '../utils/getDependencyInfo'; import { isReactNewApi } from '../utils/isReactNewApi'; +import { utilizeEsbuild } from '../utils/config'; async function buildStandalone( target: string, type: Extract, ) { - // True if there's no preference set - or the preference is for webpack. - const useWebpack = - !process.env.USE_MODULAR_WEBPACK || - process.env.USE_MODULAR_WEBPACK === 'true'; - - // True if the preferene IS set and the preference is esbuid. - const useEsbuild = - process.env.USE_MODULAR_ESBUILD && - process.env.USE_MODULAR_ESBUILD === 'true'; - - // If you want to use webpack then we'll always use webpack. But if you've indicated - // you want esbuild - then we'll switch you to the new fancy world. - const isEsbuild = !useWebpack || useEsbuild; + const isEsbuild = await utilizeEsbuild(); // Setup Paths const modularRoot = getModularRoot(); @@ -132,6 +121,7 @@ async function buildStandalone( let cssEntryPoint: string | undefined; if (isEsbuild) { + logger.debug('Building with esbuild'); const { default: buildEsbuildApp } = await import( '../esbuild-scripts/build' ); @@ -140,6 +130,7 @@ async function buildStandalone( cssEntryPoint = getEntryPoint(paths, result, '.css'); assets = createEsbuildAssets(paths, result); } else { + logger.debug('Building with Webpack'); // create-react-app doesn't support plain module outputs yet, // so --preserve-modules has no effect here diff --git a/packages/modular-scripts/src/start.ts b/packages/modular-scripts/src/start.ts index f592588f6..526e92d47 100644 --- a/packages/modular-scripts/src/start.ts +++ b/packages/modular-scripts/src/start.ts @@ -16,6 +16,7 @@ import createEsbuildBrowserslistTarget from './utils/createEsbuildBrowserslistTa import prompts from 'prompts'; import { getDependencyInfo } from './utils/getDependencyInfo'; import { isReactNewApi } from './utils/isReactNewApi'; +import { utilizeEsbuild } from './utils/config'; async function start(packageName: string): Promise { let target = packageName; @@ -61,16 +62,6 @@ async function start(packageName: string): Promise { await checkBrowsers(targetPath); - // True if there's no preference set - or the preference is for webpack. - const useWebpack = - !process.env.USE_MODULAR_WEBPACK || - process.env.USE_MODULAR_WEBPACK === 'true'; - - // True if the preference IS set and the preference is esbuild. - const useEsbuild = - process.env.USE_MODULAR_ESBUILD && - process.env.USE_MODULAR_ESBUILD === 'true'; - // Retrieve dependency info for target to inform the build process const { importMap, @@ -102,7 +93,7 @@ async function start(packageName: string): Promise { // If you want to use webpack then we'll always use webpack. But if you've indicated // you want esbuild - then we'll switch you to the new fancy world. - if (!useWebpack || useEsbuild) { + if (await utilizeEsbuild()) { const { default: startEsbuildApp } = await import( './esbuild-scripts/start' ); diff --git a/packages/modular-scripts/src/test/utils.ts b/packages/modular-scripts/src/test/utils.ts index a8d5e2589..08ac4cc1c 100644 --- a/packages/modular-scripts/src/test/utils.ts +++ b/packages/modular-scripts/src/test/utils.ts @@ -98,6 +98,10 @@ export function createModularTestContext(): string { 'last 1 safari version', ], }, + dependencies: { + react: '^18.2.0', + 'react-dom': '^18.2.0', + }, }; fs.writeJSONSync(path.join(tempModularRepo, 'package.json'), packageJson, { diff --git a/packages/modular-scripts/src/utils/config.ts b/packages/modular-scripts/src/utils/config.ts new file mode 100644 index 000000000..858725628 --- /dev/null +++ b/packages/modular-scripts/src/utils/config.ts @@ -0,0 +1,91 @@ +import { cosmiconfig } from 'cosmiconfig'; +import path from 'path'; +import getModularRoot from './getModularRoot'; +import * as logger from './logger'; + +// Where cosmiconfig can look for the configuration +const searchPlaces = [ + '.modular.js', + 'package.json', + `.modularrc`, + `.modularrc.json`, + `.modularrc.yaml`, + `.modularrc.yml`, + `.modularrc.js`, + `.modularrc.cjs`, + `modular.config.js`, + `modular.config.cjs`, +]; + +// Look for configuration file +const modularRoot = getModularRoot(); +const explorer = cosmiconfig('modular', { searchPlaces }); +const configuration = explorer.search(path.join(modularRoot, 'package.json')); + +// Interface with all configurations +interface ConfigObject { + useModularEsbuild: boolean; +} + +type ConfigObjectKey = keyof ConfigObject; + +/** + * Get the configured value for a given configuration field. + * Rejects if no configuration file is present or the queired field is not present. + * @param configEntry Field containing the configuration variable + * @returns Value of configuration variable queried if present + */ +export async function getConfiguration( + configEntry: ConfigObjectKey, +): Promise { + const loadedConfiguration = await configuration; + // Handle no or empty configuration - debug log? don't think we should error should we? + if (loadedConfiguration) { + // Error if configuration doesn't match our interface? + const config = loadedConfiguration.config as ConfigObject; + const value = config[configEntry]; + if (value) { + return value; + } else { + throw new Error( + `No field ${configEntry.toString()} found in configuration file`, + ); + } + } else { + throw new Error( + `Couldn't identify and load a valid modular configuration file`, + ); + } +} + +/** + * Reads env variables and configuration to understand if esbuild or Webpack should be used + * Webpack is used as default if no configuration is set or both are set to true + * Environment variables take precedence over config file + * @returns True if esbuild should be used or false if webpack should be used + */ +export async function utilizeEsbuild(): Promise { + if ( + process.env.USE_MODULAR_WEBPACK === 'true' || + process.env.USE_MODULAR_ESBUILD === 'false' + ) { + return false; + } + if ( + process.env.USE_MODULAR_ESBUILD === 'true' || + process.env.USE_MODULAR_WEBPACK === 'false' + ) { + return true; + } else { + return await getConfiguration('useModularEsbuild') + .then((result) => { + return result; + }) + // Debug logging the errors as it's reasonable for users not to have provided a configuration, + // but it's useful to know while trying to figure out what's going wrong + .catch((err: Error) => { + logger.debug(err.message); + return false; + }); + } +} From dac62893f2e85d53ab15e0bd4d96c3683e0390ec Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Wed, 7 Dec 2022 13:53:40 +0000 Subject: [PATCH 03/27] Update comments --- packages/modular-scripts/src/utils/config.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/modular-scripts/src/utils/config.ts b/packages/modular-scripts/src/utils/config.ts index 858725628..41978f053 100644 --- a/packages/modular-scripts/src/utils/config.ts +++ b/packages/modular-scripts/src/utils/config.ts @@ -32,8 +32,8 @@ type ConfigObjectKey = keyof ConfigObject; /** * Get the configured value for a given configuration field. * Rejects if no configuration file is present or the queired field is not present. - * @param configEntry Field containing the configuration variable - * @returns Value of configuration variable queried if present + * @param configEntry Field containing the configuration variable to read + * @returns Value of configuration field queried if present */ export async function getConfiguration( configEntry: ConfigObjectKey, From 7fb53708ee0fcf901f73163679f70f0e11fd257f Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Thu, 8 Dec 2022 15:27:50 +0000 Subject: [PATCH 04/27] Update config logic --- .../src/__tests__/utils/config.test.ts | 2 +- packages/modular-scripts/src/build/index.ts | 4 +- packages/modular-scripts/src/start.ts | 4 +- .../src/utils/buildImportMap.ts | 5 +- packages/modular-scripts/src/utils/config.ts | 104 ++++++++---------- .../src/utils/rewriteDependencies.ts | 5 +- 6 files changed, 55 insertions(+), 69 deletions(-) diff --git a/packages/modular-scripts/src/__tests__/utils/config.test.ts b/packages/modular-scripts/src/__tests__/utils/config.test.ts index a64697f6c..298370971 100644 --- a/packages/modular-scripts/src/__tests__/utils/config.test.ts +++ b/packages/modular-scripts/src/__tests__/utils/config.test.ts @@ -42,7 +42,7 @@ describe('A simple modular repo with a .modular.js config file', () => { it('builds using webpack if the environment variable is provided as it overrides the config', async () => { const result = await modular(`build test-app --verbose`, tempModularRepo, { env: { - USE_MODULAR_WEBPACK: 'true', + USE_MODULAR_ESBUILD: 'false', }, }); expect(result.stdout).toContain('Building with Webpack'); diff --git a/packages/modular-scripts/src/build/index.ts b/packages/modular-scripts/src/build/index.ts index 4c7a4f14e..6dc550e63 100644 --- a/packages/modular-scripts/src/build/index.ts +++ b/packages/modular-scripts/src/build/index.ts @@ -37,13 +37,13 @@ import { } from './esbuildFileSizeReporter'; import { getDependencyInfo } from '../utils/getDependencyInfo'; import { isReactNewApi } from '../utils/isReactNewApi'; -import { utilizeEsbuild } from '../utils/config'; +import { getConfiguration } from '../utils/config'; async function buildStandalone( target: string, type: Extract, ) { - const isEsbuild = await utilizeEsbuild(); + const isEsbuild = getConfiguration('useModularEsbuild') as boolean; // Setup Paths const modularRoot = getModularRoot(); diff --git a/packages/modular-scripts/src/start.ts b/packages/modular-scripts/src/start.ts index 526e92d47..b2cb20d2f 100644 --- a/packages/modular-scripts/src/start.ts +++ b/packages/modular-scripts/src/start.ts @@ -16,7 +16,7 @@ import createEsbuildBrowserslistTarget from './utils/createEsbuildBrowserslistTa import prompts from 'prompts'; import { getDependencyInfo } from './utils/getDependencyInfo'; import { isReactNewApi } from './utils/isReactNewApi'; -import { utilizeEsbuild } from './utils/config'; +import { getConfiguration } from './utils/config'; async function start(packageName: string): Promise { let target = packageName; @@ -93,7 +93,7 @@ async function start(packageName: string): Promise { // If you want to use webpack then we'll always use webpack. But if you've indicated // you want esbuild - then we'll switch you to the new fancy world. - if (await utilizeEsbuild()) { + if (getConfiguration('useModularEsbuild') as boolean) { const { default: startEsbuildApp } = await import( './esbuild-scripts/start' ); diff --git a/packages/modular-scripts/src/utils/buildImportMap.ts b/packages/modular-scripts/src/utils/buildImportMap.ts index c612572cd..935e07a35 100644 --- a/packages/modular-scripts/src/utils/buildImportMap.ts +++ b/packages/modular-scripts/src/utils/buildImportMap.ts @@ -1,9 +1,8 @@ import { parsePackageName } from './parsePackageName'; import type { Dependency } from '@schemastore/package'; +import { getConfiguration } from './config'; -const externalCdnTemplate = - process.env.EXTERNAL_CDN_TEMPLATE ?? - 'https://cdn.skypack.dev/[name]@[version]'; +const externalCdnTemplate = getConfiguration('externalCdnTemplate') as string; interface BuildImportMapParams { externalDependencies: Dependency; diff --git a/packages/modular-scripts/src/utils/config.ts b/packages/modular-scripts/src/utils/config.ts index 41978f053..c42cc4a12 100644 --- a/packages/modular-scripts/src/utils/config.ts +++ b/packages/modular-scripts/src/utils/config.ts @@ -1,7 +1,6 @@ -import { cosmiconfig } from 'cosmiconfig'; +import { cosmiconfigSync } from 'cosmiconfig'; import path from 'path'; import getModularRoot from './getModularRoot'; -import * as logger from './logger'; // Where cosmiconfig can look for the configuration const searchPlaces = [ @@ -19,73 +18,62 @@ const searchPlaces = [ // Look for configuration file const modularRoot = getModularRoot(); -const explorer = cosmiconfig('modular', { searchPlaces }); -const configuration = explorer.search(path.join(modularRoot, 'package.json')); +const explorer = cosmiconfigSync('modular', { searchPlaces }); +const configResult = explorer.search(path.join(modularRoot, 'package.json')); -// Interface with all configurations +/** + * Configuration file interface + */ interface ConfigObject { - useModularEsbuild: boolean; + useModularEsbuild: boolean | null; + externalCdnTemplate: string | null; } -type ConfigObjectKey = keyof ConfigObject; +/** + * Defaults and env variable overrides + */ +const config = { + useModularEsbuild: { + default: false, + override: + process.env.USE_MODULAR_ESBUILD === undefined + ? undefined + : process.env.USE_MODULAR_ESBUILD === 'true', + }, + externalCdnTemplate: { + default: 'https://cdn.skypack.dev/[name]@[version]', + override: process.env.EXTERNAL_CDN_TEMPLATE, + }, +}; + +type ConfigObjectKey = keyof typeof config; /** * Get the configured value for a given configuration field. - * Rejects if no configuration file is present or the queired field is not present. * @param configEntry Field containing the configuration variable to read - * @returns Value of configuration field queried if present + * @returns configured value: + * - the override environment variable if configured + * - the value stated in the config file if provided + * - the default value if neither environment variable nor the config file are provided + * + * Although return type can be many things, we can use 'as' with confidence to restrict it to the type we're querying: + * + * - 'useModularEsbuild' will always be a boolean, so we can do getConfiguration('useModularEsbuild') as boolean */ -export async function getConfiguration( +export function getConfiguration( configEntry: ConfigObjectKey, -): Promise { - const loadedConfiguration = await configuration; - // Handle no or empty configuration - debug log? don't think we should error should we? - if (loadedConfiguration) { +): string | boolean { + const overrideValue = config[configEntry].override; + const defaultValue = config[configEntry].default; + if (overrideValue !== undefined) { + return overrideValue; + } else if (configResult) { // Error if configuration doesn't match our interface? - const config = loadedConfiguration.config as ConfigObject; - const value = config[configEntry]; - if (value) { - return value; - } else { - throw new Error( - `No field ${configEntry.toString()} found in configuration file`, - ); + const loadedConfig = configResult.config as ConfigObject; + const configValue = loadedConfig[configEntry]; + if (configValue !== null && typeof configValue === typeof defaultValue) { + return configValue; } - } else { - throw new Error( - `Couldn't identify and load a valid modular configuration file`, - ); - } -} - -/** - * Reads env variables and configuration to understand if esbuild or Webpack should be used - * Webpack is used as default if no configuration is set or both are set to true - * Environment variables take precedence over config file - * @returns True if esbuild should be used or false if webpack should be used - */ -export async function utilizeEsbuild(): Promise { - if ( - process.env.USE_MODULAR_WEBPACK === 'true' || - process.env.USE_MODULAR_ESBUILD === 'false' - ) { - return false; - } - if ( - process.env.USE_MODULAR_ESBUILD === 'true' || - process.env.USE_MODULAR_WEBPACK === 'false' - ) { - return true; - } else { - return await getConfiguration('useModularEsbuild') - .then((result) => { - return result; - }) - // Debug logging the errors as it's reasonable for users not to have provided a configuration, - // but it's useful to know while trying to figure out what's going wrong - .catch((err: Error) => { - logger.debug(err.message); - return false; - }); } + return defaultValue; } diff --git a/packages/modular-scripts/src/utils/rewriteDependencies.ts b/packages/modular-scripts/src/utils/rewriteDependencies.ts index 2bfae851b..b05d1e5c8 100644 --- a/packages/modular-scripts/src/utils/rewriteDependencies.ts +++ b/packages/modular-scripts/src/utils/rewriteDependencies.ts @@ -1,8 +1,7 @@ import type { Dependency } from '@schemastore/package'; +import { getConfiguration } from './config'; -const externalCdnTemplate = - process.env.EXTERNAL_CDN_TEMPLATE ?? - 'https://cdn.skypack.dev/[name]@[version]'; +const externalCdnTemplate = getConfiguration('externalCdnTemplate') as string; /** * Rewrite maps of package,version to package,CDN URL From 33742bf1188dec236a7fc140f36faa3b7a54e241 Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Fri, 9 Dec 2022 09:53:04 +0000 Subject: [PATCH 05/27] Fix config --- packages/modular-scripts/src/utils/config.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/modular-scripts/src/utils/config.ts b/packages/modular-scripts/src/utils/config.ts index c42cc4a12..1d8998530 100644 --- a/packages/modular-scripts/src/utils/config.ts +++ b/packages/modular-scripts/src/utils/config.ts @@ -36,9 +36,10 @@ const config = { useModularEsbuild: { default: false, override: - process.env.USE_MODULAR_ESBUILD === undefined - ? undefined - : process.env.USE_MODULAR_ESBUILD === 'true', + process.env.USE_MODULAR_ESBUILD === 'true' || + process.env.USE_MODULAR_ESBUILD === 'false' + ? process.env.USE_MODULAR_ESBUILD === 'true' + : undefined, }, externalCdnTemplate: { default: 'https://cdn.skypack.dev/[name]@[version]', From cde234d066354690c870839a4c376251e898d1c6 Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Fri, 9 Dec 2022 15:33:58 +0000 Subject: [PATCH 06/27] Change the default CDN to esm.sh --- packages/modular-scripts/src/utils/config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/modular-scripts/src/utils/config.ts b/packages/modular-scripts/src/utils/config.ts index 1d8998530..7869b9c75 100644 --- a/packages/modular-scripts/src/utils/config.ts +++ b/packages/modular-scripts/src/utils/config.ts @@ -42,7 +42,7 @@ const config = { : undefined, }, externalCdnTemplate: { - default: 'https://cdn.skypack.dev/[name]@[version]', + default: 'https://esm.sh/[name]@[version]', override: process.env.EXTERNAL_CDN_TEMPLATE, }, }; From dc77942dcdb909be42355f71a5b1918380fab8fd Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Fri, 9 Dec 2022 16:02:38 +0000 Subject: [PATCH 07/27] Update test snapshots for change to esm.sh --- .../src/__tests__/__snapshots__/esmView.test.ts.snap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/modular-scripts/src/__tests__/__snapshots__/esmView.test.ts.snap b/packages/modular-scripts/src/__tests__/__snapshots__/esmView.test.ts.snap index 5565c0c4e..b5d52dbe3 100644 --- a/packages/modular-scripts/src/__tests__/__snapshots__/esmView.test.ts.snap +++ b/packages/modular-scripts/src/__tests__/__snapshots__/esmView.test.ts.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`modular-scripts WHEN building a esm-view THEN matches the entrypoint snapshot 1`] = ` -"import * as t from "https://cdn.skypack.dev/react@17.0.2"; +"import * as t from "https://esm.sh/react@17.0.2"; function e() { return t.createElement( "div", From cec53a1171275a855ac7a83d43283581188a6b4e Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Mon, 12 Dec 2022 10:44:57 +0000 Subject: [PATCH 08/27] More configurables --- packages/modular-scripts/src/build/index.ts | 4 +-- .../src/esbuild-scripts/start/index.ts | 3 +- packages/modular-scripts/src/start.ts | 4 +-- .../src/utils/buildImportMap.ts | 4 +-- packages/modular-scripts/src/utils/config.ts | 28 +++++++++++++++++-- .../src/utils/filterDependencies.ts | 9 ++---- .../src/utils/rewriteDependencies.ts | 4 +-- 7 files changed, 38 insertions(+), 18 deletions(-) diff --git a/packages/modular-scripts/src/build/index.ts b/packages/modular-scripts/src/build/index.ts index 6dc550e63..5f047483a 100644 --- a/packages/modular-scripts/src/build/index.ts +++ b/packages/modular-scripts/src/build/index.ts @@ -37,13 +37,13 @@ import { } from './esbuildFileSizeReporter'; import { getDependencyInfo } from '../utils/getDependencyInfo'; import { isReactNewApi } from '../utils/isReactNewApi'; -import { getConfiguration } from '../utils/config'; +import { getConfig } from '../utils/config'; async function buildStandalone( target: string, type: Extract, ) { - const isEsbuild = getConfiguration('useModularEsbuild') as boolean; + const isEsbuild = getConfig('useModularEsbuild') as boolean; // Setup Paths const modularRoot = getModularRoot(); diff --git a/packages/modular-scripts/src/esbuild-scripts/start/index.ts b/packages/modular-scripts/src/esbuild-scripts/start/index.ts index c015efb46..3a5674959 100644 --- a/packages/modular-scripts/src/esbuild-scripts/start/index.ts +++ b/packages/modular-scripts/src/esbuild-scripts/start/index.ts @@ -35,6 +35,7 @@ import getModularRoot from '../../utils/getModularRoot'; import { createRewriteDependenciesPlugin } from '../plugins/rewriteDependenciesPlugin'; import createEsbuildBrowserslistTarget from '../../utils/createEsbuildBrowserslistTarget'; import { normalizeToPosix } from '../utils/formatPath'; +import { getConfig } from '../../utils/config'; const RUNTIME_DIR = path.join(__dirname, 'runtime'); class DevServer { @@ -392,7 +393,7 @@ export default async function start({ const host = getHost(); const port = await getPort(host); const urls = prepareUrls( - process.env.HTTPS === 'true' ? 'https' : 'http', + (getConfig('https') as boolean) ? 'https' : 'http', host, port, paths.publicUrlOrPath.slice(0, -1), diff --git a/packages/modular-scripts/src/start.ts b/packages/modular-scripts/src/start.ts index b2cb20d2f..61e23cee9 100644 --- a/packages/modular-scripts/src/start.ts +++ b/packages/modular-scripts/src/start.ts @@ -16,7 +16,7 @@ import createEsbuildBrowserslistTarget from './utils/createEsbuildBrowserslistTa import prompts from 'prompts'; import { getDependencyInfo } from './utils/getDependencyInfo'; import { isReactNewApi } from './utils/isReactNewApi'; -import { getConfiguration } from './utils/config'; +import { getConfig } from './utils/config'; async function start(packageName: string): Promise { let target = packageName; @@ -93,7 +93,7 @@ async function start(packageName: string): Promise { // If you want to use webpack then we'll always use webpack. But if you've indicated // you want esbuild - then we'll switch you to the new fancy world. - if (getConfiguration('useModularEsbuild') as boolean) { + if (getConfig('useModularEsbuild') as boolean) { const { default: startEsbuildApp } = await import( './esbuild-scripts/start' ); diff --git a/packages/modular-scripts/src/utils/buildImportMap.ts b/packages/modular-scripts/src/utils/buildImportMap.ts index 935e07a35..21b21f016 100644 --- a/packages/modular-scripts/src/utils/buildImportMap.ts +++ b/packages/modular-scripts/src/utils/buildImportMap.ts @@ -1,8 +1,8 @@ import { parsePackageName } from './parsePackageName'; import type { Dependency } from '@schemastore/package'; -import { getConfiguration } from './config'; +import { getConfig } from './config'; -const externalCdnTemplate = getConfiguration('externalCdnTemplate') as string; +const externalCdnTemplate = getConfig('externalCdnTemplate') as string; interface BuildImportMapParams { externalDependencies: Dependency; diff --git a/packages/modular-scripts/src/utils/config.ts b/packages/modular-scripts/src/utils/config.ts index 7869b9c75..094aff058 100644 --- a/packages/modular-scripts/src/utils/config.ts +++ b/packages/modular-scripts/src/utils/config.ts @@ -27,6 +27,9 @@ const configResult = explorer.search(path.join(modularRoot, 'package.json')); interface ConfigObject { useModularEsbuild: boolean | null; externalCdnTemplate: string | null; + externalBlockList: string[] | null; + externalAllowList: string[] | null; + https: boolean | null; } /** @@ -45,6 +48,25 @@ const config = { default: 'https://esm.sh/[name]@[version]', override: process.env.EXTERNAL_CDN_TEMPLATE, }, + externalBlockList: { + default: [], + override: process.env.EXTERNAL_BLOCK_LIST + ? process.env.EXTERNAL_BLOCK_LIST.split(',') + : undefined, + }, + externalAllowList: { + default: ['**'], + override: process.env.EXTERNAL_ALLOW_LIST + ? process.env.EXTERNAL_ALLOW_LIST.split(',') + : undefined, + }, + https: { + default: false, + override: + process.env.HTTPS === 'true' || process.env.HTTPS === 'false' + ? process.env.HTTPS === 'true' + : undefined, + }, }; type ConfigObjectKey = keyof typeof config; @@ -59,11 +81,11 @@ type ConfigObjectKey = keyof typeof config; * * Although return type can be many things, we can use 'as' with confidence to restrict it to the type we're querying: * - * - 'useModularEsbuild' will always be a boolean, so we can do getConfiguration('useModularEsbuild') as boolean + * - 'useModularEsbuild' will always be a boolean, so we can do getConfig('useModularEsbuild') as boolean */ -export function getConfiguration( +export function getConfig( configEntry: ConfigObjectKey, -): string | boolean { +): string | boolean | string[] { const overrideValue = config[configEntry].override; const defaultValue = config[configEntry].default; if (overrideValue !== undefined) { diff --git a/packages/modular-scripts/src/utils/filterDependencies.ts b/packages/modular-scripts/src/utils/filterDependencies.ts index fc202a00f..f10a5a962 100644 --- a/packages/modular-scripts/src/utils/filterDependencies.ts +++ b/packages/modular-scripts/src/utils/filterDependencies.ts @@ -3,6 +3,7 @@ import * as semver from 'semver'; import * as logger from './logger'; import type { Dependency } from '@schemastore/package'; import type { WorkspaceInfo } from './getWorkspaceInfo'; +import { getConfig } from './config'; interface FilteredDependencies { external: Dependency; @@ -17,13 +18,9 @@ export function filterDependencies({ dependencies: Dependency; workspaceInfo: WorkspaceInfo; }): FilteredDependencies { - const externalBlockList = process.env.EXTERNAL_BLOCK_LIST - ? process.env.EXTERNAL_BLOCK_LIST.split(',') - : undefined; + const externalBlockList = getConfig('externalBlockList') as string[]; - const externalAllowList = process.env.EXTERNAL_ALLOW_LIST - ? process.env.EXTERNAL_ALLOW_LIST.split(',') - : undefined; + const externalAllowList = getConfig('externalAllowList') as string[]; return partitionDependencies({ dependencies, diff --git a/packages/modular-scripts/src/utils/rewriteDependencies.ts b/packages/modular-scripts/src/utils/rewriteDependencies.ts index b05d1e5c8..8825ebbfe 100644 --- a/packages/modular-scripts/src/utils/rewriteDependencies.ts +++ b/packages/modular-scripts/src/utils/rewriteDependencies.ts @@ -1,7 +1,7 @@ import type { Dependency } from '@schemastore/package'; -import { getConfiguration } from './config'; +import { getConfig } from './config'; -const externalCdnTemplate = getConfiguration('externalCdnTemplate') as string; +const externalCdnTemplate = getConfig('externalCdnTemplate') as string; /** * Rewrite maps of package,version to package,CDN URL From f854b5e352415ca1e390a9294e50d422f7cc98c7 Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Mon, 12 Dec 2022 16:27:12 +0000 Subject: [PATCH 09/27] https config --- .../modular-scripts/react-scripts/config/getHttpsConfig.js | 5 +++-- packages/modular-scripts/react-scripts/scripts/start.js | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/modular-scripts/react-scripts/config/getHttpsConfig.js b/packages/modular-scripts/react-scripts/config/getHttpsConfig.js index c055b58bc..db69f6f31 100644 --- a/packages/modular-scripts/react-scripts/config/getHttpsConfig.js +++ b/packages/modular-scripts/react-scripts/config/getHttpsConfig.js @@ -5,6 +5,7 @@ const path = require('path'); const crypto = require('crypto'); const chalk = require('chalk'); const paths = require('./paths'); +const { getConfig } = require('../../src/utils/config'); // Ensure the certificate and key provided are valid and if not // throw an easy to debug error @@ -46,8 +47,8 @@ function readEnvFile(file, type) { // Get the https config // Return cert files if provided in env, otherwise just true or false function getHttpsConfig() { - const { SSL_CRT_FILE, SSL_KEY_FILE, HTTPS } = process.env; - const isHttps = HTTPS === 'true'; + const isHttps = getConfig('https'); + const { SSL_CRT_FILE, SSL_KEY_FILE } = process.env; if (isHttps && SSL_CRT_FILE && SSL_KEY_FILE) { const crtFile = path.resolve(paths.appPath, SSL_CRT_FILE); diff --git a/packages/modular-scripts/react-scripts/scripts/start.js b/packages/modular-scripts/react-scripts/scripts/start.js index db5f399ba..17c3a5763 100644 --- a/packages/modular-scripts/react-scripts/scripts/start.js +++ b/packages/modular-scripts/react-scripts/scripts/start.js @@ -24,6 +24,7 @@ const isCI = require('is-ci'); const paths = require('../config/paths'); const configFactory = require('../config/webpack.config'); const createDevServerConfig = require('../config/webpackDevServer.config'); +const { getConfig } = require('../../src/utils/config'); const isInteractive = process.stdout.isTTY; @@ -60,7 +61,7 @@ choosePort(HOST, DEFAULT_PORT) level: 'none', }; - const protocol = process.env.HTTPS === 'true' ? 'https' : 'http'; + const protocol = getConfig('https') ? 'https' : 'http'; const appName = require(paths.appPackageJson).name; const useTypeScript = !isCI && fs.existsSync(paths.appTsConfig); From 249390f97982f8c092ec165c5bd9001b3ff68c3d Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Tue, 13 Dec 2022 12:31:55 +0000 Subject: [PATCH 10/27] Let JS files in react-scripts use config.ts using ts-node/register --- packages/modular-scripts/package.json | 1 + .../react-scripts/config/getHttpsConfig.js | 1 + .../react-scripts/config/webpackDevServer.config.js | 4 +++- .../modular-scripts/react-scripts/scripts/start.js | 10 +++++----- .../src/esbuild-scripts/start/utils/getHost.ts | 8 +++++--- packages/modular-scripts/src/utils/config.ts | 5 +++++ yarn.lock | 2 +- 7 files changed, 21 insertions(+), 10 deletions(-) diff --git a/packages/modular-scripts/package.json b/packages/modular-scripts/package.json index c835eb81f..5b919d67c 100644 --- a/packages/modular-scripts/package.json +++ b/packages/modular-scripts/package.json @@ -123,6 +123,7 @@ "tmp": "^0.2.1", "ts-jest": "^29.0.0", "ts-morph": "^14.0.0", + "ts-node": "^10.9.1", "update-notifier": "5.1.0", "url-loader": "4.1.1", "validate-npm-package-name": "^4.0.0", diff --git a/packages/modular-scripts/react-scripts/config/getHttpsConfig.js b/packages/modular-scripts/react-scripts/config/getHttpsConfig.js index db69f6f31..a58957a27 100644 --- a/packages/modular-scripts/react-scripts/config/getHttpsConfig.js +++ b/packages/modular-scripts/react-scripts/config/getHttpsConfig.js @@ -1,5 +1,6 @@ 'use strict'; +require('ts-node/register'); const fs = require('fs'); const path = require('path'); const crypto = require('crypto'); diff --git a/packages/modular-scripts/react-scripts/config/webpackDevServer.config.js b/packages/modular-scripts/react-scripts/config/webpackDevServer.config.js index a1cc6541b..03c1c8e6e 100644 --- a/packages/modular-scripts/react-scripts/config/webpackDevServer.config.js +++ b/packages/modular-scripts/react-scripts/config/webpackDevServer.config.js @@ -1,5 +1,6 @@ 'use strict'; +require('ts-node/register'); const fs = require('fs'); const errorOverlayMiddleware = require('../../react-dev-utils/errorOverlayMiddleware'); const evalSourceMapMiddleware = require('../../react-dev-utils/evalSourceMapMiddleware'); @@ -8,8 +9,9 @@ const ignoredFiles = require('../../react-dev-utils/ignoredFiles'); const redirectServedPath = require('../../react-dev-utils/redirectServedPathMiddleware'); const paths = require('./paths'); const getHttpsConfig = require('./getHttpsConfig'); +const { getConfig } = require('../../src/utils/config'); -const host = process.env.HOST || '0.0.0.0'; +const host = getConfig('host'); const sockHost = process.env.WDS_SOCKET_HOST; const sockPath = process.env.WDS_SOCKET_PATH; // default: '/ws' const sockPort = process.env.WDS_SOCKET_PORT; diff --git a/packages/modular-scripts/react-scripts/scripts/start.js b/packages/modular-scripts/react-scripts/scripts/start.js index 17c3a5763..6feab43d3 100644 --- a/packages/modular-scripts/react-scripts/scripts/start.js +++ b/packages/modular-scripts/react-scripts/scripts/start.js @@ -7,6 +7,8 @@ process.on('unhandledRejection', (err) => { throw err; }); +require('ts-node/register'); +const { getConfig } = require('../../src/utils/config'); const fs = require('fs'); const chalk = require('chalk'); const webpack = require('webpack'); @@ -24,19 +26,17 @@ const isCI = require('is-ci'); const paths = require('../config/paths'); const configFactory = require('../config/webpack.config'); const createDevServerConfig = require('../config/webpackDevServer.config'); -const { getConfig } = require('../../src/utils/config'); - const isInteractive = process.stdout.isTTY; // Tools like Cloud9 rely on this. const DEFAULT_PORT = parseInt(process.env.PORT, 10) || 3000; -const HOST = process.env.HOST || '0.0.0.0'; +const HOST = getConfig('host'); -if (process.env.HOST) { +if (HOST !== '0.0.0.0') { log( chalk.cyan( `Attempting to bind to HOST environment variable: ${chalk.yellow( - chalk.bold(process.env.HOST), + chalk.bold(HOST), )}`, ), ); diff --git a/packages/modular-scripts/src/esbuild-scripts/start/utils/getHost.ts b/packages/modular-scripts/src/esbuild-scripts/start/utils/getHost.ts index 52970d33b..8fd78515d 100644 --- a/packages/modular-scripts/src/esbuild-scripts/start/utils/getHost.ts +++ b/packages/modular-scripts/src/esbuild-scripts/start/utils/getHost.ts @@ -2,13 +2,15 @@ import chalk from 'chalk'; import memoize from '../../../utils/memoize'; import * as logger from '../../../utils/logger'; +import { getConfig } from '../../../utils/config'; const getHost = memoize(() => { - if (process.env.HOST) { + const HOST = getConfig('host') as string; + if (HOST !== '0.0.0.0') { logger.log( chalk.cyan( `Attempting to bind to HOST environment variable: ${chalk.yellow( - chalk.bold(process.env.HOST), + chalk.bold(HOST), )}`, ), ); @@ -20,7 +22,7 @@ const getHost = memoize(() => { ); logger.log(); } - return process.env.HOST || '0.0.0.0'; + return HOST; }); export default getHost; diff --git a/packages/modular-scripts/src/utils/config.ts b/packages/modular-scripts/src/utils/config.ts index 094aff058..0719afd78 100644 --- a/packages/modular-scripts/src/utils/config.ts +++ b/packages/modular-scripts/src/utils/config.ts @@ -30,6 +30,7 @@ interface ConfigObject { externalBlockList: string[] | null; externalAllowList: string[] | null; https: boolean | null; + host: string | null; } /** @@ -67,6 +68,10 @@ const config = { ? process.env.HTTPS === 'true' : undefined, }, + host: { + default: '0.0.0.0', + override: process.env.HOST, + }, }; type ConfigObjectKey = keyof typeof config; diff --git a/yarn.lock b/yarn.lock index 3f35dd93a..562bf0a3b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12204,7 +12204,7 @@ ts-morph@^14.0.0: "@ts-morph/common" "~0.13.0" code-block-writer "^11.0.0" -ts-node@10.9.1: +ts-node@10.9.1, ts-node@^10.9.1: version "10.9.1" resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== From 7e08f6a2434cee1986db42f87ab11f1ddf5ea22c Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Tue, 13 Dec 2022 14:11:19 +0000 Subject: [PATCH 11/27] Fix ts-node register --- .../react-scripts/config/webpackDevServer.config.js | 2 +- packages/modular-scripts/react-scripts/scripts/start.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/modular-scripts/react-scripts/config/webpackDevServer.config.js b/packages/modular-scripts/react-scripts/config/webpackDevServer.config.js index 03c1c8e6e..2159f7aa2 100644 --- a/packages/modular-scripts/react-scripts/config/webpackDevServer.config.js +++ b/packages/modular-scripts/react-scripts/config/webpackDevServer.config.js @@ -1,6 +1,6 @@ 'use strict'; -require('ts-node/register'); +require('ts-node').register(); const fs = require('fs'); const errorOverlayMiddleware = require('../../react-dev-utils/errorOverlayMiddleware'); const evalSourceMapMiddleware = require('../../react-dev-utils/evalSourceMapMiddleware'); diff --git a/packages/modular-scripts/react-scripts/scripts/start.js b/packages/modular-scripts/react-scripts/scripts/start.js index 6feab43d3..4af83c04c 100644 --- a/packages/modular-scripts/react-scripts/scripts/start.js +++ b/packages/modular-scripts/react-scripts/scripts/start.js @@ -7,7 +7,7 @@ process.on('unhandledRejection', (err) => { throw err; }); -require('ts-node/register'); +require('ts-node').register(); const { getConfig } = require('../../src/utils/config'); const fs = require('fs'); const chalk = require('chalk'); From b9b4f5bb10f983936d4aff4d4e6f72dfbb256eb0 Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Tue, 13 Dec 2022 14:23:13 +0000 Subject: [PATCH 12/27] More require ts-node register --- packages/modular-scripts/react-scripts/config/getHttpsConfig.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/modular-scripts/react-scripts/config/getHttpsConfig.js b/packages/modular-scripts/react-scripts/config/getHttpsConfig.js index a58957a27..1c997a447 100644 --- a/packages/modular-scripts/react-scripts/config/getHttpsConfig.js +++ b/packages/modular-scripts/react-scripts/config/getHttpsConfig.js @@ -1,6 +1,6 @@ 'use strict'; -require('ts-node/register'); +require('ts-node').register(); const fs = require('fs'); const path = require('path'); const crypto = require('crypto'); From 675b10f5b3a66dc6ff5382679ac282d25d98d728 Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Wed, 14 Dec 2022 15:01:41 +0000 Subject: [PATCH 13/27] Remove HOST and HTTPS config --- .../react-scripts/config/getHttpsConfig.js | 6 ++---- .../react-scripts/config/webpackDevServer.config.js | 4 +--- .../modular-scripts/react-scripts/scripts/start.js | 11 ++++------- .../src/esbuild-scripts/start/index.ts | 3 +-- .../src/esbuild-scripts/start/utils/getHost.ts | 8 +++----- packages/modular-scripts/src/utils/config.ts | 13 ------------- 6 files changed, 11 insertions(+), 34 deletions(-) diff --git a/packages/modular-scripts/react-scripts/config/getHttpsConfig.js b/packages/modular-scripts/react-scripts/config/getHttpsConfig.js index 1c997a447..c055b58bc 100644 --- a/packages/modular-scripts/react-scripts/config/getHttpsConfig.js +++ b/packages/modular-scripts/react-scripts/config/getHttpsConfig.js @@ -1,12 +1,10 @@ 'use strict'; -require('ts-node').register(); const fs = require('fs'); const path = require('path'); const crypto = require('crypto'); const chalk = require('chalk'); const paths = require('./paths'); -const { getConfig } = require('../../src/utils/config'); // Ensure the certificate and key provided are valid and if not // throw an easy to debug error @@ -48,8 +46,8 @@ function readEnvFile(file, type) { // Get the https config // Return cert files if provided in env, otherwise just true or false function getHttpsConfig() { - const isHttps = getConfig('https'); - const { SSL_CRT_FILE, SSL_KEY_FILE } = process.env; + const { SSL_CRT_FILE, SSL_KEY_FILE, HTTPS } = process.env; + const isHttps = HTTPS === 'true'; if (isHttps && SSL_CRT_FILE && SSL_KEY_FILE) { const crtFile = path.resolve(paths.appPath, SSL_CRT_FILE); diff --git a/packages/modular-scripts/react-scripts/config/webpackDevServer.config.js b/packages/modular-scripts/react-scripts/config/webpackDevServer.config.js index 2159f7aa2..a1cc6541b 100644 --- a/packages/modular-scripts/react-scripts/config/webpackDevServer.config.js +++ b/packages/modular-scripts/react-scripts/config/webpackDevServer.config.js @@ -1,6 +1,5 @@ 'use strict'; -require('ts-node').register(); const fs = require('fs'); const errorOverlayMiddleware = require('../../react-dev-utils/errorOverlayMiddleware'); const evalSourceMapMiddleware = require('../../react-dev-utils/evalSourceMapMiddleware'); @@ -9,9 +8,8 @@ const ignoredFiles = require('../../react-dev-utils/ignoredFiles'); const redirectServedPath = require('../../react-dev-utils/redirectServedPathMiddleware'); const paths = require('./paths'); const getHttpsConfig = require('./getHttpsConfig'); -const { getConfig } = require('../../src/utils/config'); -const host = getConfig('host'); +const host = process.env.HOST || '0.0.0.0'; const sockHost = process.env.WDS_SOCKET_HOST; const sockPath = process.env.WDS_SOCKET_PATH; // default: '/ws' const sockPort = process.env.WDS_SOCKET_PORT; diff --git a/packages/modular-scripts/react-scripts/scripts/start.js b/packages/modular-scripts/react-scripts/scripts/start.js index 4af83c04c..5c2695973 100644 --- a/packages/modular-scripts/react-scripts/scripts/start.js +++ b/packages/modular-scripts/react-scripts/scripts/start.js @@ -7,8 +7,6 @@ process.on('unhandledRejection', (err) => { throw err; }); -require('ts-node').register(); -const { getConfig } = require('../../src/utils/config'); const fs = require('fs'); const chalk = require('chalk'); const webpack = require('webpack'); @@ -30,13 +28,12 @@ const isInteractive = process.stdout.isTTY; // Tools like Cloud9 rely on this. const DEFAULT_PORT = parseInt(process.env.PORT, 10) || 3000; -const HOST = getConfig('host'); - -if (HOST !== '0.0.0.0') { +const HOST = process.env.HOST || '0.0.0.0'; +if (process.env.HOST) { log( chalk.cyan( `Attempting to bind to HOST environment variable: ${chalk.yellow( - chalk.bold(HOST), + chalk.bold(process.env.HOST), )}`, ), ); @@ -61,7 +58,7 @@ choosePort(HOST, DEFAULT_PORT) level: 'none', }; - const protocol = getConfig('https') ? 'https' : 'http'; + const protocol = process.env.HTTPS === 'true' ? 'https' : 'http'; const appName = require(paths.appPackageJson).name; const useTypeScript = !isCI && fs.existsSync(paths.appTsConfig); diff --git a/packages/modular-scripts/src/esbuild-scripts/start/index.ts b/packages/modular-scripts/src/esbuild-scripts/start/index.ts index 3a5674959..c015efb46 100644 --- a/packages/modular-scripts/src/esbuild-scripts/start/index.ts +++ b/packages/modular-scripts/src/esbuild-scripts/start/index.ts @@ -35,7 +35,6 @@ import getModularRoot from '../../utils/getModularRoot'; import { createRewriteDependenciesPlugin } from '../plugins/rewriteDependenciesPlugin'; import createEsbuildBrowserslistTarget from '../../utils/createEsbuildBrowserslistTarget'; import { normalizeToPosix } from '../utils/formatPath'; -import { getConfig } from '../../utils/config'; const RUNTIME_DIR = path.join(__dirname, 'runtime'); class DevServer { @@ -393,7 +392,7 @@ export default async function start({ const host = getHost(); const port = await getPort(host); const urls = prepareUrls( - (getConfig('https') as boolean) ? 'https' : 'http', + process.env.HTTPS === 'true' ? 'https' : 'http', host, port, paths.publicUrlOrPath.slice(0, -1), diff --git a/packages/modular-scripts/src/esbuild-scripts/start/utils/getHost.ts b/packages/modular-scripts/src/esbuild-scripts/start/utils/getHost.ts index 8fd78515d..52970d33b 100644 --- a/packages/modular-scripts/src/esbuild-scripts/start/utils/getHost.ts +++ b/packages/modular-scripts/src/esbuild-scripts/start/utils/getHost.ts @@ -2,15 +2,13 @@ import chalk from 'chalk'; import memoize from '../../../utils/memoize'; import * as logger from '../../../utils/logger'; -import { getConfig } from '../../../utils/config'; const getHost = memoize(() => { - const HOST = getConfig('host') as string; - if (HOST !== '0.0.0.0') { + if (process.env.HOST) { logger.log( chalk.cyan( `Attempting to bind to HOST environment variable: ${chalk.yellow( - chalk.bold(HOST), + chalk.bold(process.env.HOST), )}`, ), ); @@ -22,7 +20,7 @@ const getHost = memoize(() => { ); logger.log(); } - return HOST; + return process.env.HOST || '0.0.0.0'; }); export default getHost; diff --git a/packages/modular-scripts/src/utils/config.ts b/packages/modular-scripts/src/utils/config.ts index 0719afd78..bb715a4f3 100644 --- a/packages/modular-scripts/src/utils/config.ts +++ b/packages/modular-scripts/src/utils/config.ts @@ -29,8 +29,6 @@ interface ConfigObject { externalCdnTemplate: string | null; externalBlockList: string[] | null; externalAllowList: string[] | null; - https: boolean | null; - host: string | null; } /** @@ -61,17 +59,6 @@ const config = { ? process.env.EXTERNAL_ALLOW_LIST.split(',') : undefined, }, - https: { - default: false, - override: - process.env.HTTPS === 'true' || process.env.HTTPS === 'false' - ? process.env.HTTPS === 'true' - : undefined, - }, - host: { - default: '0.0.0.0', - override: process.env.HOST, - }, }; type ConfigObjectKey = keyof typeof config; From 73fee89e7f654562a3b62eacf71e7bfc1c31a5e8 Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Thu, 15 Dec 2022 13:58:16 +0000 Subject: [PATCH 14/27] Configurable PUBLIC_URL & GENERATE_SOURCEMAP --- packages/modular-scripts/package.json | 1 - .../react-scripts/config/paths.js | 2 +- .../react-scripts/config/webpack.config.js | 2 +- packages/modular-scripts/src/build/index.ts | 2 ++ packages/modular-scripts/src/start.ts | 2 ++ packages/modular-scripts/src/utils/config.ts | 21 +++++++++++++++++-- yarn.lock | 2 +- 7 files changed, 26 insertions(+), 6 deletions(-) diff --git a/packages/modular-scripts/package.json b/packages/modular-scripts/package.json index 5b919d67c..c835eb81f 100644 --- a/packages/modular-scripts/package.json +++ b/packages/modular-scripts/package.json @@ -123,7 +123,6 @@ "tmp": "^0.2.1", "ts-jest": "^29.0.0", "ts-morph": "^14.0.0", - "ts-node": "^10.9.1", "update-notifier": "5.1.0", "url-loader": "4.1.1", "validate-npm-package-name": "^4.0.0", diff --git a/packages/modular-scripts/react-scripts/config/paths.js b/packages/modular-scripts/react-scripts/config/paths.js index 0cdcf2f27..f9325447e 100644 --- a/packages/modular-scripts/react-scripts/config/paths.js +++ b/packages/modular-scripts/react-scripts/config/paths.js @@ -46,7 +46,7 @@ const resolveModular = (relativePath) => const publicUrlOrPath = getPublicUrlOrPath( process.env.NODE_ENV === 'development', require(resolveApp('package.json')).homepage, - process.env.PUBLIC_URL, + process.env.INTERNAL_PUBLIC_URL, ); const buildPath = path.join(modularRoot, 'dist', modularPackageName); diff --git a/packages/modular-scripts/react-scripts/config/webpack.config.js b/packages/modular-scripts/react-scripts/config/webpack.config.js index 6dba0bd2e..cc5a2a282 100644 --- a/packages/modular-scripts/react-scripts/config/webpack.config.js +++ b/packages/modular-scripts/react-scripts/config/webpack.config.js @@ -37,7 +37,7 @@ const useReactCreateRoot = getEnvironmentVariable( const styleImports = getEnvironmentVariable('MODULAR_STYLE_IMPORT_MAPS', []); // Source maps are resource heavy and can cause out of memory issue for large source files. -const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false'; +const shouldUseSourceMap = process.env.INTERNAL_GENERATE_SOURCEMAP !== 'false'; const imageInlineSizeLimit = parseInt( process.env.IMAGE_INLINE_SIZE_LIMIT || '10000', diff --git a/packages/modular-scripts/src/build/index.ts b/packages/modular-scripts/src/build/index.ts index 5f047483a..78d842872 100644 --- a/packages/modular-scripts/src/build/index.ts +++ b/packages/modular-scripts/src/build/index.ts @@ -151,6 +151,8 @@ async function buildStandalone( MODULAR_IS_APP: JSON.stringify(isApp), MODULAR_IMPORT_MAP: JSON.stringify(Object.fromEntries(importMap || [])), MODULAR_USE_REACT_CREATE_ROOT: JSON.stringify(useReactCreateRoot), + INTERNAL_PUBLIC_URL: getConfig('publicUrl') as string, + INTERNAL_GENERATE_SOURCEMAP: getConfig('generateSourceMap') as string, }, }); diff --git a/packages/modular-scripts/src/start.ts b/packages/modular-scripts/src/start.ts index 61e23cee9..1e370bbc0 100644 --- a/packages/modular-scripts/src/start.ts +++ b/packages/modular-scripts/src/start.ts @@ -128,6 +128,8 @@ async function start(packageName: string): Promise { MODULAR_IMPORT_MAP: JSON.stringify(Object.fromEntries(importMap || [])), MODULAR_USE_REACT_CREATE_ROOT: JSON.stringify(useReactCreateRoot), MODULAR_STYLE_IMPORT_MAPS: JSON.stringify([...styleImports]), + INTERNAL_PUBLIC_URL: getConfig('publicUrl') as string, + INTERNAL_GENERATE_SOURCEMAP: getConfig('generateSourceMap') as string, }, }); } diff --git a/packages/modular-scripts/src/utils/config.ts b/packages/modular-scripts/src/utils/config.ts index bb715a4f3..92fa91ff8 100644 --- a/packages/modular-scripts/src/utils/config.ts +++ b/packages/modular-scripts/src/utils/config.ts @@ -29,6 +29,8 @@ interface ConfigObject { externalCdnTemplate: string | null; externalBlockList: string[] | null; externalAllowList: string[] | null; + publicUrl: string | null; + generateSourceMap: boolean | null; } /** @@ -59,6 +61,18 @@ const config = { ? process.env.EXTERNAL_ALLOW_LIST.split(',') : undefined, }, + publicUrl: { + default: undefined, + override: process.env.PUBLIC_URL, + }, + generateSourceMap: { + default: true, + override: + process.env.GENERATE_SOURCEMAP === 'true' || + process.env.GENERATE_SOURCEMAP === 'false' + ? process.env.GENERATE_SOURCEMAP === 'true' + : undefined, + }, }; type ConfigObjectKey = keyof typeof config; @@ -77,7 +91,7 @@ type ConfigObjectKey = keyof typeof config; */ export function getConfig( configEntry: ConfigObjectKey, -): string | boolean | string[] { +): string | boolean | string[] | undefined { const overrideValue = config[configEntry].override; const defaultValue = config[configEntry].default; if (overrideValue !== undefined) { @@ -86,7 +100,10 @@ export function getConfig( // Error if configuration doesn't match our interface? const loadedConfig = configResult.config as ConfigObject; const configValue = loadedConfig[configEntry]; - if (configValue !== null && typeof configValue === typeof defaultValue) { + if ( + configValue !== null && + (typeof configValue === typeof defaultValue || configValue === undefined) + ) { return configValue; } } diff --git a/yarn.lock b/yarn.lock index 562bf0a3b..3f35dd93a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12204,7 +12204,7 @@ ts-morph@^14.0.0: "@ts-morph/common" "~0.13.0" code-block-writer "^11.0.0" -ts-node@10.9.1, ts-node@^10.9.1: +ts-node@10.9.1: version "10.9.1" resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== From b08bd3735a40a96e836c3f4013cb33fde9afece0 Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Thu, 15 Dec 2022 14:30:30 +0000 Subject: [PATCH 15/27] Undo changes for PUBLIC_URL & GENERATE_SOURCEMAP config --- packages/modular-scripts/react-scripts/config/paths.js | 2 +- packages/modular-scripts/react-scripts/config/webpack.config.js | 2 +- packages/modular-scripts/src/build/index.ts | 2 -- packages/modular-scripts/src/start.ts | 2 -- 4 files changed, 2 insertions(+), 6 deletions(-) diff --git a/packages/modular-scripts/react-scripts/config/paths.js b/packages/modular-scripts/react-scripts/config/paths.js index f9325447e..0cdcf2f27 100644 --- a/packages/modular-scripts/react-scripts/config/paths.js +++ b/packages/modular-scripts/react-scripts/config/paths.js @@ -46,7 +46,7 @@ const resolveModular = (relativePath) => const publicUrlOrPath = getPublicUrlOrPath( process.env.NODE_ENV === 'development', require(resolveApp('package.json')).homepage, - process.env.INTERNAL_PUBLIC_URL, + process.env.PUBLIC_URL, ); const buildPath = path.join(modularRoot, 'dist', modularPackageName); diff --git a/packages/modular-scripts/react-scripts/config/webpack.config.js b/packages/modular-scripts/react-scripts/config/webpack.config.js index cc5a2a282..6dba0bd2e 100644 --- a/packages/modular-scripts/react-scripts/config/webpack.config.js +++ b/packages/modular-scripts/react-scripts/config/webpack.config.js @@ -37,7 +37,7 @@ const useReactCreateRoot = getEnvironmentVariable( const styleImports = getEnvironmentVariable('MODULAR_STYLE_IMPORT_MAPS', []); // Source maps are resource heavy and can cause out of memory issue for large source files. -const shouldUseSourceMap = process.env.INTERNAL_GENERATE_SOURCEMAP !== 'false'; +const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false'; const imageInlineSizeLimit = parseInt( process.env.IMAGE_INLINE_SIZE_LIMIT || '10000', diff --git a/packages/modular-scripts/src/build/index.ts b/packages/modular-scripts/src/build/index.ts index 78d842872..5f047483a 100644 --- a/packages/modular-scripts/src/build/index.ts +++ b/packages/modular-scripts/src/build/index.ts @@ -151,8 +151,6 @@ async function buildStandalone( MODULAR_IS_APP: JSON.stringify(isApp), MODULAR_IMPORT_MAP: JSON.stringify(Object.fromEntries(importMap || [])), MODULAR_USE_REACT_CREATE_ROOT: JSON.stringify(useReactCreateRoot), - INTERNAL_PUBLIC_URL: getConfig('publicUrl') as string, - INTERNAL_GENERATE_SOURCEMAP: getConfig('generateSourceMap') as string, }, }); diff --git a/packages/modular-scripts/src/start.ts b/packages/modular-scripts/src/start.ts index 1e370bbc0..61e23cee9 100644 --- a/packages/modular-scripts/src/start.ts +++ b/packages/modular-scripts/src/start.ts @@ -128,8 +128,6 @@ async function start(packageName: string): Promise { MODULAR_IMPORT_MAP: JSON.stringify(Object.fromEntries(importMap || [])), MODULAR_USE_REACT_CREATE_ROOT: JSON.stringify(useReactCreateRoot), MODULAR_STYLE_IMPORT_MAPS: JSON.stringify([...styleImports]), - INTERNAL_PUBLIC_URL: getConfig('publicUrl') as string, - INTERNAL_GENERATE_SOURCEMAP: getConfig('generateSourceMap') as string, }, }); } From 5054f28b6045dd73b11d33f2aefad147b780e200 Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Thu, 15 Dec 2022 15:10:29 +0000 Subject: [PATCH 16/27] 2nd attempt re-implementing config for generate sourcemap and public url --- packages/modular-scripts/package.json | 1 + packages/modular-scripts/react-scripts/config/paths.js | 4 +++- .../react-scripts/config/webpack.config.js | 2 +- .../modular-scripts/src/build/buildPackage/makeBundle.ts | 3 ++- packages/modular-scripts/src/build/index.ts | 2 ++ .../src/esbuild-scripts/config/createEsbuildConfig.ts | 3 ++- packages/modular-scripts/src/start.ts | 2 ++ packages/modular-scripts/src/utils/config.ts | 9 +++------ packages/modular-scripts/src/utils/createPaths.ts | 4 +++- yarn.lock | 5 +++++ 10 files changed, 24 insertions(+), 11 deletions(-) diff --git a/packages/modular-scripts/package.json b/packages/modular-scripts/package.json index c835eb81f..8249b2c24 100644 --- a/packages/modular-scripts/package.json +++ b/packages/modular-scripts/package.json @@ -36,6 +36,7 @@ "@rollup/plugin-node-resolve": "13.3.0", "@svgr/core": "6.2.1", "@svgr/webpack": "6.2.1", + "@types/lodash": "^4.14.191", "@types/micromatch": "4.0.2", "@types/npmcli__arborist": "^5.6.0", "@types/yarnpkg__lockfile": "^1.1.5", diff --git a/packages/modular-scripts/react-scripts/config/paths.js b/packages/modular-scripts/react-scripts/config/paths.js index 0cdcf2f27..902f89e44 100644 --- a/packages/modular-scripts/react-scripts/config/paths.js +++ b/packages/modular-scripts/react-scripts/config/paths.js @@ -46,7 +46,9 @@ const resolveModular = (relativePath) => const publicUrlOrPath = getPublicUrlOrPath( process.env.NODE_ENV === 'development', require(resolveApp('package.json')).homepage, - process.env.PUBLIC_URL, + process.env.INTERNAL_PUBLIC_URL === '' + ? undefined + : process.env.INTERNAL_PUBLIC_URL, ); const buildPath = path.join(modularRoot, 'dist', modularPackageName); diff --git a/packages/modular-scripts/react-scripts/config/webpack.config.js b/packages/modular-scripts/react-scripts/config/webpack.config.js index 6dba0bd2e..cc5a2a282 100644 --- a/packages/modular-scripts/react-scripts/config/webpack.config.js +++ b/packages/modular-scripts/react-scripts/config/webpack.config.js @@ -37,7 +37,7 @@ const useReactCreateRoot = getEnvironmentVariable( const styleImports = getEnvironmentVariable('MODULAR_STYLE_IMPORT_MAPS', []); // Source maps are resource heavy and can cause out of memory issue for large source files. -const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false'; +const shouldUseSourceMap = process.env.INTERNAL_GENERATE_SOURCEMAP !== 'false'; const imageInlineSizeLimit = parseInt( process.env.IMAGE_INLINE_SIZE_LIMIT || '10000', diff --git a/packages/modular-scripts/src/build/buildPackage/makeBundle.ts b/packages/modular-scripts/src/build/buildPackage/makeBundle.ts index 91cb475fb..c2ae05076 100644 --- a/packages/modular-scripts/src/build/buildPackage/makeBundle.ts +++ b/packages/modular-scripts/src/build/buildPackage/makeBundle.ts @@ -20,6 +20,7 @@ import getRelativeLocation from '../../utils/getRelativeLocation'; import createEsbuildBrowserslistTarget from '../../utils/createEsbuildBrowserslistTarget'; import type { ModularPackageJson } from '@modular-scripts/modular-types'; +import { getConfig } from '../../utils/config'; const outputDirectory = 'dist'; const extensions = ['.ts', '.tsx', '.js', '.jsx']; @@ -107,7 +108,7 @@ export async function makeBundle( const outputOptions: rollup.OutputOptions = { freeze: false, - sourcemap: true, // TODO: read this off env + sourcemap: getConfig('generateSourceMap') as boolean, sourcemapPathTransform(relativeSourcePath: string, sourceMapPath: string) { // make source map input files relative to the `${packagePath}/dist-${format}` within // the package directory diff --git a/packages/modular-scripts/src/build/index.ts b/packages/modular-scripts/src/build/index.ts index 5f047483a..f45659dc5 100644 --- a/packages/modular-scripts/src/build/index.ts +++ b/packages/modular-scripts/src/build/index.ts @@ -151,6 +151,8 @@ async function buildStandalone( MODULAR_IS_APP: JSON.stringify(isApp), MODULAR_IMPORT_MAP: JSON.stringify(Object.fromEntries(importMap || [])), MODULAR_USE_REACT_CREATE_ROOT: JSON.stringify(useReactCreateRoot), + INTERNAL_PUBLIC_URL: getConfig('publicUrl') as string, + INTERNAL_GENERATE_SOURCEMAP: String(getConfig('generateSourceMap')), }, }); diff --git a/packages/modular-scripts/src/esbuild-scripts/config/createEsbuildConfig.ts b/packages/modular-scripts/src/esbuild-scripts/config/createEsbuildConfig.ts index 97fbdffa5..95088b333 100644 --- a/packages/modular-scripts/src/esbuild-scripts/config/createEsbuildConfig.ts +++ b/packages/modular-scripts/src/esbuild-scripts/config/createEsbuildConfig.ts @@ -9,6 +9,7 @@ import * as logger from '../../utils/logger'; import moduleScopePlugin from '../plugins/moduleScopePlugin'; import svgrPlugin from '../plugins/svgr'; import workerFactoryPlugin from '../plugins/workerFactoryPlugin'; +import { getConfig } from '../../utils/config'; export default function createEsbuildConfig( paths: Paths, @@ -46,7 +47,7 @@ export default function createEsbuildConfig( resolveExtensions: paths.moduleFileExtensions.map( (extension) => `.${extension}`, ), - sourcemap: true, + sourcemap: getConfig('generateSourceMap') as boolean, loader: { // loaders for images which are supported as files '.avif': 'file', diff --git a/packages/modular-scripts/src/start.ts b/packages/modular-scripts/src/start.ts index 61e23cee9..7bc3a58a6 100644 --- a/packages/modular-scripts/src/start.ts +++ b/packages/modular-scripts/src/start.ts @@ -128,6 +128,8 @@ async function start(packageName: string): Promise { MODULAR_IMPORT_MAP: JSON.stringify(Object.fromEntries(importMap || [])), MODULAR_USE_REACT_CREATE_ROOT: JSON.stringify(useReactCreateRoot), MODULAR_STYLE_IMPORT_MAPS: JSON.stringify([...styleImports]), + INTERNAL_PUBLIC_URL: getConfig('publicUrl') as string, + INTERNAL_GENERATE_SOURCEMAP: String(getConfig('generateSourceMap')), }, }); } diff --git a/packages/modular-scripts/src/utils/config.ts b/packages/modular-scripts/src/utils/config.ts index 92fa91ff8..30b9d6de6 100644 --- a/packages/modular-scripts/src/utils/config.ts +++ b/packages/modular-scripts/src/utils/config.ts @@ -62,7 +62,7 @@ const config = { : undefined, }, publicUrl: { - default: undefined, + default: '', override: process.env.PUBLIC_URL, }, generateSourceMap: { @@ -91,7 +91,7 @@ type ConfigObjectKey = keyof typeof config; */ export function getConfig( configEntry: ConfigObjectKey, -): string | boolean | string[] | undefined { +): string | boolean | string[] { const overrideValue = config[configEntry].override; const defaultValue = config[configEntry].default; if (overrideValue !== undefined) { @@ -100,10 +100,7 @@ export function getConfig( // Error if configuration doesn't match our interface? const loadedConfig = configResult.config as ConfigObject; const configValue = loadedConfig[configEntry]; - if ( - configValue !== null && - (typeof configValue === typeof defaultValue || configValue === undefined) - ) { + if (configValue !== null && typeof configValue === typeof defaultValue) { return configValue; } } diff --git a/packages/modular-scripts/src/utils/createPaths.ts b/packages/modular-scripts/src/utils/createPaths.ts index 881c3cc0f..4b6571160 100644 --- a/packages/modular-scripts/src/utils/createPaths.ts +++ b/packages/modular-scripts/src/utils/createPaths.ts @@ -5,6 +5,7 @@ import * as path from 'path'; import getPublicUrlOrPath from './getPublicUrlOrPath'; import getModularRoot from './getModularRoot'; import getLocation from './getLocation'; +import { getConfig } from './config'; export interface Paths { modularRoot: string; publicUrlOrPath: string; @@ -47,10 +48,11 @@ export default async function createPaths(target: string): Promise { // single-page apps that may serve index.html for nested URLs like /todos/42. // We can't use a relative path in HTML because we don't want to load something // like /todos/42/static/js/bundle.7289d.js. We have to know the root. + const publicUrl = getConfig('publicUrl') as string; const publicUrlOrPath = getPublicUrlOrPath( process.env.NODE_ENV === 'development', (fs.readJSONSync(resolveApp('package.json')) as AppPackageJson).homepage, - process.env.PUBLIC_URL, + publicUrl === '' ? undefined : publicUrl, ); const moduleFileExtensions = [ diff --git a/yarn.lock b/yarn.lock index 3f35dd93a..4a726899a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2905,6 +2905,11 @@ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== +"@types/lodash@^4.14.191": + version "4.14.191" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.191.tgz#09511e7f7cba275acd8b419ddac8da9a6a79e2fa" + integrity sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ== + "@types/micromatch@4.0.2": version "4.0.2" resolved "https://registry.yarnpkg.com/@types/micromatch/-/micromatch-4.0.2.tgz#ce29c8b166a73bf980a5727b1e4a4d099965151d" From 755a13f378dd715aa2217cb6c0d3360cc895ba7d Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Thu, 15 Dec 2022 15:17:52 +0000 Subject: [PATCH 17/27] Add changeset --- .changeset/cyan-flowers-rest.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/cyan-flowers-rest.md diff --git a/.changeset/cyan-flowers-rest.md b/.changeset/cyan-flowers-rest.md new file mode 100644 index 000000000..a5051e1e0 --- /dev/null +++ b/.changeset/cyan-flowers-rest.md @@ -0,0 +1,6 @@ +--- +'modular-scripts': major +--- + +Changed default CDN from Skypack to esm.sh as skypack is no longer actively +maintained. Add support for configuring modular through a configuration file. From 1a447a3c7c262fcd2c584ad3a47ed882b1477e41 Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Thu, 15 Dec 2022 16:22:46 +0000 Subject: [PATCH 18/27] Documentation --- docs/configuration.md | 75 +++++++++++++++++++++ docs/esm-views/customize-bundle-strategy.md | 3 +- docs/esm-views/esm-cdn.md | 3 +- 3 files changed, 79 insertions(+), 2 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index e7f0c9d92..081daa912 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -7,6 +7,81 @@ nav_order: 10 Modular has minimal configuration because of its philosophy. However there is a set of minimum configuration required. +## Configuration File + +We allow a number of Modular behaviours to be configured via a dedicated Modular +config file, `.modular.js`, located at the root of the repository. + +We support the following file names/formats: + +- `modular` property within your `package.json` +- `.modular.js` +- `.modularrc` +- `.modularrc.json` +- `.modularrc.yaml` +- `.modularrc.yml` +- `.modularrc.js` +- `.modularrc.cjs` +- `modular.config.js` +- `modular.config.cjs` + +Example `.modular.js` file contents with all configurable attributes and their +default values: + +```js +module.exports = { + useModularEsbuild: false, + externalCdnTemplate: 'https://esm.sh/[name]@[version]', + externalBlockList: [], + externalAllowList: ['**'], + publicUrl: '', + generateSourceMap: true, +}; +``` + +### useModularEsbuild + +`boolean` + +Use esbuild instead of default Webpack. Only affects Views and ESM Views. + +### externalCdnTemplate + +`string` + +Template to resolve the URL used to fetch packages from a CDN. Defaults to +esm.sh. Only applies to ESM Views. + +### externalBlockList + +`string[]` + +Packages that should be bundled and not fetched from a CDN. Avoid using this +unless absolutely necessary. Defaults to none. Only applies to ESM Views. + +### externalAllowList + +`string[]` + +Packages that should be fetched from a CDN. Avoid changing this unless +absolutely necessary. Defaults to all packages. Only applies to ESM Views. + +### publicUrl + +`string` + +Same as Create React App PUBLIC_URL. Instead of assuming the application is +hosted in the web server's root or subpath specified by homepage in +package.json, assets will be referenced to the URL provided. + +### generateSourceMap + +`boolean` + +Should build process generate a source map - can be disabled for performance +reasons. Source maps are resource heavy and can cause out of memory issue for +large source files. + ## `package.json#modular` _NOTE: This property is created automatically and is described here for diff --git a/docs/esm-views/customize-bundle-strategy.md b/docs/esm-views/customize-bundle-strategy.md index ccd2ace3d..75b322d35 100644 --- a/docs/esm-views/customize-bundle-strategy.md +++ b/docs/esm-views/customize-bundle-strategy.md @@ -7,7 +7,8 @@ title: Customize bundling strategy # Customize bundling / rewriting strategy By default, all external dependencies are rewritten to a CDN URL and none is -bundled. This logic can be controlled using two environment variables: +bundled. This logic can be controlled using two environment variables or by +using a [modular configuration file](../configuration.md).: 1. `EXTERNAL_ALLOW_LIST` is a comma-separated string that specifies which dependencies are allowed to be rewritten to the CDN; if not specified, its diff --git a/docs/esm-views/esm-cdn.md b/docs/esm-views/esm-cdn.md index d3b9902af..dcfd00c15 100644 --- a/docs/esm-views/esm-cdn.md +++ b/docs/esm-views/esm-cdn.md @@ -27,7 +27,8 @@ evaluated only once, it plays well with stateful libraries. # Customise the ESM CDN You can specify a CDN template to rewrite dependencies using the environment -variable `EXTERNAL_CDN_TEMPLATE`. +variable `EXTERNAL_CDN_TEMPLATE`, or by using a +[modular configuration file](../configuration.md). For example: From ee938f72dad159d9ce97481b2026bac06f71f1af Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Thu, 15 Dec 2022 16:32:49 +0000 Subject: [PATCH 19/27] Update changelog --- docs/releases/4.0.x.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/releases/4.0.x.md b/docs/releases/4.0.x.md index e0dae3986..898af71d9 100644 --- a/docs/releases/4.0.x.md +++ b/docs/releases/4.0.x.md @@ -9,6 +9,7 @@ title: 4.0.x - Node 18 Support - Updated Jest to [^29.3.1](https://github.com/facebook/jest/releases) +- Support for a dedicated [Modular configuration file](../configuration.md) ## Breaking Changes @@ -66,6 +67,13 @@ manually complete the tasks previously covered by these commands. - Dropped support for minor versions of Node 14.17 and Node 16 version 16.9 and below - Now support Node ^14.18.0, >=16.10.0, and >=18.0.0 +- Dropped `USE_MODULAR_WEBPACK` environment variable, as Webpack is used by + default. Use `USE_MODULAR_ESBUILD` env variable or useModularEsbuild in a + [modular configuration file](../configuration.md) to use esbuild +- Changed default Content Delivery Network for ESM Views to esm.sh instead of + Skypack, as it is no longer actively maintained. The CDN can still be + configured through the `EXTERNAL_CDN_TEMPLATE` environment variable or through + a [modular configuration file](../configuration.md). # Merged Changes From 7eead448bb06f1ac287d2658778ebe112c8e3917 Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Thu, 15 Dec 2022 17:13:08 +0000 Subject: [PATCH 20/27] Update documentation --- docs/configuration.md | 36 ++++++++++++++------- docs/esm-views/customize-bundle-strategy.md | 15 +++++---- docs/esm-views/esm-cdn.md | 4 +-- 3 files changed, 34 insertions(+), 21 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index 081daa912..a045c41fe 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -39,44 +39,56 @@ module.exports = { }; ``` -### useModularEsbuild +### **useModularEsbuild** -`boolean` +**Type**: `boolean` + +**Default**: `false` - Uses [Webpack](https://webpack.js.org/) Use esbuild instead of default Webpack. Only affects Views and ESM Views. -### externalCdnTemplate +### **externalCdnTemplate** + +**Type**: `string` -`string` +**Default**: `https://esm.sh/[name]@[version]` - [esm.sh](https://esm.sh/) Template to resolve the URL used to fetch packages from a CDN. Defaults to esm.sh. Only applies to ESM Views. -### externalBlockList +### **externalBlockList** + +**Type**: `string[]` -`string[]` +**Default**: `[]` - No packages Packages that should be bundled and not fetched from a CDN. Avoid using this unless absolutely necessary. Defaults to none. Only applies to ESM Views. -### externalAllowList +### **externalAllowList** -`string[]` +**Type**: `string[]` + +**Default**: `[**]` - All packages Packages that should be fetched from a CDN. Avoid changing this unless absolutely necessary. Defaults to all packages. Only applies to ESM Views. -### publicUrl +### **publicUrl** + +**Type**: `string` -`string` +**Default**: `''` - No Public URL Same as Create React App PUBLIC_URL. Instead of assuming the application is hosted in the web server's root or subpath specified by homepage in package.json, assets will be referenced to the URL provided. -### generateSourceMap +### **generateSourceMap** + +**Type**: `boolean` -`boolean` +**Default**: `true` Should build process generate a source map - can be disabled for performance reasons. Source maps are resource heavy and can cause out of memory issue for diff --git a/docs/esm-views/customize-bundle-strategy.md b/docs/esm-views/customize-bundle-strategy.md index 75b322d35..1976303e6 100644 --- a/docs/esm-views/customize-bundle-strategy.md +++ b/docs/esm-views/customize-bundle-strategy.md @@ -10,13 +10,14 @@ By default, all external dependencies are rewritten to a CDN URL and none is bundled. This logic can be controlled using two environment variables or by using a [modular configuration file](../configuration.md).: -1. `EXTERNAL_ALLOW_LIST` is a comma-separated string that specifies which - dependencies are allowed to be rewritten to the CDN; if not specified, its - default value is `**` ( -> all dependencies are rewritten) -2. `EXTERNAL_BLOCK_LIST` is a comma-separated string that specifies which - dependencies are **not** allowed to be rewritten to the CDN; if not specified - its default value is empty ( -> no dependency excluded, i.e. all dependencies - are rewritten) +1. [`EXTERNAL_ALLOW_LIST`](../configuration.md#externalallowlist) is a + comma-separated string that specifies which dependencies are allowed to be + rewritten to the CDN; if not specified, its default value is `**` ( -> all + dependencies are rewritten) +2. [`EXTERNAL_BLOCK_LIST`](../configuration.md#externalblocklist) is a + comma-separated string that specifies which dependencies are **not** allowed + to be rewritten to the CDN; if not specified its default value is empty ( -> + no dependency excluded, i.e. all dependencies are rewritten) The allow / block lists are parsed and processed according to this logic: diff --git a/docs/esm-views/esm-cdn.md b/docs/esm-views/esm-cdn.md index dcfd00c15..b307272c1 100644 --- a/docs/esm-views/esm-cdn.md +++ b/docs/esm-views/esm-cdn.md @@ -27,8 +27,8 @@ evaluated only once, it plays well with stateful libraries. # Customise the ESM CDN You can specify a CDN template to rewrite dependencies using the environment -variable `EXTERNAL_CDN_TEMPLATE`, or by using a -[modular configuration file](../configuration.md). +variable [`EXTERNAL_CDN_TEMPLATE`](../configuration.md#externalcdntemplate), or +by using a [modular configuration file](../configuration.md). For example: From 5a94077549b8c9eb267f896bd533ab0067ec1eac Mon Sep 17 00:00:00 2001 From: Alberto Brusa <94554131+AlbertoBrusa@users.noreply.github.com> Date: Fri, 16 Dec 2022 09:41:51 +0000 Subject: [PATCH 21/27] Update docs/releases/4.0.x.md Co-authored-by: Steve King --- docs/releases/4.0.x.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/releases/4.0.x.md b/docs/releases/4.0.x.md index 898af71d9..eb3033b86 100644 --- a/docs/releases/4.0.x.md +++ b/docs/releases/4.0.x.md @@ -68,7 +68,7 @@ manually complete the tasks previously covered by these commands. below - Now support Node ^14.18.0, >=16.10.0, and >=18.0.0 - Dropped `USE_MODULAR_WEBPACK` environment variable, as Webpack is used by - default. Use `USE_MODULAR_ESBUILD` env variable or useModularEsbuild in a + default. Use `USE_MODULAR_ESBUILD` env variable or `useModularEsbuild` in a [modular configuration file](../configuration.md) to use esbuild - Changed default Content Delivery Network for ESM Views to esm.sh instead of Skypack, as it is no longer actively maintained. The CDN can still be From 142b7efa99b53e411f8efe708ee01c4315723dc2 Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Fri, 16 Dec 2022 09:54:31 +0000 Subject: [PATCH 22/27] Update documentation --- docs/configuration.md | 18 ++++++++++++------ docs/releases/4.0.x.md | 2 +- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index a045c41fe..bfb63e90c 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -4,8 +4,9 @@ nav_order: 10 # Configuration -Modular has minimal configuration because of its philosophy. However there is a -set of minimum configuration required. +Because of its philosophy, Modular has a restricted set of configurable +behaviours. Additionally it requires some minimal configuration within the +`package.json`s in the repository, all handled by Modular itself. ## Configuration File @@ -62,8 +63,11 @@ esm.sh. Only applies to ESM Views. **Default**: `[]` - No packages -Packages that should be bundled and not fetched from a CDN. Avoid using this -unless absolutely necessary. Defaults to none. Only applies to ESM Views. +Packages that should be bundled and not fetched from a CDN. We recommend +allowing all packages to be handled by the CDN, except for particular cases +where they would not work correctly. See +[known-limitations](./esm-views/known-limitations.md). Defaults to none. Only +applies to ESM Views. ### **externalAllowList** @@ -71,8 +75,10 @@ unless absolutely necessary. Defaults to none. Only applies to ESM Views. **Default**: `[**]` - All packages -Packages that should be fetched from a CDN. Avoid changing this unless -absolutely necessary. Defaults to all packages. Only applies to ESM Views. +Packages that should be fetched from a CDN. We recommend allowing all packages +to be handled by the CDN, except for particular cases where they would not work +correctly. See [known-limitations](./esm-views/known-limitations.md). Defaults +to all packages. Only applies to ESM Views. ### **publicUrl** diff --git a/docs/releases/4.0.x.md b/docs/releases/4.0.x.md index 898af71d9..eb3033b86 100644 --- a/docs/releases/4.0.x.md +++ b/docs/releases/4.0.x.md @@ -68,7 +68,7 @@ manually complete the tasks previously covered by these commands. below - Now support Node ^14.18.0, >=16.10.0, and >=18.0.0 - Dropped `USE_MODULAR_WEBPACK` environment variable, as Webpack is used by - default. Use `USE_MODULAR_ESBUILD` env variable or useModularEsbuild in a + default. Use `USE_MODULAR_ESBUILD` env variable or `useModularEsbuild` in a [modular configuration file](../configuration.md) to use esbuild - Changed default Content Delivery Network for ESM Views to esm.sh instead of Skypack, as it is no longer actively maintained. The CDN can still be From c8ef95c4f7ce3476264fd16497cd4fdd0daccac6 Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Fri, 16 Dec 2022 11:57:20 +0000 Subject: [PATCH 23/27] Improved config function --- .../src/build/buildPackage/makeBundle.ts | 2 +- packages/modular-scripts/src/build/index.ts | 4 +- .../config/createEsbuildConfig.ts | 2 +- packages/modular-scripts/src/start.ts | 4 +- .../src/utils/buildImportMap.ts | 2 +- packages/modular-scripts/src/utils/config.ts | 40 +++++++++---------- .../modular-scripts/src/utils/createPaths.ts | 2 +- .../src/utils/filterDependencies.ts | 4 +- .../src/utils/rewriteDependencies.ts | 2 +- 9 files changed, 29 insertions(+), 33 deletions(-) diff --git a/packages/modular-scripts/src/build/buildPackage/makeBundle.ts b/packages/modular-scripts/src/build/buildPackage/makeBundle.ts index c2ae05076..f7fd7b2ff 100644 --- a/packages/modular-scripts/src/build/buildPackage/makeBundle.ts +++ b/packages/modular-scripts/src/build/buildPackage/makeBundle.ts @@ -108,7 +108,7 @@ export async function makeBundle( const outputOptions: rollup.OutputOptions = { freeze: false, - sourcemap: getConfig('generateSourceMap') as boolean, + sourcemap: getConfig('generateSourceMap'), sourcemapPathTransform(relativeSourcePath: string, sourceMapPath: string) { // make source map input files relative to the `${packagePath}/dist-${format}` within // the package directory diff --git a/packages/modular-scripts/src/build/index.ts b/packages/modular-scripts/src/build/index.ts index f45659dc5..489f5a61b 100644 --- a/packages/modular-scripts/src/build/index.ts +++ b/packages/modular-scripts/src/build/index.ts @@ -43,7 +43,7 @@ async function buildStandalone( target: string, type: Extract, ) { - const isEsbuild = getConfig('useModularEsbuild') as boolean; + const isEsbuild = getConfig('useModularEsbuild'); // Setup Paths const modularRoot = getModularRoot(); @@ -151,7 +151,7 @@ async function buildStandalone( MODULAR_IS_APP: JSON.stringify(isApp), MODULAR_IMPORT_MAP: JSON.stringify(Object.fromEntries(importMap || [])), MODULAR_USE_REACT_CREATE_ROOT: JSON.stringify(useReactCreateRoot), - INTERNAL_PUBLIC_URL: getConfig('publicUrl') as string, + INTERNAL_PUBLIC_URL: getConfig('publicUrl'), INTERNAL_GENERATE_SOURCEMAP: String(getConfig('generateSourceMap')), }, }); diff --git a/packages/modular-scripts/src/esbuild-scripts/config/createEsbuildConfig.ts b/packages/modular-scripts/src/esbuild-scripts/config/createEsbuildConfig.ts index 95088b333..58bbd6fb0 100644 --- a/packages/modular-scripts/src/esbuild-scripts/config/createEsbuildConfig.ts +++ b/packages/modular-scripts/src/esbuild-scripts/config/createEsbuildConfig.ts @@ -47,7 +47,7 @@ export default function createEsbuildConfig( resolveExtensions: paths.moduleFileExtensions.map( (extension) => `.${extension}`, ), - sourcemap: getConfig('generateSourceMap') as boolean, + sourcemap: getConfig('generateSourceMap'), loader: { // loaders for images which are supported as files '.avif': 'file', diff --git a/packages/modular-scripts/src/start.ts b/packages/modular-scripts/src/start.ts index 7bc3a58a6..b855e6698 100644 --- a/packages/modular-scripts/src/start.ts +++ b/packages/modular-scripts/src/start.ts @@ -93,7 +93,7 @@ async function start(packageName: string): Promise { // If you want to use webpack then we'll always use webpack. But if you've indicated // you want esbuild - then we'll switch you to the new fancy world. - if (getConfig('useModularEsbuild') as boolean) { + if (getConfig('useModularEsbuild')) { const { default: startEsbuildApp } = await import( './esbuild-scripts/start' ); @@ -128,7 +128,7 @@ async function start(packageName: string): Promise { MODULAR_IMPORT_MAP: JSON.stringify(Object.fromEntries(importMap || [])), MODULAR_USE_REACT_CREATE_ROOT: JSON.stringify(useReactCreateRoot), MODULAR_STYLE_IMPORT_MAPS: JSON.stringify([...styleImports]), - INTERNAL_PUBLIC_URL: getConfig('publicUrl') as string, + INTERNAL_PUBLIC_URL: getConfig('publicUrl'), INTERNAL_GENERATE_SOURCEMAP: String(getConfig('generateSourceMap')), }, }); diff --git a/packages/modular-scripts/src/utils/buildImportMap.ts b/packages/modular-scripts/src/utils/buildImportMap.ts index 21b21f016..9326ebb4e 100644 --- a/packages/modular-scripts/src/utils/buildImportMap.ts +++ b/packages/modular-scripts/src/utils/buildImportMap.ts @@ -2,7 +2,7 @@ import { parsePackageName } from './parsePackageName'; import type { Dependency } from '@schemastore/package'; import { getConfig } from './config'; -const externalCdnTemplate = getConfig('externalCdnTemplate') as string; +const externalCdnTemplate = getConfig('externalCdnTemplate'); interface BuildImportMapParams { externalDependencies: Dependency; diff --git a/packages/modular-scripts/src/utils/config.ts b/packages/modular-scripts/src/utils/config.ts index 30b9d6de6..65f003ce6 100644 --- a/packages/modular-scripts/src/utils/config.ts +++ b/packages/modular-scripts/src/utils/config.ts @@ -24,7 +24,7 @@ const configResult = explorer.search(path.join(modularRoot, 'package.json')); /** * Configuration file interface */ -interface ConfigObject { +interface Config { useModularEsbuild: boolean | null; externalCdnTemplate: string | null; externalBlockList: string[] | null; @@ -33,10 +33,17 @@ interface ConfigObject { generateSourceMap: boolean | null; } +type ConfigDefs = { + [Key in keyof Config]: { + default: Exclude; + override: undefined | Exclude; + }; +}; + /** * Defaults and env variable overrides */ -const config = { +const defs: ConfigDefs = { useModularEsbuild: { default: false, override: @@ -75,8 +82,6 @@ const config = { }, }; -type ConfigObjectKey = keyof typeof config; - /** * Get the configured value for a given configuration field. * @param configEntry Field containing the configuration variable to read @@ -84,25 +89,16 @@ type ConfigObjectKey = keyof typeof config; * - the override environment variable if configured * - the value stated in the config file if provided * - the default value if neither environment variable nor the config file are provided - * - * Although return type can be many things, we can use 'as' with confidence to restrict it to the type we're querying: - * - * - 'useModularEsbuild' will always be a boolean, so we can do getConfig('useModularEsbuild') as boolean */ -export function getConfig( - configEntry: ConfigObjectKey, -): string | boolean | string[] { - const overrideValue = config[configEntry].override; - const defaultValue = config[configEntry].default; - if (overrideValue !== undefined) { - return overrideValue; - } else if (configResult) { - // Error if configuration doesn't match our interface? - const loadedConfig = configResult.config as ConfigObject; - const configValue = loadedConfig[configEntry]; - if (configValue !== null && typeof configValue === typeof defaultValue) { - return configValue; +export function getConfig( + key: T, +): Exclude { + let configValue; + if (configResult) { + const loadedConfig = configResult.config as Config; + if (typeof loadedConfig[key] === typeof defs[key].default) { + configValue = loadedConfig[key] as Exclude; } } - return defaultValue; + return defs[key].override ?? configValue ?? defs[key].default; } diff --git a/packages/modular-scripts/src/utils/createPaths.ts b/packages/modular-scripts/src/utils/createPaths.ts index 4b6571160..bebed20cc 100644 --- a/packages/modular-scripts/src/utils/createPaths.ts +++ b/packages/modular-scripts/src/utils/createPaths.ts @@ -48,7 +48,7 @@ export default async function createPaths(target: string): Promise { // single-page apps that may serve index.html for nested URLs like /todos/42. // We can't use a relative path in HTML because we don't want to load something // like /todos/42/static/js/bundle.7289d.js. We have to know the root. - const publicUrl = getConfig('publicUrl') as string; + const publicUrl = getConfig('publicUrl'); const publicUrlOrPath = getPublicUrlOrPath( process.env.NODE_ENV === 'development', (fs.readJSONSync(resolveApp('package.json')) as AppPackageJson).homepage, diff --git a/packages/modular-scripts/src/utils/filterDependencies.ts b/packages/modular-scripts/src/utils/filterDependencies.ts index f10a5a962..9b8d7539c 100644 --- a/packages/modular-scripts/src/utils/filterDependencies.ts +++ b/packages/modular-scripts/src/utils/filterDependencies.ts @@ -18,9 +18,9 @@ export function filterDependencies({ dependencies: Dependency; workspaceInfo: WorkspaceInfo; }): FilteredDependencies { - const externalBlockList = getConfig('externalBlockList') as string[]; + const externalBlockList = getConfig('externalBlockList'); - const externalAllowList = getConfig('externalAllowList') as string[]; + const externalAllowList = getConfig('externalAllowList'); return partitionDependencies({ dependencies, diff --git a/packages/modular-scripts/src/utils/rewriteDependencies.ts b/packages/modular-scripts/src/utils/rewriteDependencies.ts index 8825ebbfe..b400c2484 100644 --- a/packages/modular-scripts/src/utils/rewriteDependencies.ts +++ b/packages/modular-scripts/src/utils/rewriteDependencies.ts @@ -1,7 +1,7 @@ import type { Dependency } from '@schemastore/package'; import { getConfig } from './config'; -const externalCdnTemplate = getConfig('externalCdnTemplate') as string; +const externalCdnTemplate = getConfig('externalCdnTemplate'); /** * Rewrite maps of package,version to package,CDN URL From 617580960f0c2633a0f206288b2c83ed192fd38f Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Fri, 16 Dec 2022 12:03:34 +0000 Subject: [PATCH 24/27] Update config function --- packages/modular-scripts/src/utils/config.ts | 30 +++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/packages/modular-scripts/src/utils/config.ts b/packages/modular-scripts/src/utils/config.ts index 65f003ce6..0cc7edb0c 100644 --- a/packages/modular-scripts/src/utils/config.ts +++ b/packages/modular-scripts/src/utils/config.ts @@ -16,21 +16,16 @@ const searchPlaces = [ `modular.config.cjs`, ]; -// Look for configuration file -const modularRoot = getModularRoot(); -const explorer = cosmiconfigSync('modular', { searchPlaces }); -const configResult = explorer.search(path.join(modularRoot, 'package.json')); - /** * Configuration file interface */ interface Config { - useModularEsbuild: boolean | null; - externalCdnTemplate: string | null; - externalBlockList: string[] | null; - externalAllowList: string[] | null; - publicUrl: string | null; - generateSourceMap: boolean | null; + useModularEsbuild: boolean; + externalCdnTemplate: string; + externalBlockList: string[]; + externalAllowList: string[]; + publicUrl: string; + generateSourceMap: boolean; } type ConfigDefs = { @@ -82,6 +77,13 @@ const defs: ConfigDefs = { }, }; +// Look for configuration file +const modularRoot = getModularRoot(); +const explorer = cosmiconfigSync('modular', { searchPlaces }); +const configResult: null | { config: Partial } = explorer.search( + path.join(modularRoot, 'package.json'), +); + /** * Get the configured value for a given configuration field. * @param configEntry Field containing the configuration variable to read @@ -95,9 +97,9 @@ export function getConfig( ): Exclude { let configValue; if (configResult) { - const loadedConfig = configResult.config as Config; - if (typeof loadedConfig[key] === typeof defs[key].default) { - configValue = loadedConfig[key] as Exclude; + const loadedConfigValue = configResult.config[key]; + if (typeof loadedConfigValue === typeof defs[key].default) { + configValue = loadedConfigValue as Exclude; } } return defs[key].override ?? configValue ?? defs[key].default; From f73878e8f97d7aba7ec4b86a2772708a03c57743 Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Fri, 16 Dec 2022 12:58:08 +0000 Subject: [PATCH 25/27] Refactor config function --- packages/modular-scripts/src/utils/config.ts | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/packages/modular-scripts/src/utils/config.ts b/packages/modular-scripts/src/utils/config.ts index 0cc7edb0c..b56b8f086 100644 --- a/packages/modular-scripts/src/utils/config.ts +++ b/packages/modular-scripts/src/utils/config.ts @@ -30,8 +30,8 @@ interface Config { type ConfigDefs = { [Key in keyof Config]: { - default: Exclude; - override: undefined | Exclude; + default: Config[Key]; + override: undefined | Config[Key]; }; }; @@ -92,15 +92,9 @@ const configResult: null | { config: Partial } = explorer.search( * - the value stated in the config file if provided * - the default value if neither environment variable nor the config file are provided */ -export function getConfig( - key: T, -): Exclude { - let configValue; - if (configResult) { - const loadedConfigValue = configResult.config[key]; - if (typeof loadedConfigValue === typeof defs[key].default) { - configValue = loadedConfigValue as Exclude; - } - } +export function getConfig(key: T): Config[T] { + const configValue: Config[T] | undefined = configResult + ? configResult.config[key] + : undefined; return defs[key].override ?? configValue ?? defs[key].default; } From 7448a3b8c683f0aa104b616741de16c6123bd2aa Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Fri, 16 Dec 2022 12:59:48 +0000 Subject: [PATCH 26/27] Removed unnecessary type annotations --- packages/modular-scripts/src/utils/config.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/modular-scripts/src/utils/config.ts b/packages/modular-scripts/src/utils/config.ts index b56b8f086..4f7324866 100644 --- a/packages/modular-scripts/src/utils/config.ts +++ b/packages/modular-scripts/src/utils/config.ts @@ -93,8 +93,6 @@ const configResult: null | { config: Partial } = explorer.search( * - the default value if neither environment variable nor the config file are provided */ export function getConfig(key: T): Config[T] { - const configValue: Config[T] | undefined = configResult - ? configResult.config[key] - : undefined; + const configValue = configResult ? configResult.config[key] : undefined; return defs[key].override ?? configValue ?? defs[key].default; } From f0e2e93e1721b34fc08b5a3ebdecd1b03755017a Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Fri, 16 Dec 2022 15:33:52 +0000 Subject: [PATCH 27/27] More cleaning up of Config() --- packages/modular-scripts/src/utils/config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/modular-scripts/src/utils/config.ts b/packages/modular-scripts/src/utils/config.ts index 4f7324866..fb0b68a5c 100644 --- a/packages/modular-scripts/src/utils/config.ts +++ b/packages/modular-scripts/src/utils/config.ts @@ -92,7 +92,7 @@ const configResult: null | { config: Partial } = explorer.search( * - the value stated in the config file if provided * - the default value if neither environment variable nor the config file are provided */ -export function getConfig(key: T): Config[T] { +export function getConfig(key: T): Config[T] { const configValue = configResult ? configResult.config[key] : undefined; return defs[key].override ?? configValue ?? defs[key].default; }