From ef63eb3982e5984f72b7ea326a8c1da034c83253 Mon Sep 17 00:00:00 2001 From: Alberto Brusa <94554131+AlbertoBrusa@users.noreply.github.com> Date: Wed, 3 May 2023 13:51:49 +0100 Subject: [PATCH 01/42] Deprecate Node 14 Support & add Node 20 & switch to es2017 (#2370) * Change engines & tests to Node 16, 18 & 20, dropping Node 14 * Change target to ES2017 * Update docs * Add changeset --- .changeset/spotty-hornets-hug.md | 7 +++++++ .github/workflows/integration.yml | 2 +- .github/workflows/release.yml | 2 +- .github/workflows/static.yml | 2 +- .github/workflows/test-windows.yml | 2 +- .github/workflows/test.yml | 2 +- .github/workflows/validate.yml | 4 ++-- babel.config.js | 2 +- docs/compatibility.md | 9 ++++----- package.json | 2 +- packages/create-modular-react-app/package.json | 2 +- packages/eslint-config-modular-app/package.json | 2 +- packages/modular-scripts/package.json | 2 +- packages/modular-scripts/src/__tests__/build.test.ts | 2 +- packages/modular-scripts/src/__tests__/index.test.ts | 6 +++--- packages/modular-scripts/src/test/config.ts | 2 +- packages/modular-scripts/tsconfig.json | 2 +- 17 files changed, 29 insertions(+), 23 deletions(-) create mode 100644 .changeset/spotty-hornets-hug.md diff --git a/.changeset/spotty-hornets-hug.md b/.changeset/spotty-hornets-hug.md new file mode 100644 index 000000000..74a6249fe --- /dev/null +++ b/.changeset/spotty-hornets-hug.md @@ -0,0 +1,7 @@ +--- +'create-modular-react-app': major +'eslint-config-modular-app': major +'modular-scripts': major +--- + +Dropped Node 14 support, added Node 20 support. Changed target to ES2017 diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index f5f1bff01..159a50ac5 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -24,7 +24,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - node-version: ['14.18.0', '16.x', '18.x'] + node-version: ['16.x', '18.x', '20.x'] yarn-version: ['1.22.19', '3.5.0'] steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2de272ccc..abfe230a7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -20,7 +20,7 @@ jobs: - name: Use Node.js uses: actions/setup-node@v3.3.0 with: - node-version: '14.18.0' + node-version: '18.x' registry-url: https://registry.npmjs.org/ cache: 'yarn' diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml index 30baebf9d..a5eac57a0 100644 --- a/.github/workflows/static.yml +++ b/.github/workflows/static.yml @@ -29,7 +29,7 @@ jobs: - name: Use Node.js uses: actions/setup-node@v3.3.0 with: - node-version: '14.18.0' + node-version: '18.x' cache: 'yarn' - name: 'Install Dependencies' diff --git a/.github/workflows/test-windows.yml b/.github/workflows/test-windows.yml index 265e447e6..d49e4de1e 100644 --- a/.github/workflows/test-windows.yml +++ b/.github/workflows/test-windows.yml @@ -20,7 +20,7 @@ jobs: fail-fast: false matrix: os: [windows-latest] - node-version: ['14.18.0', '16.x', '18.x'] + node-version: ['16.x', '18.x', '20.x'] steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3feb22e46..9c8403967 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -22,7 +22,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - node-version: ['14.18.0', '16.x', '18.x'] + node-version: ['16.x', '18.x', '20.x'] steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 722185a63..1f73ec5c5 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -12,10 +12,10 @@ jobs: steps: - name: Checkout uses: actions/checkout@v3 - - name: Use Node.js 14 + - name: Use Node.js 18 uses: actions/setup-node@v3.3.0 with: - node-version: 14 + node-version: 18 cache: 'yarn' - name: Install Dependencies run: yarn --frozen-lockfile diff --git a/babel.config.js b/babel.config.js index 78a9d5831..35ccd849d 100644 --- a/babel.config.js +++ b/babel.config.js @@ -13,7 +13,7 @@ module.exports = (api) => { { targets: { // TODO: can we get this to read from package.json somehow..? - node: '14', + node: '16', }, }, ], diff --git a/docs/compatibility.md b/docs/compatibility.md index 7b69ecb52..bc1c01aca 100644 --- a/docs/compatibility.md +++ b/docs/compatibility.md @@ -38,17 +38,16 @@ If you find any example of v3 features which cause Modular to fail, please ### Yarn v4 and beyond -We aim to support future versions of Yarn, and we've sucessuflly useds Modular +We aim to support future versions of Yarn, and we've successfully used Modular with an unstable release candidate of Yarn 4. If there's something we don't support properly, please [let us know](https://github.com/jpmorganchase/modular/issues). ## Node versions -Modular is tested on the latest three -[Long Term Support versions of Node.js (v14, v16 and v18)](https://github.com/nodejs/release#release-schedule). -Node.js v14 is supported from version `14.18.0` onwards, while Node 16 is -supported from version `16.10.0` onwards. +Modular is tested on the current +[Long Term Support versions of Node.js: v16, v18 and v20](https://github.com/nodejs/release#release-schedule). +Node 16 is supported from version `16.10.0` onwards. ## Platforms diff --git a/package.json b/package.json index 34e8aed13..438b0a58d 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "packages/**" ], "engines": { - "node": "^14.18.0 || >=16.10.0 || >=18.0.0" + "node": ">=16.10.0 || >=18.0.0 || >=20.0.0" }, "repository": "https://github.com/jpmorganchase/modular.git", "scripts": { diff --git a/packages/create-modular-react-app/package.json b/packages/create-modular-react-app/package.json index 649ced90a..447e38beb 100644 --- a/packages/create-modular-react-app/package.json +++ b/packages/create-modular-react-app/package.json @@ -11,7 +11,7 @@ "./package.json": "./package.json" }, "engines": { - "node": "^14.18.0 || >=16.10.0 || >=18.0.0" + "node": ">=16.10.0 || >=18.0.0 || >=20.0.0" }, "scripts": { "create-modular-react-app": "ts-node src/cli.ts", diff --git a/packages/eslint-config-modular-app/package.json b/packages/eslint-config-modular-app/package.json index 1c5ff02db..2564cef97 100644 --- a/packages/eslint-config-modular-app/package.json +++ b/packages/eslint-config-modular-app/package.json @@ -4,7 +4,7 @@ "license": "Apache-2.0", "main": "index.js", "engines": { - "node": "^14.18.0 || >=16.10.0 || >=18.0.0" + "node": ">=16.10.0 || >=18.0.0 || >=20.0.0" }, "exports": { ".": "./index.js", diff --git a/packages/modular-scripts/package.json b/packages/modular-scripts/package.json index 45b5dcf98..4e340d28d 100644 --- a/packages/modular-scripts/package.json +++ b/packages/modular-scripts/package.json @@ -18,7 +18,7 @@ "./tsconfig.json": "./tsconfig.json" }, "engines": { - "node": "^14.18.0 || >=16.10.0 || >=18.0.0" + "node": ">=16.10.0 || >=18.0.0 || >=20.0.0" }, "scripts": { "modular": "ts-node src/cli.ts", diff --git a/packages/modular-scripts/src/__tests__/build.test.ts b/packages/modular-scripts/src/__tests__/build.test.ts index 23738b13e..764e50833 100644 --- a/packages/modular-scripts/src/__tests__/build.test.ts +++ b/packages/modular-scripts/src/__tests__/build.test.ts @@ -36,7 +36,7 @@ describe('WHEN building with preserve modules', () => { { "dependencies": {}, "engines": { - "node": "^14.18.0 || >=16.10.0 || >=18.0.0", + "node": ">=16.10.0 || >=18.0.0 || >=20.0.0", }, "files": [ "dist-cjs", diff --git a/packages/modular-scripts/src/__tests__/index.test.ts b/packages/modular-scripts/src/__tests__/index.test.ts index c770e919c..0d7fd49c2 100644 --- a/packages/modular-scripts/src/__tests__/index.test.ts +++ b/packages/modular-scripts/src/__tests__/index.test.ts @@ -209,7 +209,7 @@ describe('modular-scripts', () => { "react": "17.0.2", }, "engines": { - "node": "^14.18.0 || >=16.10.0 || >=18.0.0", + "node": ">=16.10.0 || >=18.0.0 || >=20.0.0", }, "files": [ "dist-cjs", @@ -364,7 +364,7 @@ describe('modular-scripts', () => { { "dependencies": {}, "engines": { - "node": "^14.18.0 || >=16.10.0 || >=18.0.0", + "node": ">=16.10.0 || >=18.0.0 || >=20.0.0", }, "files": [ "dist-cjs", @@ -448,7 +448,7 @@ describe('modular-scripts', () => { { "dependencies": {}, "engines": { - "node": "^14.18.0 || >=16.10.0 || >=18.0.0", + "node": ">=16.10.0 || >=18.0.0 || >=20.0.0", }, "files": [ "dist-cjs", diff --git a/packages/modular-scripts/src/test/config.ts b/packages/modular-scripts/src/test/config.ts index dada23148..58674e026 100644 --- a/packages/modular-scripts/src/test/config.ts +++ b/packages/modular-scripts/src/test/config.ts @@ -63,7 +63,7 @@ export function createJestConfig( module: { type: 'commonjs', strictMode: true, noInterop: false }, jsc: { externalHelpers: false, - target: 'es2016', + target: 'es2017', parser: { syntax: 'typescript', tsx: true, diff --git a/packages/modular-scripts/tsconfig.json b/packages/modular-scripts/tsconfig.json index d79bf80af..384d4b249 100644 --- a/packages/modular-scripts/tsconfig.json +++ b/packages/modular-scripts/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "target": "es2016", + "target": "es2017", "downlevelIteration": true, "lib": ["dom", "dom.iterable", "esnext", "WebWorker"], "allowJs": true, From a349aab992824b183ef7308875533d389ace2145 Mon Sep 17 00:00:00 2001 From: Alberto Brusa <94554131+AlbertoBrusa@users.noreply.github.com> Date: Thu, 4 May 2023 16:09:19 +0100 Subject: [PATCH 02/42] Remove modular-views macro (#2372) --- .eslintignore | 4 - .gitignore | 7 - package.json | 6 +- .../getWorkspaceInfo.test.ts.snap | 7 - packages/modular-views.macro/CHANGELOG.md | 138 ------------------ packages/modular-views.macro/README.md | 46 ------ packages/modular-views.macro/package.json | 31 ---- .../src/__tests__/.eslintrc.json | 10 -- .../src/__tests__/fixture.js | 3 - .../src/__tests__/index.test.ts | 77 ---------- .../modular-views.macro/src/index.macro.ts | 137 ----------------- packages/modular-views.macro/tsconfig.json | 11 -- yarn.lock | 13 +- 13 files changed, 5 insertions(+), 485 deletions(-) delete mode 100644 packages/modular-views.macro/CHANGELOG.md delete mode 100644 packages/modular-views.macro/README.md delete mode 100644 packages/modular-views.macro/package.json delete mode 100644 packages/modular-views.macro/src/__tests__/.eslintrc.json delete mode 100644 packages/modular-views.macro/src/__tests__/fixture.js delete mode 100644 packages/modular-views.macro/src/__tests__/index.test.ts delete mode 100644 packages/modular-views.macro/src/index.macro.ts delete mode 100644 packages/modular-views.macro/tsconfig.json diff --git a/.eslintignore b/.eslintignore index 0a2a278d9..9866cc9cb 100644 --- a/.eslintignore +++ b/.eslintignore @@ -9,10 +9,6 @@ packages/sample-esbuild-app packages/sample-view packages/sample-package -# created by tests in modular-views.macro -packages/view-1 -packages/view-2 - # Build output /packages/**/build/ /packages/**/dist-cjs/ diff --git a/.gitignore b/.gitignore index df3450219..f00dced50 100644 --- a/.gitignore +++ b/.gitignore @@ -20,13 +20,6 @@ packages/sample-renamable-depending-package # example app packages/esbuild-app -# created by tests in modular-views.macro -packages/view-1 -packages/view-2 -packages/scoped -packages/node-env-app - - # Build output /packages/*/build/ /packages/*/dist-cjs/ diff --git a/package.json b/package.json index 438b0a58d..be7f2cd35 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "create-modular-react-app": "ts-node packages/create-modular-react-app/src/cli.ts", "modular": "ts-node packages/modular-scripts/src/cli.ts", "test": "cross-env NODE_OPTIONS=--max_old_space_size=5120 yarn modular test --swc --runInBand --env=node", - "build": "yarn workspace @modular-scripts/workspace-resolver build && yarn workspace create-modular-react-app build && yarn workspace modular-scripts build && yarn workspace modular-views.macro build && yarn modular build @modular-scripts/remote-view && yarn prepare:remote-view", + "build": "yarn workspace @modular-scripts/workspace-resolver build && yarn workspace create-modular-react-app build && yarn workspace modular-scripts build && yarn modular build @modular-scripts/remote-view && yarn prepare:remote-view", "prepare": "is-ci || husky install", "prepare:remote-view:copy": "cp -R dist/modular-scripts-remote-view packages/remote-view/dist", "prepare:remote-view:prepublish": "node scripts/remote-view-prepublish.js", @@ -50,7 +50,6 @@ "@testing-library/jest-dom": "5.16.5", "@testing-library/react": "12.1.5", "@testing-library/user-event": "14.4.3", - "@types/babel-plugin-macros": "2.8.5", "@types/babel__code-frame": "^7.0.3", "@types/cross-spawn": "^6.0.2", "@types/dedent": "0.7.0", @@ -102,8 +101,7 @@ "jest": { "coveragePathIgnorePatterns": [ "/__fixtures__/", - "/node_modules/", - "/modular-views.macro/" + "/node_modules/" ], "coverageProvider": "v8" }, diff --git a/packages/modular-scripts/src/__tests__/utils/__snapshots__/getWorkspaceInfo.test.ts.snap b/packages/modular-scripts/src/__tests__/utils/__snapshots__/getWorkspaceInfo.test.ts.snap index d56c9b3d1..854b59190 100644 --- a/packages/modular-scripts/src/__tests__/utils/__snapshots__/getWorkspaceInfo.test.ts.snap +++ b/packages/modular-scripts/src/__tests__/utils/__snapshots__/getWorkspaceInfo.test.ts.snap @@ -93,13 +93,6 @@ exports[`getWorkspaceInfo 1`] = ` "type": "template", "workspaceDependencies": [], }, - "modular-views.macro": { - "location": "packages/modular-views.macro", - "mismatchedWorkspaceDependencies": [], - "public": true, - "type": "unknown", - "workspaceDependencies": [], - }, "remote-view-demos": { "location": "packages/remote-view-demos", "mismatchedWorkspaceDependencies": [], diff --git a/packages/modular-views.macro/CHANGELOG.md b/packages/modular-views.macro/CHANGELOG.md deleted file mode 100644 index f8a063e8e..000000000 --- a/packages/modular-views.macro/CHANGELOG.md +++ /dev/null @@ -1,138 +0,0 @@ -# modular-views.macro - -## 3.1.1 - -### Patch Changes - -- [#1590](https://github.com/jpmorganchase/modular/pull/1590) - [`f1e352e`](https://github.com/jpmorganchase/modular/commit/f1e352e70a1f61f20918538c36f7c1d9a97ec9cd) - Thanks [@dependabot](https://github.com/apps/dependabot)! - Bump fs-extra from - 10.0.1 to 10.1.0 - -## 3.1.0 - -### Minor Changes - -- [#1112](https://github.com/jpmorganchase/modular/pull/1112) - [`d08e4c2`](https://github.com/jpmorganchase/modular/commit/d08e4c2b15db93ef2adde961651254491db94140) - Thanks [@joshwooding](https://github.com/joshwooding)! - Support yarn v3 - -### Patch Changes - -- [#1283](https://github.com/jpmorganchase/modular/pull/1283) - [`918d1f1`](https://github.com/jpmorganchase/modular/commit/918d1f15b7ae27141ad180ff634aade6ca524117) - Thanks [@LukeSheard](https://github.com/LukeSheard)! - Upgrade @babel scope - packages in modular. - -* [#1411](https://github.com/jpmorganchase/modular/pull/1411) - [`1fa4e8e`](https://github.com/jpmorganchase/modular/commit/1fa4e8ea3c21449328e1927561a31d6da438b058) - Thanks [@dependabot](https://github.com/apps/dependabot)! - Bump @babel/core - from 7.17.4 to 7.17.5 - -- [#1326](https://github.com/jpmorganchase/modular/pull/1326) - [`9c6cfe2`](https://github.com/jpmorganchase/modular/commit/9c6cfe2609f82d60d0237cdc110d9278526a27c1) - Thanks [@dependabot](https://github.com/apps/dependabot)! - Bump @babel/core - from 7.16.7 to 7.16.12 - -## 3.0.1 - -### Patch Changes - -- [#1033](https://github.com/jpmorganchase/modular/pull/1033) - [`d9f42fe`](https://github.com/jpmorganchase/modular/commit/d9f42fea338b0bf70968e4690bf2b5aa2ba108ff) - Thanks [@steveukx](https://github.com/steveukx)! - Add extraneous dependencies - and add lint rule to ensure dependencies always added - -## 3.0.0 - -### Major Changes - -- [#908](https://github.com/jpmorganchase/modular/pull/908) - [`226ad45`](https://github.com/jpmorganchase/modular/commit/226ad45251ab1955bd955fac97407e263af9de76) - Thanks [@LukeSheard](https://github.com/LukeSheard)! - Add exports fields to - all packages. - -## 2.0.0 - -### Major Changes - -- af8f49f: Remove react-scripts as a dependency and release major change. - -### Patch Changes - -- d78cfa8: Bump @types/babel-plugin-macros from 2.8.4 to 2.8.5 - -## 1.2.7 - -### Patch Changes - -- ab4aa76: Bump execa from 5.0.1 to 5.1.0 -- 9585460: Bump execa from 5.1.0 to 5.1.1 - -## 1.2.6 - -### Patch Changes - -- 18aea9d: Bump execa from 5.0.0 to 5.0.1 - -## 1.2.5 - -### Patch Changes - -- 308847e: Bumping versions for actually landing/releasing - -## 1.2.4 - -### Patch Changes - -- ecb9880: Bumping versions to overcome a bad prelease publish. - -## 1.2.4-next.0 - -### Patch Changes - -- ecb9880: Bumping versions to overcome a bad prelease publish. - -## 1.2.3 - -### Patch Changes - -- f035528: Allow arbitrary directory structures for packages - -## 1.2.3-next.0 - -### Patch Changes - -- f035528: Allow arbitrary directory structures for packages - -## 1.2.2 - -### Patch Changes - -- 84ef2db: Enhance eslint-config-modular-app, add .prettierignore and - .eslintignore files in templates - -## 1.2.1 - -### Patch Changes - -- 7c14fdb: Fix the macro's type generation, and avoid some console spam when - installing. - -## 1.2.0 - -### Minor Changes - -- 0412940: Migrate codebase to TypeScript with internal typings - -## 1.1.1 - -### Patch Changes - -- 8c681a7: Allow multiple references in one file - -## 1.1.0 - -### Minor Changes - -- 48aa4d1: Implement modular-views.macro diff --git a/packages/modular-views.macro/README.md b/packages/modular-views.macro/README.md deleted file mode 100644 index 89031781c..000000000 --- a/packages/modular-views.macro/README.md +++ /dev/null @@ -1,46 +0,0 @@ -## modular-views.macro - -When used in a modular repository, this macro will scan all the available -packages, find the ones marked as 'views', and generates a map of names to the -views, each wrapped in `React.lazy`. - -### usage - -Suppose you have a modular repository, with a directory structure like so - - -``` -my-modular-repo - packages - app - pkg-1 - pkg-2 - view-1 - view-2 - view-3 - view-4 - ... - view-n -``` - -Then you can write code like this - - -```jsx -import views from 'modular-views.macro'; - -console.log(views); - -/* -The above call would log this object - - -{ - 'view-1': React.lazy(() => import('view-1')), - 'view-2': React.lazy(() => import('view-2')), - 'view-3': React.lazy(() => import('view-3')), - 'view-4': React.lazy(() => import('view-4')), - // ... - 'view-n': React.lazy(() => import('view-n')), -} - -Like magic! -*/ -``` diff --git a/packages/modular-views.macro/package.json b/packages/modular-views.macro/package.json deleted file mode 100644 index 5ceb829c1..000000000 --- a/packages/modular-views.macro/package.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "name": "modular-views.macro", - "version": "3.1.1", - "main": "build/index.macro.js", - "exports": { - ".": "./build/index.macro.js", - "./package.json": "./package.json" - }, - "typings": "build/index.macro.d.ts", - "license": "Apache-2.0", - "dependencies": { - "@babel/core": "^7.17.9", - "@babel/template": "^7.16.7", - "@babel/types": "^7.19.0", - "babel-plugin-macros": "3.1.0", - "execa": "5.1.1", - "find-up": "5.0.0", - "fs-extra": "10.1.0", - "react": "17.0.2" - }, - "devDependencies": { - "@schemastore/package": "0.0.6" - }, - "scripts": { - "clean": "rimraf build", - "prebuild": "yarn clean", - "build": "yarn build:lib && yarn build:types", - "build:lib": "babel --root-mode upward src --out-dir build --extensions .ts --ignore 'src/**/*.test.ts'", - "build:types": "tsc --emitDeclarationOnly --declarationDir build" - } -} diff --git a/packages/modular-views.macro/src/__tests__/.eslintrc.json b/packages/modular-views.macro/src/__tests__/.eslintrc.json deleted file mode 100644 index 5b0200296..000000000 --- a/packages/modular-views.macro/src/__tests__/.eslintrc.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "overrides": [ - { - "files": "fixture.js", - "parserOptions": { - "sourceType": "module" - } - } - ] -} diff --git a/packages/modular-views.macro/src/__tests__/fixture.js b/packages/modular-views.macro/src/__tests__/fixture.js deleted file mode 100644 index ad3f31889..000000000 --- a/packages/modular-views.macro/src/__tests__/fixture.js +++ /dev/null @@ -1,3 +0,0 @@ -import views from '../../build/index.macro'; - -console.log(views); diff --git a/packages/modular-views.macro/src/__tests__/index.test.ts b/packages/modular-views.macro/src/__tests__/index.test.ts deleted file mode 100644 index 3dee0b0e7..000000000 --- a/packages/modular-views.macro/src/__tests__/index.test.ts +++ /dev/null @@ -1,77 +0,0 @@ -import execa from 'execa'; -import * as path from 'path'; -import * as rimraf from 'rimraf'; - -const modularRoot = path.join(__dirname, '../../../../'); -const packagesPath = path.join(modularRoot, 'packages'); - -async function transform() { - const result = await execa( - 'babel', - ['fixture.js', '--plugins', 'babel-plugin-macros'], - { - cleanup: true, - all: true, - cwd: __dirname, - }, - ); - return result.all; -} - -async function modularAddView(name: string) { - return await execa( - 'yarnpkg', - `modular add ${name} --unstable-type view`.split(' '), - { - cleanup: true, - cwd: modularRoot, - stderr: process.stderr, - stdout: process.stdout, - }, - ); -} - -beforeAll(async () => { - await execa('yarnpkg', ['build'], { - cleanup: true, - cwd: path.join(__dirname, '..', '..'), - stderr: process.stderr, - stdout: process.stdout, - }); -}); - -afterAll(async () => { - rimraf.sync(path.join(packagesPath, 'view-1')); - rimraf.sync(path.join(packagesPath, 'view-2')); - // run yarn so yarn.lock gets reset - await execa('yarnpkg', [], { - cwd: modularRoot, - stderr: process.stderr, - stdout: process.stdout, - }); -}); - -it('outputs a plain object when no views are available', async () => { - const output = await transform(); - expect(output).toMatchInlineSnapshot(` - "const __views__map__ = {}; - console.log(__views__map__); - " - `); -}); - -it('outputs a mapping of names to lazy components when views are available', async () => { - await modularAddView('view-1'); - await modularAddView('view-2'); - - const output = await transform(); - expect(output).toMatchInlineSnapshot(` - "import { lazy as __lazy__ } from 'react'; - const __views__map__ = { - 'view-1': __lazy__(() => import('view-1')), - 'view-2': __lazy__(() => import('view-2')) - }; - console.log(__views__map__); - " - `); -}); diff --git a/packages/modular-views.macro/src/index.macro.ts b/packages/modular-views.macro/src/index.macro.ts deleted file mode 100644 index 4442da1e5..000000000 --- a/packages/modular-views.macro/src/index.macro.ts +++ /dev/null @@ -1,137 +0,0 @@ -import type { JSONSchemaForNPMPackageJsonFiles as PackageJson } from '@schemastore/package'; -import * as path from 'path'; -import fs from 'fs-extra'; -import findUp from 'find-up'; -import * as Babel from '@babel/core'; -import { ImportDeclaration, Program, Statement } from '@babel/types'; -import { default as _template } from '@babel/template'; -import { createMacro, MacroHandler } from 'babel-plugin-macros'; -import { LazyExoticComponent, ComponentType } from 'react'; -import execa from 'execa'; - -type PackageType = 'app' | 'view' | 'root' | 'package'; - -type ModularPackageJson = PackageJson & { - modular?: { - type: PackageType; - }; -}; - -function getWorkspaces(): Array<[string, { location: string }]> { - const { stdout: yarnVersion } = execa.sync('yarnpkg', ['--version']); - - if (yarnVersion.startsWith('1.')) { - const output = execa.sync('yarnpkg', ['workspaces', 'info'], { - all: true, - reject: false, - cwd: modularRootDir, - cleanup: true, - }); - - const workspaces: Array<[string, { location: string }]> = Object.entries( - // eslint-disable-next-line @typescript-eslint/no-unsafe-argument - JSON.parse(output.stdout), - ); - - return workspaces; - } - - const output = execa.sync('yarnpkg', ['workspaces', 'list', '--json'], { - all: true, - reject: false, - cwd: modularRootDir, - cleanup: true, - }); - - const workspaces = output.stdout - .split(/\r?\n/) - .reduce((acc, workspaceString) => { - const workspaceObject = JSON.parse(workspaceString) as { - name: string; - location: string; - }; - acc.push([workspaceObject.name, workspaceObject]); - - return acc; - }, [] as Array<[string, { location: string }]>); - - return workspaces; -} - -const modularRoot = findUp.sync((directory) => { - const packageJsonPath = path.join(directory, 'package.json'); - if (fs.existsSync(packageJsonPath)) { - const pkgJSON = fs.readJsonSync(packageJsonPath) as ModularPackageJson; - if (pkgJSON.modular && pkgJSON.modular.type === 'root') { - return packageJsonPath; - } - } - return; -}); - -if (!modularRoot) { - throw new Error('This macro can only be used inside a modular project.'); -} - -const packageNames = []; - -const modularRootDir = path.dirname(modularRoot); -const workspaces = getWorkspaces(); - -for (const [name, { location }] of workspaces) { - const pkgJson = fs.readJSONSync( - path.join(modularRootDir, location, 'package.json'), - ) as ModularPackageJson; - if ( - pkgJson && - pkgJson.private !== true && - pkgJson.modular && - pkgJson.modular.type === 'view' - ) { - packageNames.push(name); - } -} - -const viewsMap = `({ - ${packageNames - .map( - (packageName) => - `'${packageName}': __lazy__(() => import('${packageName}'))`, - ) - .join(',\n ')} -})`; - -const views: MacroHandler = ({ references, babel }) => { - const r = references as { default?: Babel.NodePath[] }; - if (!r.default || r.default.length === 0) { - return; - } - - const template = (babel as { template: typeof _template }).template; - - const nodePath = r.default[0]; - const hub = nodePath.hub; - const node = hub.getScope()?.path.node as Program; - const body = node.body; - const rootStatement: Statement = template.ast( - `const __views__map__ = ${viewsMap};`, - ) as Statement; - body.unshift(rootStatement); - - if (packageNames.length > 0) { - const packageStatement: Statement = template.ast( - "import {lazy as __lazy__} from 'react';", - ) as Statement; - body.unshift(packageStatement); - } - - r.default.forEach((ref) => ref.replaceWithSourceString(`__views__map__`)); -}; - -interface ViewMap { - [packageName: string]: LazyExoticComponent>; -} - -const viewMap = createMacro(views) as ViewMap; - -export default viewMap; diff --git a/packages/modular-views.macro/tsconfig.json b/packages/modular-views.macro/tsconfig.json deleted file mode 100644 index 6a2dff2af..000000000 --- a/packages/modular-views.macro/tsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "extends": "modular-scripts/tsconfig.json", - "compilerOptions": { - "rootDir": "./src", - "noEmit": false, - "declaration": true, - "declarationDir": "types" - }, - "include": ["src/**/*"], - "exclude": ["**/__tests__"] -} diff --git a/yarn.lock b/yarn.lock index 7c17c4a03..963e83a3c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -64,7 +64,7 @@ json5 "^2.2.1" semver "^6.3.0" -"@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.15.5", "@babel/core@^7.16.0", "@babel/core@^7.17.9", "@babel/core@^7.19.6": +"@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.15.5", "@babel/core@^7.16.0", "@babel/core@^7.19.6": version "7.20.2" resolved "https://registry.npmjs.org/@babel/core/-/core-7.20.2.tgz" integrity sha512-w7DbG8DtMrJcFOi4VrLm+8QM4az8Mo+PuLBKLp2zrYRCow8W/f9xiXm5sN53C8HksCyDQwCKha9JiDoIyPjT2g== @@ -2725,19 +2725,12 @@ resolved "https://registry.npmjs.org/@types/aria-query/-/aria-query-4.2.2.tgz" integrity sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig== -"@types/babel-plugin-macros@2.8.5": - version "2.8.5" - resolved "https://registry.npmjs.org/@types/babel-plugin-macros/-/babel-plugin-macros-2.8.5.tgz" - integrity sha512-+NcIm/VBaSb4xaycov9f4Vmk4hMVPrgISoHEk+kalgVK6BlkwDZbXkW9kt1jCXVczTKXldL5RHIacExaWzxAkA== - dependencies: - "@types/babel__core" "*" - "@types/babel__code-frame@^7.0.3": version "7.0.3" resolved "https://registry.npmjs.org/@types/babel__code-frame/-/babel__code-frame-7.0.3.tgz" integrity sha512-2TN6oiwtNjOezilFVl77zwdNPwQWaDBBCCWWxyo1ctiO3vAtd7H/aB/CBJdw9+kqq3+latD0SXoedIuHySSZWw== -"@types/babel__core@*", "@types/babel__core@^7.1.14": +"@types/babel__core@^7.1.14": version "7.1.20" resolved "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.20.tgz" integrity sha512-PVb6Bg2QuscZ30FvOU7z4guG6c926D9YRvOxEaelzndpMsvP+YM74Q/dAFASpg2l6+XLalxSGxcq/lrgYWZtyQ== @@ -4064,7 +4057,7 @@ babel-plugin-jest-hoist@^29.5.0: "@types/babel__core" "^7.1.14" "@types/babel__traverse" "^7.0.6" -babel-plugin-macros@3.1.0, babel-plugin-macros@^3.1.0: +babel-plugin-macros@^3.1.0: version "3.1.0" resolved "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz" integrity sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg== From b6fde598b57be9a0b74cde3147e9436a77162564 Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Wed, 10 May 2023 11:02:17 +0100 Subject: [PATCH 03/42] Run modular lint on non-modular packages if possible by default --- docs/commands/lint.md | 7 ++-- .../src/__tests__/unobtrusiveModular.test.ts | 4 +-- packages/modular-scripts/src/lint.ts | 35 ++++++++----------- packages/modular-scripts/src/program.ts | 6 +--- 4 files changed, 21 insertions(+), 31 deletions(-) diff --git a/docs/commands/lint.md b/docs/commands/lint.md index 0c4559493..01cdce841 100644 --- a/docs/commands/lint.md +++ b/docs/commands/lint.md @@ -25,6 +25,9 @@ status of each file (`PASS` or `FAIL`). If a file has a lint warning, the command will be marked as failed, with printed eslint errors for each warning/error. +Non modular packages will also be linted if they have a `lint` script specified +in their `package.json`. + ## Default behaviour `modular lint` without arguments or options will: @@ -45,10 +48,6 @@ the Selective Options) intervention wherever possible. Restages any fixed files that were previously staged when used in combination with `--staged`. -`--includeNonModular`: Allows modular to run the `lint` script of non Modular -packages included in the selection, if one is provided in the package's -package.json - ### Selective Options `--packages [packages...]`: A list of one or more packages to lint. Can be diff --git a/packages/modular-scripts/src/__tests__/unobtrusiveModular.test.ts b/packages/modular-scripts/src/__tests__/unobtrusiveModular.test.ts index 65a57d03f..50255cb93 100644 --- a/packages/modular-scripts/src/__tests__/unobtrusiveModular.test.ts +++ b/packages/modular-scripts/src/__tests__/unobtrusiveModular.test.ts @@ -74,10 +74,10 @@ describe('When there is a non-Modular package with a build script', () => { expect(result.stdout).toContain('\nnon-modular-testable was tested'); }); - it('lints non-modular packages when the --includeNonModular flag is provided', () => { + it('lints non-modular packages', () => { const result = runModularPipeLogs( tempModularRepo, - 'lint --packages non-modular-lintable --includeNonModular --verbose', + 'lint --packages non-modular-lintable --verbose', ); expect(result.stderr).toBeFalsy(); expect(result.stdout).toContain( diff --git a/packages/modular-scripts/src/lint.ts b/packages/modular-scripts/src/lint.ts index bebf5896c..554a1ba18 100644 --- a/packages/modular-scripts/src/lint.ts +++ b/packages/modular-scripts/src/lint.ts @@ -22,7 +22,6 @@ export interface LintOptions { ancestors?: boolean; descendants?: boolean; changed?: boolean; - includeNonModular?: boolean; compareBranch?: string; } @@ -38,7 +37,6 @@ async function lint( ancestors = false, descendants = false, changed = false, - includeNonModular = false, compareBranch, } = options; const modularRoot = getModularRoot(); @@ -188,25 +186,22 @@ async function lint( } } - // Lint non-modular packages - TODO: Remove conditional & flag in next major release of Modular (5.0.0) - if (includeNonModular) { - try { - logger.debug( - `Running lint command in the following non-modular packages: ${JSON.stringify( - nonModularTargets, - )}`, - ); - for (const target of nonModularTargets) { - await execAsync(`yarn`, ['workspace', target, 'lint'], { - cwd: getModularRoot(), - log: false, - }); - } - } catch (err) { - logger.debug((err as ExecaError).message); - // ✕ Modular lint did not pass - throw new Error('\u2715 Modular lint did not pass'); + try { + logger.debug( + `Running lint command in the following non-modular packages: ${JSON.stringify( + nonModularTargets, + )}`, + ); + for (const target of nonModularTargets) { + await execAsync(`yarn`, ['workspace', target, 'lint'], { + cwd: getModularRoot(), + log: false, + }); } + } catch (err) { + logger.debug((err as ExecaError).message); + // ✕ Modular lint did not pass + throw new Error('\u2715 Modular lint did not pass'); } } diff --git a/packages/modular-scripts/src/program.ts b/packages/modular-scripts/src/program.ts index df62d8efc..ac8a11c53 100755 --- a/packages/modular-scripts/src/program.ts +++ b/packages/modular-scripts/src/program.ts @@ -314,11 +314,7 @@ program `Fix the lint errors wherever possible, restages changes if run with ${lintStagedFlag}`, ) .option('--verbose', 'Enables verbose logging within modular.') - .option( - '--includeNonModular', - "Runs 'lint' script if specified in the package.json of any non-modular package included - Will be removed and true as default in Modular 5.0.0", - false, - ) + .addOption( new Option( lintStagedFlag, From c4abfa9f1f41755f7978abbfb39cb962e7c6a199 Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Wed, 10 May 2023 11:04:26 +0100 Subject: [PATCH 04/42] Fix mock lint function --- packages/modular-scripts/src/test/mockFunctions.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/modular-scripts/src/test/mockFunctions.ts b/packages/modular-scripts/src/test/mockFunctions.ts index 8721009a8..8444d4073 100644 --- a/packages/modular-scripts/src/test/mockFunctions.ts +++ b/packages/modular-scripts/src/test/mockFunctions.ts @@ -98,7 +98,6 @@ interface LintOptionsForTests { ancestors?: boolean; descendants?: boolean; changed?: boolean; - includeNonModular?: boolean; compareBranch?: string; } @@ -115,7 +114,6 @@ export async function runLintForTests( ancestors = false, descendants = false, changed = false, - includeNonModular = false, compareBranch, }: LintOptionsForTests, regexes: string[] = [], @@ -133,7 +131,6 @@ export async function runLintForTests( ancestors, descendants, changed, - includeNonModular, compareBranch, }, regexes, From b8e4840b032d64ea40527914c1fc7249f859f32a Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Wed, 10 May 2023 11:46:16 +0100 Subject: [PATCH 05/42] Unobtrusive Typechecking --- .../non-modular-typecheckable/.gitignore | 1 + .../non-modular-typecheckable/package.json | 14 ++ .../src/__tests__/index.test.ts | 5 + .../non-modular-typecheckable/src/index.ts | 3 + .../non-modular-typecheckable/tsconfig.json | 13 ++ .../src/__tests__/unobtrusiveModular.test.ts | 14 ++ packages/modular-scripts/src/lint.ts | 32 ++-- packages/modular-scripts/src/typecheck.ts | 160 ++++++++++-------- 8 files changed, 160 insertions(+), 82 deletions(-) create mode 100644 __fixtures__/non-modular/packages/non-modular-typecheckable/.gitignore create mode 100644 __fixtures__/non-modular/packages/non-modular-typecheckable/package.json create mode 100644 __fixtures__/non-modular/packages/non-modular-typecheckable/src/__tests__/index.test.ts create mode 100644 __fixtures__/non-modular/packages/non-modular-typecheckable/src/index.ts create mode 100644 __fixtures__/non-modular/packages/non-modular-typecheckable/tsconfig.json diff --git a/__fixtures__/non-modular/packages/non-modular-typecheckable/.gitignore b/__fixtures__/non-modular/packages/non-modular-typecheckable/.gitignore new file mode 100644 index 000000000..53c37a166 --- /dev/null +++ b/__fixtures__/non-modular/packages/non-modular-typecheckable/.gitignore @@ -0,0 +1 @@ +dist \ No newline at end of file diff --git a/__fixtures__/non-modular/packages/non-modular-typecheckable/package.json b/__fixtures__/non-modular/packages/non-modular-typecheckable/package.json new file mode 100644 index 000000000..dc63b4ee2 --- /dev/null +++ b/__fixtures__/non-modular/packages/non-modular-typecheckable/package.json @@ -0,0 +1,14 @@ +{ + "name": "non-modular-typecheckable", + "private": false, + "scripts": { + "typecheck": "echo 'non-modular-typecheckable was typechecked'" + }, + "files": [ + "dist", + "src" + ], + "license": "UNLICENSED", + "main": "./dist/index.js", + "version": "1.0.0" +} diff --git a/__fixtures__/non-modular/packages/non-modular-typecheckable/src/__tests__/index.test.ts b/__fixtures__/non-modular/packages/non-modular-typecheckable/src/__tests__/index.test.ts new file mode 100644 index 000000000..131d34e71 --- /dev/null +++ b/__fixtures__/non-modular/packages/non-modular-typecheckable/src/__tests__/index.test.ts @@ -0,0 +1,5 @@ +import add from '../index'; + +test('it should add two numbers', () => { + expect(add(1, 2)).toBe(3); +}); diff --git a/__fixtures__/non-modular/packages/non-modular-typecheckable/src/index.ts b/__fixtures__/non-modular/packages/non-modular-typecheckable/src/index.ts new file mode 100644 index 000000000..b92ce9fdf --- /dev/null +++ b/__fixtures__/non-modular/packages/non-modular-typecheckable/src/index.ts @@ -0,0 +1,3 @@ +export default function add(a: number, b: number): number { + return a + b; +} diff --git a/__fixtures__/non-modular/packages/non-modular-typecheckable/tsconfig.json b/__fixtures__/non-modular/packages/non-modular-typecheckable/tsconfig.json new file mode 100644 index 000000000..b3f8529fe --- /dev/null +++ b/__fixtures__/non-modular/packages/non-modular-typecheckable/tsconfig.json @@ -0,0 +1,13 @@ +{ + "include": ["src"], + "compilerOptions": { + "target": "es2018", + "outDir": "dist", + "lib": ["dom", "esnext"], + "declaration": true, + "moduleResolution": "node", + "sourceMap": true, + "strict": true, + "esModuleInterop": true + } +} diff --git a/packages/modular-scripts/src/__tests__/unobtrusiveModular.test.ts b/packages/modular-scripts/src/__tests__/unobtrusiveModular.test.ts index 50255cb93..a09f5d899 100644 --- a/packages/modular-scripts/src/__tests__/unobtrusiveModular.test.ts +++ b/packages/modular-scripts/src/__tests__/unobtrusiveModular.test.ts @@ -85,4 +85,18 @@ describe('When there is a non-Modular package with a build script', () => { ); expect(result.stdout).toContain('non-modular-lintable was linted'); }); + + it('typechecks non-modular packages', () => { + const result = runModularPipeLogs( + tempModularRepo, + 'typecheck non-modular-typecheckable --verbose', + ); + expect(result.stderr).toBeFalsy(); + expect(result.stdout).toContain( + 'Running typecheck command in the following non-modular packages: ["non-modular-typecheckable"]', + ); + expect(result.stdout).toContain( + 'non-modular-typecheckable was typechecked', + ); + }); }); diff --git a/packages/modular-scripts/src/lint.ts b/packages/modular-scripts/src/lint.ts index 554a1ba18..fee26f6dc 100644 --- a/packages/modular-scripts/src/lint.ts +++ b/packages/modular-scripts/src/lint.ts @@ -186,22 +186,24 @@ async function lint( } } - try { - logger.debug( - `Running lint command in the following non-modular packages: ${JSON.stringify( - nonModularTargets, - )}`, - ); - for (const target of nonModularTargets) { - await execAsync(`yarn`, ['workspace', target, 'lint'], { - cwd: getModularRoot(), - log: false, - }); + if (nonModularTargets.length) { + try { + logger.debug( + `Running lint command in the following non-modular packages: ${JSON.stringify( + nonModularTargets, + )}`, + ); + for (const target of nonModularTargets) { + await execAsync(`yarn`, ['workspace', target, 'lint'], { + cwd: getModularRoot(), + log: false, + }); + } + } catch (err) { + logger.debug((err as ExecaError).message); + // ✕ Modular lint did not pass + throw new Error('\u2715 Modular lint did not pass'); } - } catch (err) { - logger.debug((err as ExecaError).message); - // ✕ Modular lint did not pass - throw new Error('\u2715 Modular lint did not pass'); } } diff --git a/packages/modular-scripts/src/typecheck.ts b/packages/modular-scripts/src/typecheck.ts index 37c241db3..a072a9bf1 100644 --- a/packages/modular-scripts/src/typecheck.ts +++ b/packages/modular-scripts/src/typecheck.ts @@ -7,6 +7,8 @@ import getModularRoot from './utils/getModularRoot'; import actionPreflightCheck from './utils/actionPreflightCheck'; import { getAllWorkspaces } from './utils/getAllWorkspaces'; import { selectWorkspaces } from './utils/selectWorkspaces'; +import { partitionPackages } from './utils/unobtrusiveModular'; +import execAsync from './utils/execAsync'; import type { CompilerOptionsDefinition, JSONSchemaForTheTypeScriptCompilerSConfigurationFile as TSConfig, @@ -83,97 +85,121 @@ async function typecheck( const { ancestors, descendants, changed, compareBranch } = options; const isSelective = changed || ancestors || descendants || packages.length; const modularRoot = getModularRoot(); - const [allWorkspacePackages] = await getAllWorkspaces(modularRoot); - const targets = isSelective ? packages : [...allWorkspacePackages.keys()]; - let replaceInclude: undefined | string[]; + const [workspaceMap] = await getAllWorkspaces(); + let selectedTargets: string[]; if (isSelective) { - const selectedTargets = await selectWorkspaces({ - targets, + selectedTargets = await selectWorkspaces({ + targets: packages, changed, compareBranch, descendants, ancestors, }); + } else { + selectedTargets = [...workspaceMap.keys()]; + } - const targetLocations: string[] = []; - for (const [pkgName, pkg] of allWorkspacePackages) { - if (selectedTargets.includes(pkgName)) { - targetLocations.push(pkg.location); - } - } + // Split packages into modular and non-modular testable. Make sure that "root" is not there. + const [modularTargets, nonModularTargets] = partitionPackages( + selectedTargets, + workspaceMap, + 'typecheck', + ); - if (targetLocations.length) { - replaceInclude = targetLocations; + const targetLocations: string[] = []; + for (const [pkgName, pkg] of workspaceMap) { + if (modularTargets.includes(pkgName)) { + targetLocations.push(pkg.location); } } - const { typescriptConfig } = await getPackageMetadata(); - const tsConfig = restrictUserTsconfig(typescriptConfig, replaceInclude); - - const diagnosticHost = { - getCurrentDirectory: (): string => getModularRoot(), - getNewLine: (): string => ts.sys.newLine, - getCanonicalFileName: (file: string): string => - ts.sys.useCaseSensitiveFileNames ? file : toFileNameLowerCase(file), - }; - - // Parse all config except for compilerOptions - const configParseResult = ts.parseJsonConfigFileContent( - tsConfig, - ts.sys, - modularRoot, + logger.debug( + `Typechecking the following locations: ${JSON.stringify(targetLocations)}`, ); - if (configParseResult.errors.length > 0) { - logger.error('Failed to parse your tsconfig.json'); - throw new Error( - ts.formatDiagnostics(configParseResult.errors, diagnosticHost), + const { typescriptConfig } = await getPackageMetadata(); + const tsConfig = restrictUserTsconfig(typescriptConfig, targetLocations); + + if (modularTargets.length) { + const diagnosticHost = { + getCurrentDirectory: (): string => getModularRoot(), + getNewLine: (): string => ts.sys.newLine, + getCanonicalFileName: (file: string): string => + ts.sys.useCaseSensitiveFileNames ? file : toFileNameLowerCase(file), + }; + + // Parse all config except for compilerOptions + const configParseResult = ts.parseJsonConfigFileContent( + tsConfig, + ts.sys, + modularRoot, ); - } - const program = ts.createProgram( - configParseResult.fileNames, - configParseResult.options, - ); - - // Pulled from typescript's getCanonicalFileName logic - // eslint-disable-next-line no-useless-escape - const fileNameLowerCaseRegExp = /[^\u0130\u0131\u00DFa-z0-9\\/:\-_\. ]+/g; + if (configParseResult.errors.length > 0) { + logger.error('Failed to parse your tsconfig.json'); + throw new Error( + ts.formatDiagnostics(configParseResult.errors, diagnosticHost), + ); + } - function toFileNameLowerCase(x: string) { - return fileNameLowerCaseRegExp.test(x) - ? x.replace(fileNameLowerCaseRegExp, x.toLowerCase()) - : x; - } + const program = ts.createProgram( + configParseResult.fileNames, + configParseResult.options, + ); - program - .getSourceFiles() - .map((f) => f.fileName) - .sort() - .forEach((f) => { - logger.debug(f); - }); + // Pulled from typescript's getCanonicalFileName logic + // eslint-disable-next-line no-useless-escape + const fileNameLowerCaseRegExp = /[^\u0130\u0131\u00DFa-z0-9\\/:\-_\. ]+/g; - // Does not emit files or typings but will add declaration diagnostics to our errors - // This will ensure that makeTypings will be successful in CI before actually attempting to build - const emitResult = program.emit(); + function toFileNameLowerCase(x: string) { + return fileNameLowerCaseRegExp.test(x) + ? x.replace(fileNameLowerCaseRegExp, x.toLowerCase()) + : x; + } - const diagnostics = ts - .getPreEmitDiagnostics(program) - .concat(emitResult.diagnostics); + program + .getSourceFiles() + .map((f) => f.fileName) + .sort() + .forEach((f) => { + logger.debug(f); + }); + + // Does not emit files or typings but will add declaration diagnostics to our errors + // This will ensure that makeTypings will be successful in CI before actually attempting to build + const emitResult = program.emit(); + + const diagnostics = ts + .getPreEmitDiagnostics(program) + .concat(emitResult.diagnostics); + + if (diagnostics.length) { + if (isCI) { + // formatDiagnostics will return a readable list of error messages, each with its own line + throw new Error(ts.formatDiagnostics(diagnostics, diagnosticHost)); + } - if (diagnostics.length) { - if (isCI) { - // formatDiagnostics will return a readable list of error messages, each with its own line - throw new Error(ts.formatDiagnostics(diagnostics, diagnosticHost)); + // formatDiagnosticsWithColorAndContext will return a list of errors, each with its own line + // and provide an expanded snapshot of the line with the error + throw new Error( + ts.formatDiagnosticsWithColorAndContext(diagnostics, diagnosticHost), + ); } + } - // formatDiagnosticsWithColorAndContext will return a list of errors, each with its own line - // and provide an expanded snapshot of the line with the error - throw new Error( - ts.formatDiagnosticsWithColorAndContext(diagnostics, diagnosticHost), + if (nonModularTargets.length) { + logger.debug( + `Running typecheck command in the following non-modular packages: ${JSON.stringify( + nonModularTargets, + )}`, ); + for (const target of nonModularTargets) { + await execAsync(`yarn`, ['workspace', target, 'typecheck'], { + cwd: getModularRoot(), + log: false, + }); + } } // "✓ Typecheck passed" From 922b081f8315dbd722ddedf8ffd52923b7a8953b Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Wed, 10 May 2023 17:15:08 +0100 Subject: [PATCH 06/42] Fix CMRA tests broken by 4.4 release --- .../__snapshots__/index.test.ts.snap | 85 ++++++++++++----- .../src/__tests__/index.test.ts | 93 ++++--------------- 2 files changed, 77 insertions(+), 101 deletions(-) diff --git a/packages/create-modular-react-app/src/__tests__/__snapshots__/index.test.ts.snap b/packages/create-modular-react-app/src/__tests__/__snapshots__/index.test.ts.snap index 203c9ac5f..4bad7b59d 100644 --- a/packages/create-modular-react-app/src/__tests__/__snapshots__/index.test.ts.snap +++ b/packages/create-modular-react-app/src/__tests__/__snapshots__/index.test.ts.snap @@ -1,5 +1,66 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`create-modular-react-app WHEN it sets up a project with prefer Offline SHOULD setup an package.json correctly 1`] = ` +{ + "author": "?", + "browserslist": { + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version", + ], + "production": [ + ">0.2%", + "not dead", + "not op_mini all", + ], + }, + "dependencies": { + "@testing-library/dom": "?", + "@testing-library/jest-dom": "?", + "@testing-library/react": "?", + "@testing-library/user-event": "?", + "@types/jest": "?", + "@types/node": "?", + "@types/react": "?", + "@types/react-dom": "?", + "eslint-config-modular-app": "?", + "modular-scripts": "?", + "prettier": "?", + "react": "?", + "react-dom": "?", + "typescript": "?", + }, + "eslintConfig": { + "extends": "modular-app/recommended", + }, + "license": "MIT", + "main": "index.js", + "modular": { + "type": "root", + }, + "name": "test-repo", + "prettier": { + "printWidth": 80, + "proseWrap": "always", + "singleQuote": true, + "trailingComma": "all", + }, + "private": true, + "scripts": { + "build": "modular build", + "lint": "modular lint", + "prettier": "prettier --write .", + "start": "modular start", + "test": "modular test", + }, + "version": "1.0.0", + "workspaces": [ + "packages/**", + ], +} +`; + exports[`create-modular-react-app WHEN it sets up a project with prefer Offline should create a project with prefer offline 1`] = ` "test-repo ├─ .editorconfig @@ -42,29 +103,6 @@ exports[`create-modular-react-app WHEN it sets up a project with prefer Offline └─ yarn.lock" `; -exports[`create-modular-react-app WHEN setting a project with defaults Sets up an app package.json correctly: - Object { - "author": "?", - "dependencies": Object {}, - "modular": Object { - "type": "app", - }, - "name": "app", - "private": true, - "version": "0.1.0", - } - 1`] = ` -{ - "author": "?", - "modular": { - "type": "app", - }, - "name": "app", - "private": true, - "version": "1.0.0", -} -`; - exports[`create-modular-react-app WHEN setting a project with defaults Sets up the package.json correctly: Object { "author": "?", @@ -150,7 +188,6 @@ exports[`create-modular-react-app WHEN setting a project with defaults Sets up t "@types/react-dom": "?", "eslint-config-modular-app": "?", "modular-scripts": "?", - "modular-template-app": "?", "prettier": "?", "react": "?", "react-dom": "?", diff --git a/packages/create-modular-react-app/src/__tests__/index.test.ts b/packages/create-modular-react-app/src/__tests__/index.test.ts index f3d32fccc..da1ac8743 100644 --- a/packages/create-modular-react-app/src/__tests__/index.test.ts +++ b/packages/create-modular-react-app/src/__tests__/index.test.ts @@ -137,18 +137,17 @@ describe('create-modular-react-app', () => { await readCensoredPackageJson( path.join(destination, 'packages', 'app', 'package.json'), ), - ).toMatchSnapshot(` - Object { - "author": "?", - "dependencies": Object {}, - "modular": Object { - "type": "app", - }, - "name": "app", - "private": true, - "version": "0.1.0", - } - `); + ).toMatchInlineSnapshot(` + { + "author": "?", + "modular": { + "type": "app", + }, + "name": "app", + "private": true, + "version": "1.0.0", + } + `); }); }); @@ -168,66 +167,7 @@ describe('create-modular-react-app', () => { it('SHOULD setup an package.json correctly', async () => { expect( await readCensoredPackageJson(path.join(destination, 'package.json')), - ).toMatchSnapshot(` - Object { - "author": "?", - "browserslist": Object { - "development": Array [ - "last 1 chrome version", - "last 1 firefox version", - "last 1 safari version", - ], - "production": Array [ - ">0.2%", - "not dead", - "not op_mini all", - ], - }, - "dependencies": Object { - "@testing-library/dom": "?", - "@testing-library/jest-dom": "?", - "@testing-library/react": "?", - "@testing-library/user-event": "?", - "@types/jest": "?", - "@types/node": "?", - "@types/react": "?", - "@types/react-dom": "?", - "eslint-config-modular-app": "?", - "modular-scripts": "?", - "prettier": "?", - "react": "?", - "react-dom": "?", - "typescript": "?", - }, - "eslintConfig": Object { - "extends": "modular-app", - }, - "license": "MIT", - "main": "index.js", - "modular": Object { - "type": "root", - }, - "name": "test-repo", - "prettier": Object { - "printWidth": 80, - "proseWrap": "always", - "singleQuote": true, - "trailingComma": "all", - }, - "private": true, - "scripts": Object { - "build": "modular build", - "lint": "modular lint", - "prettier": "prettier --write .", - "start": "modular start", - "test": "modular test", - }, - "version": "1.0.0", - "workspaces": Array [ - "packages/**", - ], - } - `); + ).toMatchSnapshot(); }); it('SHOULD setup an app package.json correctly', async () => { @@ -235,16 +175,15 @@ describe('create-modular-react-app', () => { await readCensoredPackageJson( path.join(destination, 'packages', 'app', 'package.json'), ), - ).toMatchSnapshot(` - Object { + ).toMatchInlineSnapshot(` + { "author": "?", - "dependencies": Object {}, - "modular": Object { + "modular": { "type": "app", }, "name": "app", "private": true, - "version": "0.1.0", + "version": "1.0.0", } `); }); From d44ead1ea5c566bf32d0b43fa873df7fd543da3b Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Thu, 11 May 2023 15:21:10 +0100 Subject: [PATCH 07/42] Standardize lint command --- docs/commands/lint.md | 56 +++--- packages/modular-scripts/package.json | 3 + .../src/__tests__/lint.test.ts | 12 +- packages/modular-scripts/src/lint.ts | 167 +++++++++--------- packages/modular-scripts/src/program.ts | 17 +- packages/modular-scripts/src/test/utils.ts | 18 +- 6 files changed, 142 insertions(+), 131 deletions(-) diff --git a/docs/commands/lint.md b/docs/commands/lint.md index 01cdce841..b8f580a25 100644 --- a/docs/commands/lint.md +++ b/docs/commands/lint.md @@ -3,61 +3,59 @@ parent: Commands title: modular lint --- -# `modular lint [options] [regexes...]` - -`modular lint` without arguments or options will check the diff between the -current branch and your remote origin default branch (i.e. `master` or `main`) -and only lint the `.ts`, `.tsx`, `.js`, `.jsx` files that have changes. When in -CI without arguments or options or when the `--all` option is provided, it will -lint the entire codebase. When `--staged` is provided, it will only lint the -files staged on git. - -Alternatively, when it is invoked with one or more selective options -(`--packages`, `--ancestors`, `--descendants` or `--changed`), it will lint all -the source code files in the provided `--packages`, optionally agumenting the -set of packages by adding their ancestors (`--ancestors`), their descendants +# `modular lint [options] [packages...]` + +`modular lint` without arguments or options will lint all modular packages in +the repository, and run any `lint` scripts specified in the `package.json` of +any non-modular packages. + +`--diff` will check the diff between the current branch and your remote origin +default branch (i.e. `master` or `main`) and only lint the `.ts`, `.tsx`, `.js`, +`.jsx` files that have changes. When `--staged` is provided, it will only lint +the files staged on git. + +Alternatively, when it is invoked with one or more selective options (packages +provided, `--ancestors`, `--descendants` or `--changed`), it will lint all the +source code files in the provided packages, optionally agumenting the set of +packages by adding their ancestors (`--ancestors`), their descendants (`--descendants`) or the files that have changed (`--changed`), calculated comparing the current state of the git repository with the branch specified by `--compareBranch` or, if `--compareBranch` is not set, with the default branch. +Non modular packages will also be linted if they have a `lint` script specified +in their `package.json`. It uses your project eslint config to lint and jest runner to report on the lint status of each file (`PASS` or `FAIL`). If a file has a lint warning, the command will be marked as failed, with printed eslint errors for each warning/error. -Non modular packages will also be linted if they have a `lint` script specified -in their `package.json`. - ## Default behaviour -`modular lint` without arguments or options will: - -- default to lint the `git diff` between the current branch and the remote - origin's default branch when not in CI -- default to lint everything (essentially like `--all`) when in CI +`modular lint` without arguments or options will lint all packages in the +repository, and run any `lint` scripts specified in the `package.json` of any +non-modular packages. ## Options: -`--all`: Lints the entire codebase (not compatible with `--staged` and with the -Selective Options) - `--staged`: Lints only files staged on git (not compatible with `--all` and with the Selective Options) +`--diff`: Lints only files that have changed compared to the default branch or +branch specified with `--compareBranch` + `--fix`: Allows eslint to fix the errors and warnings that do not require manual intervention wherever possible. Restages any fixed files that were previously staged when used in combination with `--staged`. -### Selective Options +`--regex [regexes...]`: A list of one or more regexes to select files to lint. -`--packages [packages...]`: A list of one or more packages to lint. Can be -combined with all the other selective options. +### Selective Options -`--ancestors`: Take the packages specified via `--packages` or `--changed` and +`--ancestors`: Take the packages specified with the command or `--changed` and add their ancestors (i.e. the packages that have a direct or indirect dependency on them) to the lint list. -`--descendants`: Take the packages specified via `--packages` or `--changed` and +`--descendants`: Take the packages specified with the command or `--changed` and add their descendants (i.e. the packages they directly or indirectly depend on) to the lint list. diff --git a/packages/modular-scripts/package.json b/packages/modular-scripts/package.json index 8cc3f1756..771b042a0 100644 --- a/packages/modular-scripts/package.json +++ b/packages/modular-scripts/package.json @@ -2,6 +2,9 @@ "name": "modular-scripts", "version": "4.4.0", "license": "Apache-2.0", + "modular": { + "type": "package" + }, "repository": { "type": "git", "url": "https://github.com/jpmorganchase/modular.git", diff --git a/packages/modular-scripts/src/__tests__/lint.test.ts b/packages/modular-scripts/src/__tests__/lint.test.ts index 9f8213074..c79acb852 100644 --- a/packages/modular-scripts/src/__tests__/lint.test.ts +++ b/packages/modular-scripts/src/__tests__/lint.test.ts @@ -60,7 +60,7 @@ describe('Modular lint', () => { } let modularLogs: string[] = []; try { - await runYarnModular(tempModularRepo, 'lint __fixtures__/lint'); + await runYarnModular(tempModularRepo, 'lint --regex __fixtures__/lint'); } catch ({ stderr }) { modularLogs = (stderr as string).split('\n'); } @@ -71,7 +71,7 @@ describe('Modular lint', () => { it('should not pass lint test', async () => { let modularLogs: string[] = []; try { - await runYarnModular(tempModularRepo, 'lint __fixtures__/lint'); + await runYarnModular(tempModularRepo, 'lint --regex __fixtures__/lint'); } catch ({ stderr }) { modularLogs = (stderr as string).split('\n'); } @@ -88,7 +88,7 @@ describe('Modular lint', () => { const files = fs.readdirSync(fixturesFolder); const result = await runYarnModular( modularRoot, - 'lint __fixtures__/lint', + 'lint --regex __fixtures__/lint', ); const modularLogs: string[] = result.stderr.split('\n'); expect(modularLogs).toContain( @@ -128,7 +128,7 @@ describe('lint command can successfully do selective tests based on selected pac it('finds test after specifying a valid package', () => { const resultPackages = runModularPipeLogs( randomOutputFolder, - 'lint --packages beta-lint gamma-lint', + 'lint beta-lint gamma-lint', 'true', ); expect(resultPackages.stderr).toContain('packages/beta-lint/src/'); @@ -141,7 +141,7 @@ describe('lint command can successfully do selective tests based on selected pac it('finds ancestors using --ancestors', () => { const resultPackagesWithAncestors = runModularPipeLogs( randomOutputFolder, - 'lint --packages beta-lint gamma-lint --ancestors', + 'lint beta-lint gamma-lint --ancestors', 'true', ); expect(resultPackagesWithAncestors.stderr).toContain( @@ -164,7 +164,7 @@ describe('lint command can successfully do selective tests based on selected pac it('finds descendants using --descendants', () => { const resultPackagesWithDescendants = runModularPipeLogs( randomOutputFolder, - 'lint --packages beta-lint gamma-lint --descendants', + 'lint beta-lint gamma-lint --descendants', 'true', ); expect(resultPackagesWithDescendants.stderr).toContain( diff --git a/packages/modular-scripts/src/lint.ts b/packages/modular-scripts/src/lint.ts index fee26f6dc..013d15c2a 100644 --- a/packages/modular-scripts/src/lint.ts +++ b/packages/modular-scripts/src/lint.ts @@ -1,5 +1,4 @@ import * as path from 'path'; -import isCI from 'is-ci'; import { ExecaError } from 'execa'; import actionPreflightCheck from './utils/actionPreflightCheck'; import { resolveAsBin } from './utils/resolveAsBin'; @@ -15,119 +14,127 @@ import { partitionPackages, } from './utils/unobtrusiveModular'; export interface LintOptions { - all: boolean; fix: boolean; staged: boolean; - packages?: string[]; + regex?: string[]; ancestors?: boolean; descendants?: boolean; changed?: boolean; compareBranch?: string; + diff?: boolean; } async function lint( options: LintOptions, - userRegexes: string[] = [], + packages: string[] = [], ): Promise { const { - all = false, fix = false, staged = false, - packages = [], + regex: userRegexes = [], ancestors = false, descendants = false, changed = false, compareBranch, + diff = false, } = options; const modularRoot = getModularRoot(); const lintExtensions = ['.ts', '.tsx', '.js', '.jsx']; const [workspaceMap] = await getAllWorkspaces(); - const isSelective = - packages?.length || ancestors || descendants || changed || compareBranch; - let selectedTargets: string[]; + const isSelective = changed || ancestors || descendants || packages.length; - if (!isSelective) { - selectedTargets = [...workspaceMap.keys()]; - } else { - // Otherwise, calculate which packages are selected - selectedTargets = await selectWorkspaces({ - targets: packages, - changed, - ancestors, - descendants, - compareBranch, - }); - } - - // Split packages into modular and non-modular testable. Make sure that "root" is not there. - const [modularTargets, nonModularTargets] = partitionPackages( - selectedTargets, - workspaceMap, - 'lint', - ); - - // Compute patterns to pass Jest for the packages that we want to test - const selectedPackageRegexes = await computeRegexesFromPackageNames( - modularTargets, - ); - - // Only set regexes if all or selective options have been specified - let processedPackageRegexes = selectedPackageRegexes.map( - (regex) => `/${regex}/src/**/*.{js,jsx,ts,tsx}`, - ); - - let lintRegexes = isSelective || all ? processedPackageRegexes : []; - - if (all && isSelective) { - logger.warn( - 'You specified --all already; selective options are redundant.', + if ((staged || diff || userRegexes.length) && isSelective) { + logger.error( + "Can't specify --staged --diff --regex along with selective options", ); + process.exit(-1); } - if (staged && isSelective) { - logger.error("Can't specify --staged along with selective options"); + if ( + (staged && diff) || + (staged && userRegexes.length) || + (diff && userRegexes.length) + ) { + logger.error( + "--regex, --diff and --staged are mutually exclusive options that can't be used together", + ); process.exit(-1); } - // Not selective, not --all and no regexes; - // TODO: Bring this in line with behaviour of other commands, too 'unpredictable' from a user point of view - if (!all && !isSelective && userRegexes.length === 0) { - if (staged || !isCI) { - // If --staged or not in CI, calculate the file regexes of --diff or --staged - let diffedFiles: null | string[]; - - try { - // This can throw in case there is no git directory; in this case, we need to continue like nothing happened - diffedFiles = staged ? getStagedFiles() : getDiffedFiles(); - } catch { - diffedFiles = null; - logger.log( - 'Getting staged or diffed files failed - are you sure this is a git repo? Falling back to `--all`.', - ); - lintRegexes = processedPackageRegexes; - } - if (diffedFiles !== null) { - if (diffedFiles.length === 0) { - logger.log( - 'No diffed files detected. Use the `--all` option to lint the entire codebase', - ); - } else { - processedPackageRegexes = diffedFiles - .filter((p: string) => lintExtensions.includes(path.extname(p))) - .map((p: string) => `/${p}`); - - // if none of the diffed files meet the extension criteria, do not lint - // end the process early with a success - if (!processedPackageRegexes.length) { - logger.warn('No diffed target files to lint found'); - } + let modularTargets: string[]; + let nonModularTargets: string[]; + + // If --diff or --staged, lint only diffed or staged files, + // otherwise lint selected packages or all packages if nothing selected + let lintRegexes: string[]; + + if (diff || staged) { + // Calculate the file regexes of --diff or --staged + try { + // This can throw in case there is no git directory; in this case, we need to continue like nothing happened + const diffedFiles = staged + ? getStagedFiles() + : getDiffedFiles(compareBranch); + + if (diffedFiles.length === 0) { + logger.warn(`No staged or diffed files detected.`); + process.exit(0); + } else { + lintRegexes = diffedFiles + .filter((p: string) => lintExtensions.includes(path.extname(p))) + .map((p: string) => `/${p}`); + + // if none of the diffed files meet the extension criteria, do not lint + // end the process early with a success + if (!lintRegexes.length) { + logger.warn('No lintable diffed or staged target files found'); + process.exit(0); } } + } catch { + logger.error( + 'Getting staged or diffed files failed - are you sure this is a git repo?', + ); + process.exit(1); + } + nonModularTargets = []; + } + if (userRegexes.length) { + lintRegexes = []; + nonModularTargets = []; + } else { + let selectedTargets: string[]; + + if (isSelective) { + selectedTargets = await selectWorkspaces({ + targets: packages, + changed, + compareBranch, + descendants, + ancestors, + }); } else { - // If in CI, then lint all - lintRegexes = processedPackageRegexes; + selectedTargets = [...workspaceMap.keys()]; } + + // Split packages into modular and non-modular testable. Make sure that "root" is not there. + [modularTargets, nonModularTargets] = partitionPackages( + selectedTargets, + workspaceMap, + 'lint', + ); + + // Compute patterns to pass Jest for the packages that we want to test + const selectedPackageRegexes = await computeRegexesFromPackageNames( + modularTargets, + ); + + const processedPackageRegexes = selectedPackageRegexes.map( + (regex) => `/${regex}/src/**/*.{js,jsx,ts,tsx}`, + ); + + lintRegexes = processedPackageRegexes; } // If we computed no regexes and there are no non-modular packages to lint, bail out diff --git a/packages/modular-scripts/src/program.ts b/packages/modular-scripts/src/program.ts index ac8a11c53..557201e7d 100755 --- a/packages/modular-scripts/src/program.ts +++ b/packages/modular-scripts/src/program.ts @@ -285,12 +285,8 @@ program const lintStagedFlag = '--staged'; program - .command('lint [regexes...]') - .option( - '--all', - 'Only lint diffed files from your remote origin default branch (e.g. main or master)', - ) - .option('--packages [packages...]', 'Only lint selected packages') + .command('lint [packages...]') + .option('--regex [regexes...]', 'Only lint selected packages') .option( '--ancestors', 'Lint workspaces that depend on workspaces that have changed', @@ -314,7 +310,10 @@ program `Fix the lint errors wherever possible, restages changes if run with ${lintStagedFlag}`, ) .option('--verbose', 'Enables verbose logging within modular.') - + .option( + '--diff', + 'Only lint files that have changed compared to the compare branch', + ) .addOption( new Option( lintStagedFlag, @@ -322,9 +321,9 @@ program ).conflicts('all'), ) .description('Lints the codebase') - .action(async (regexes: string[], options: LintOptions) => { + .action(async (packages: string[], options: LintOptions) => { const { default: lint } = await import('./lint'); - await lint(options, regexes); + await lint(options, packages); }); program diff --git a/packages/modular-scripts/src/test/utils.ts b/packages/modular-scripts/src/test/utils.ts index 99e5bde57..9231ac01f 100644 --- a/packages/modular-scripts/src/test/utils.ts +++ b/packages/modular-scripts/src/test/utils.ts @@ -267,7 +267,7 @@ export async function runModularForTestsAsync( path.join(modularRoot, '/node_modules/.bin/ts-node'), [ path.join(modularRoot, '/packages/modular-scripts/src/cli.ts'), - ...args.split(' '), + ...args.split(/ +(?=(?:(?:[^"]*"){2})*[^"]*$)/g), ], { cwd, @@ -293,10 +293,14 @@ export async function runYarnModular( args: string, opts: Record = {}, ) { - return execa('yarnpkg', ['modular', ...args.split(' ')], { - cwd, - all: true, - cleanup: true, - ...opts, - }); + return execa( + 'yarnpkg', + ['modular', ...args.split(/ +(?=(?:(?:[^"]*"){2})*[^"]*$)/g)], + { + cwd, + all: true, + cleanup: true, + ...opts, + }, + ); } From 787f8979e099bf059e6897cc13931b164eb33827 Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Thu, 11 May 2023 15:30:17 +0100 Subject: [PATCH 08/42] Remove modular type from modular-scripts --- packages/modular-scripts/package.json | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/modular-scripts/package.json b/packages/modular-scripts/package.json index 771b042a0..8cc3f1756 100644 --- a/packages/modular-scripts/package.json +++ b/packages/modular-scripts/package.json @@ -2,9 +2,6 @@ "name": "modular-scripts", "version": "4.4.0", "license": "Apache-2.0", - "modular": { - "type": "package" - }, "repository": { "type": "git", "url": "https://github.com/jpmorganchase/modular.git", From 3ccf91b3d488e11f126babd08b2a1d14eef9f0c6 Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Thu, 11 May 2023 15:50:54 +0100 Subject: [PATCH 09/42] Fix typecheck tests --- .../modular-scripts/src/__tests__/typecheck.test.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/modular-scripts/src/__tests__/typecheck.test.ts b/packages/modular-scripts/src/__tests__/typecheck.test.ts index aa943da35..c723ef1d3 100644 --- a/packages/modular-scripts/src/__tests__/typecheck.test.ts +++ b/packages/modular-scripts/src/__tests__/typecheck.test.ts @@ -34,6 +34,18 @@ describe('Modular typecheck', () => { path.join(tempFixturesFolder, 'InvalidTyping.ts'), invalidTsContent, ); + // Must be recognized as a modular workspace to be type-checked + fs.writeJsonSync( + path.join(tempModularRepo, 'packages', 'app', 'package.json'), + { + name: 'modular-template-app', + version: '2.0.0', + modular: { + type: 'template', + templateType: 'app', + }, + }, + ); fs.copyFileSync( path.join(modularRoot, 'tsconfig.json'), path.join(tempModularRepo, 'tsconfig.json'), From 5e859bbecdff27cf4359efd1326b18bea5564b9b Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Thu, 11 May 2023 16:12:37 +0100 Subject: [PATCH 10/42] Fix tests --- .../modular-scripts/src/__tests__/unobtrusiveModular.test.ts | 2 +- packages/modular-scripts/src/lint.ts | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/modular-scripts/src/__tests__/unobtrusiveModular.test.ts b/packages/modular-scripts/src/__tests__/unobtrusiveModular.test.ts index a09f5d899..e43c516b5 100644 --- a/packages/modular-scripts/src/__tests__/unobtrusiveModular.test.ts +++ b/packages/modular-scripts/src/__tests__/unobtrusiveModular.test.ts @@ -77,7 +77,7 @@ describe('When there is a non-Modular package with a build script', () => { it('lints non-modular packages', () => { const result = runModularPipeLogs( tempModularRepo, - 'lint --packages non-modular-lintable --verbose', + 'lint non-modular-lintable --verbose', ); expect(result.stderr).toBeFalsy(); expect(result.stdout).toContain( diff --git a/packages/modular-scripts/src/lint.ts b/packages/modular-scripts/src/lint.ts index 013d15c2a..932a54b48 100644 --- a/packages/modular-scripts/src/lint.ts +++ b/packages/modular-scripts/src/lint.ts @@ -99,11 +99,12 @@ async function lint( process.exit(1); } nonModularTargets = []; - } - if (userRegexes.length) { + } else if (userRegexes.length) { + // Don't calculate any regexes or non-modular targets - only use the user provided regexes lintRegexes = []; nonModularTargets = []; } else { + // Compute selected packages or run on all modular & non-modular packages let selectedTargets: string[]; if (isSelective) { From 1e9c8cb09c523169d196116c5335c04ec6fe9fac Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Thu, 11 May 2023 16:25:32 +0100 Subject: [PATCH 11/42] Changeset --- .changeset/moody-mayflies-lick.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .changeset/moody-mayflies-lick.md diff --git a/.changeset/moody-mayflies-lick.md b/.changeset/moody-mayflies-lick.md new file mode 100644 index 000000000..e4d01817e --- /dev/null +++ b/.changeset/moody-mayflies-lick.md @@ -0,0 +1,7 @@ +--- +'modular-scripts': major +--- + +Standardized lint and typecheck commands to bring them in line with other +modular selective behaviour. Now lints and typechecks non-modular packages by +default From 5ba67bf81e737bae49c6aa9ee46c36b8986f6127 Mon Sep 17 00:00:00 2001 From: Alberto Brusa <94554131+AlbertoBrusa@users.noreply.github.com> Date: Mon, 15 May 2023 15:32:54 +0100 Subject: [PATCH 12/42] Fix esm-view not starting by downgrading esbuild-loader to 2.x.x (#2385) * Fix esm-view not starting by downgrading esbuild-loader to 2.x.x * Add esmView start test and update snapshots --- .changeset/fifty-rats-add.md | 5 + .../__snapshots__/index.test.ts.snap | 146 +++++++---------- .../src/__tests__/index.test.ts | 154 ++---------------- packages/modular-scripts/package.json | 2 +- .../__snapshots__/app.node-env.test.ts.snap | 8 +- .../__tests__/__snapshots__/app.test.ts.snap | 48 +++--- .../src/__tests__/app.node-env.test.ts | 14 +- .../modular-scripts/src/__tests__/app.test.ts | 48 +++--- .../src/__tests__/esmView.test.ts | 59 +++++++ yarn.lock | 31 ++-- 10 files changed, 217 insertions(+), 298 deletions(-) create mode 100644 .changeset/fifty-rats-add.md diff --git a/.changeset/fifty-rats-add.md b/.changeset/fifty-rats-add.md new file mode 100644 index 000000000..301bb56a8 --- /dev/null +++ b/.changeset/fifty-rats-add.md @@ -0,0 +1,5 @@ +--- +'modular-scripts': patch +--- + +Fix esm-views not starting diff --git a/packages/create-modular-react-app/src/__tests__/__snapshots__/index.test.ts.snap b/packages/create-modular-react-app/src/__tests__/__snapshots__/index.test.ts.snap index 203c9ac5f..cb50f7756 100644 --- a/packages/create-modular-react-app/src/__tests__/__snapshots__/index.test.ts.snap +++ b/packages/create-modular-react-app/src/__tests__/__snapshots__/index.test.ts.snap @@ -1,5 +1,66 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`create-modular-react-app WHEN it sets up a project with prefer Offline SHOULD setup an package.json correctly 1`] = ` +{ + "author": "?", + "browserslist": { + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version", + ], + "production": [ + ">0.2%", + "not dead", + "not op_mini all", + ], + }, + "dependencies": { + "@testing-library/dom": "?", + "@testing-library/jest-dom": "?", + "@testing-library/react": "?", + "@testing-library/user-event": "?", + "@types/jest": "?", + "@types/node": "?", + "@types/react": "?", + "@types/react-dom": "?", + "eslint-config-modular-app": "?", + "modular-scripts": "?", + "prettier": "?", + "react": "?", + "react-dom": "?", + "typescript": "?", + }, + "eslintConfig": { + "extends": "modular-app/recommended", + }, + "license": "MIT", + "main": "index.js", + "modular": { + "type": "root", + }, + "name": "test-repo", + "prettier": { + "printWidth": 80, + "proseWrap": "always", + "singleQuote": true, + "trailingComma": "all", + }, + "private": true, + "scripts": { + "build": "modular build", + "lint": "modular lint", + "prettier": "prettier --write .", + "start": "modular start", + "test": "modular test", + }, + "version": "1.0.0", + "workspaces": [ + "packages/**", + ], +} +`; + exports[`create-modular-react-app WHEN it sets up a project with prefer Offline should create a project with prefer offline 1`] = ` "test-repo ├─ .editorconfig @@ -42,89 +103,7 @@ exports[`create-modular-react-app WHEN it sets up a project with prefer Offline └─ yarn.lock" `; -exports[`create-modular-react-app WHEN setting a project with defaults Sets up an app package.json correctly: - Object { - "author": "?", - "dependencies": Object {}, - "modular": Object { - "type": "app", - }, - "name": "app", - "private": true, - "version": "0.1.0", - } - 1`] = ` -{ - "author": "?", - "modular": { - "type": "app", - }, - "name": "app", - "private": true, - "version": "1.0.0", -} -`; - -exports[`create-modular-react-app WHEN setting a project with defaults Sets up the package.json correctly: - Object { - "author": "?", - "browserslist": Object { - "development": Array [ - "last 1 chrome version", - "last 1 firefox version", - "last 1 safari version", - ], - "production": Array [ - ">0.2%", - "not dead", - "not op_mini all", - ], - }, - "dependencies": Object { - "@testing-library/dom": "?", - "@testing-library/jest-dom": "?", - "@testing-library/react": "?", - "@testing-library/user-event": "?", - "@types/jest": "?", - "@types/node": "?", - "@types/react": "?", - "@types/react-dom": "?", - "eslint-config-modular-app": "?", - "modular-scripts": "?", - "prettier": "?", - "react": "?", - "react-dom": "?", - "typescript": "?", - }, - "eslintConfig": Object { - "extends": "modular-app", - }, - "license": "MIT", - "main": "index.js", - "modular": Object { - "type": "root", - }, - "name": "test-repo", - "prettier": Object { - "printWidth": 80, - "proseWrap": "always", - "singleQuote": true, - "trailingComma": "all", - }, - "private": true, - "scripts": Object { - "build": "modular build", - "lint": "modular lint", - "prettier": "prettier --write .", - "start": "modular start", - "test": "modular test", - }, - "version": "1.0.0", - "workspaces": Array [ - "packages/**", - ], - } - 1`] = ` +exports[`create-modular-react-app WHEN setting a project with defaults Sets up the package.json correctly 1`] = ` { "author": "?", "browserslist": { @@ -150,7 +129,6 @@ exports[`create-modular-react-app WHEN setting a project with defaults Sets up t "@types/react-dom": "?", "eslint-config-modular-app": "?", "modular-scripts": "?", - "modular-template-app": "?", "prettier": "?", "react": "?", "react-dom": "?", diff --git a/packages/create-modular-react-app/src/__tests__/index.test.ts b/packages/create-modular-react-app/src/__tests__/index.test.ts index f3d32fccc..48d95901f 100644 --- a/packages/create-modular-react-app/src/__tests__/index.test.ts +++ b/packages/create-modular-react-app/src/__tests__/index.test.ts @@ -70,66 +70,7 @@ describe('create-modular-react-app', () => { it('Sets up the package.json correctly', async () => { expect( await readCensoredPackageJson(path.join(destination, 'package.json')), - ).toMatchSnapshot(` - Object { - "author": "?", - "browserslist": Object { - "development": Array [ - "last 1 chrome version", - "last 1 firefox version", - "last 1 safari version", - ], - "production": Array [ - ">0.2%", - "not dead", - "not op_mini all", - ], - }, - "dependencies": Object { - "@testing-library/dom": "?", - "@testing-library/jest-dom": "?", - "@testing-library/react": "?", - "@testing-library/user-event": "?", - "@types/jest": "?", - "@types/node": "?", - "@types/react": "?", - "@types/react-dom": "?", - "eslint-config-modular-app": "?", - "modular-scripts": "?", - "prettier": "?", - "react": "?", - "react-dom": "?", - "typescript": "?", - }, - "eslintConfig": Object { - "extends": "modular-app", - }, - "license": "MIT", - "main": "index.js", - "modular": Object { - "type": "root", - }, - "name": "test-repo", - "prettier": Object { - "printWidth": 80, - "proseWrap": "always", - "singleQuote": true, - "trailingComma": "all", - }, - "private": true, - "scripts": Object { - "build": "modular build", - "lint": "modular lint", - "prettier": "prettier --write .", - "start": "modular start", - "test": "modular test", - }, - "version": "1.0.0", - "workspaces": Array [ - "packages/**", - ], - } - `); + ).toMatchSnapshot(); }); it('Sets up an app package.json correctly', async () => { @@ -137,18 +78,17 @@ describe('create-modular-react-app', () => { await readCensoredPackageJson( path.join(destination, 'packages', 'app', 'package.json'), ), - ).toMatchSnapshot(` - Object { - "author": "?", - "dependencies": Object {}, - "modular": Object { - "type": "app", - }, - "name": "app", - "private": true, - "version": "0.1.0", - } - `); + ).toMatchInlineSnapshot(` + { + "author": "?", + "modular": { + "type": "app", + }, + "name": "app", + "private": true, + "version": "1.0.0", + } + `); }); }); @@ -168,66 +108,7 @@ describe('create-modular-react-app', () => { it('SHOULD setup an package.json correctly', async () => { expect( await readCensoredPackageJson(path.join(destination, 'package.json')), - ).toMatchSnapshot(` - Object { - "author": "?", - "browserslist": Object { - "development": Array [ - "last 1 chrome version", - "last 1 firefox version", - "last 1 safari version", - ], - "production": Array [ - ">0.2%", - "not dead", - "not op_mini all", - ], - }, - "dependencies": Object { - "@testing-library/dom": "?", - "@testing-library/jest-dom": "?", - "@testing-library/react": "?", - "@testing-library/user-event": "?", - "@types/jest": "?", - "@types/node": "?", - "@types/react": "?", - "@types/react-dom": "?", - "eslint-config-modular-app": "?", - "modular-scripts": "?", - "prettier": "?", - "react": "?", - "react-dom": "?", - "typescript": "?", - }, - "eslintConfig": Object { - "extends": "modular-app", - }, - "license": "MIT", - "main": "index.js", - "modular": Object { - "type": "root", - }, - "name": "test-repo", - "prettier": Object { - "printWidth": 80, - "proseWrap": "always", - "singleQuote": true, - "trailingComma": "all", - }, - "private": true, - "scripts": Object { - "build": "modular build", - "lint": "modular lint", - "prettier": "prettier --write .", - "start": "modular start", - "test": "modular test", - }, - "version": "1.0.0", - "workspaces": Array [ - "packages/**", - ], - } - `); + ).toMatchSnapshot(); }); it('SHOULD setup an app package.json correctly', async () => { @@ -235,16 +116,15 @@ describe('create-modular-react-app', () => { await readCensoredPackageJson( path.join(destination, 'packages', 'app', 'package.json'), ), - ).toMatchSnapshot(` - Object { + ).toMatchInlineSnapshot(` + { "author": "?", - "dependencies": Object {}, - "modular": Object { + "modular": { "type": "app", }, "name": "app", "private": true, - "version": "0.1.0", + "version": "1.0.0", } `); }); diff --git a/packages/modular-scripts/package.json b/packages/modular-scripts/package.json index 984b3eae6..363840f5a 100644 --- a/packages/modular-scripts/package.json +++ b/packages/modular-scripts/package.json @@ -66,7 +66,7 @@ "dotenv": "16.0.2", "dotenv-expand": "8.0.3", "esbuild": "0.17.14", - "esbuild-loader": "3.0.1", + "esbuild-loader": "^2.16.0", "escape-string-regexp": "2.0.0", "eslint": "8.28.0", "execa": "5.1.1", diff --git a/packages/modular-scripts/src/__tests__/__snapshots__/app.node-env.test.ts.snap b/packages/modular-scripts/src/__tests__/__snapshots__/app.node-env.test.ts.snap index 6f95e8bd9..a896e8974 100644 --- a/packages/modular-scripts/src/__tests__/__snapshots__/app.node-env.test.ts.snap +++ b/packages/modular-scripts/src/__tests__/__snapshots__/app.node-env.test.ts.snap @@ -6,20 +6,20 @@ exports[`when working with a NODE_ENV app WHEN building with esbuild can generat " `; -exports[`when working with a NODE_ENV app WHEN building with webpack can generate a js/main.5d879077.js 1`] = ` +exports[`when working with a NODE_ENV app WHEN building with webpack can generate a js/main.a482480b.js 1`] = ` ""use strict"; (self.webpackChunknode_env_app = self.webpackChunknode_env_app || []).push([ [179], { - 560: () => { + 908: () => { console.log("production"); }, }, (e) => { var n; - (n = 560), e((e.s = n)); + (n = 908), e((e.s = n)); }, ]); -//# sourceMappingURL=main.6f2657b7.js.map +//# sourceMappingURL=main.a482480b.js.map " `; diff --git a/packages/modular-scripts/src/__tests__/__snapshots__/app.test.ts.snap b/packages/modular-scripts/src/__tests__/__snapshots__/app.test.ts.snap index f5852c8b8..3a633b387 100644 --- a/packages/modular-scripts/src/__tests__/__snapshots__/app.test.ts.snap +++ b/packages/modular-scripts/src/__tests__/__snapshots__/app.test.ts.snap @@ -4,13 +4,13 @@ exports[`When working with a npm scoped app can generate a asset-manifest 1`] = "{ "files": { "main.css": "/static/css/main.1a7488ce.css", - "main.js": "/static/js/main.3eba3908.js", + "main.js": "/static/js/main.b44531b6.js", "runtime-main.js": "/static/js/runtime-main.de012fdc.js", "static/js/316.74c894ba.js": "/static/js/316.74c894ba.js", "static/media/logo.svg": "/static/media/logo.103b5fa18196d5665a7e12318285c916.svg", "index.html": "/index.html", "main.1a7488ce.css.map": "/static/css/main.1a7488ce.css.map", - "main.3eba3908.js.map": "/static/js/main.3eba3908.js.map", + "main.b44531b6.js.map": "/static/js/main.b44531b6.js.map", "runtime-main.de012fdc.js.map": "/static/js/runtime-main.de012fdc.js.map", "316.74c894ba.js.map": "/static/js/316.74c894ba.js.map" }, @@ -18,7 +18,7 @@ exports[`When working with a npm scoped app can generate a asset-manifest 1`] = "static/js/runtime-main.de012fdc.js", "static/js/316.74c894ba.js", "static/css/main.1a7488ce.css", - "static/js/main.3eba3908.js" + "static/js/main.b44531b6.js" ] }" `; @@ -146,7 +146,7 @@ exports[`When working with a npm scoped app can generate a hashed main js chunk self.webpackChunk_scoped_sample_app || []).push([ [179], { - 274: (e, t, a) => { + 354: (e, t, a) => { var r = a(784), l = a(316); const n = a.p + "static/media/logo.103b5fa18196d5665a7e12318285c916.svg"; @@ -190,13 +190,13 @@ exports[`When working with a npm scoped app can generate a hashed main js chunk }, (e) => { e.O(0, [316], () => { - return (t = 274), e((e.s = t)); + return (t = 354), e((e.s = t)); var t; }); e.O(); }, ]); -//# sourceMappingURL=main.3eba3908.js.map +//# sourceMappingURL=main.b44531b6.js.map " `; @@ -8622,7 +8622,7 @@ exports[`When working with a npm scoped app can generate a index.html 1`] = ` })(); - + @@ -8666,13 +8666,13 @@ exports[`When working with an app added in a custom directory can generate a ass "{ "files": { "main.css": "/static/css/main.1a7488ce.css", - "main.js": "/static/js/main.a1b87a25.js", + "main.js": "/static/js/main.fba21b67.js", "runtime-main.js": "/static/js/runtime-main.cef70e6c.js", "static/js/350.44eb2511.js": "/static/js/350.44eb2511.js", "static/media/logo.svg": "/static/media/logo.103b5fa18196d5665a7e12318285c916.svg", "index.html": "/index.html", "main.1a7488ce.css.map": "/static/css/main.1a7488ce.css.map", - "main.a1b87a25.js.map": "/static/js/main.a1b87a25.js.map", + "main.fba21b67.js.map": "/static/js/main.fba21b67.js.map", "runtime-main.cef70e6c.js.map": "/static/js/runtime-main.cef70e6c.js.map", "350.44eb2511.js.map": "/static/js/350.44eb2511.js.map" }, @@ -8680,7 +8680,7 @@ exports[`When working with an app added in a custom directory can generate a ass "static/js/runtime-main.cef70e6c.js", "static/js/350.44eb2511.js", "static/css/main.1a7488ce.css", - "static/js/main.a1b87a25.js" + "static/js/main.fba21b67.js" ] }" `; @@ -8808,7 +8808,7 @@ exports[`When working with an app added in a custom directory can generate a has self.webpackChunk_scoped_custom_app || []).push([ [179], { - 192: (e, t, a) => { + 187: (e, t, a) => { var r = a(902), c = a(350); const l = a.p + "static/media/logo.103b5fa18196d5665a7e12318285c916.svg"; @@ -8852,13 +8852,13 @@ exports[`When working with an app added in a custom directory can generate a has }, (e) => { e.O(0, [350], () => { - return (t = 192), e((e.s = t)); + return (t = 187), e((e.s = t)); var t; }); e.O(); }, ]); -//# sourceMappingURL=main.a1b87a25.js.map +//# sourceMappingURL=main.fba21b67.js.map " `; @@ -17284,7 +17284,7 @@ exports[`When working with an app added in a custom directory can generate a ind })(); - + @@ -17329,16 +17329,16 @@ exports[`when working with a NODE_ENV app can generate a hashed js chunk in the (self.webpackChunknode_env_app = self.webpackChunknode_env_app || []).push([ [179], { - 560: () => { + 908: () => { console.log("production"); }, }, (e) => { var n; - (n = 560), e((e.s = n)); + (n = 908), e((e.s = n)); }, ]); -//# sourceMappingURL=main.6f2657b7.js.map +//# sourceMappingURL=main.a482480b.js.map " `; @@ -17346,13 +17346,13 @@ exports[`when working with a non-scoped app can generate a asset-manifest 1`] = "{ "files": { "main.css": "/static/css/main.1a7488ce.css", - "main.js": "/static/js/main.b81fd1ea.js", + "main.js": "/static/js/main.abe6afa1.js", "runtime-main.js": "/static/js/runtime-main.e92969dd.js", "static/js/316.394ef80b.js": "/static/js/316.394ef80b.js", "static/media/logo.svg": "/static/media/logo.103b5fa18196d5665a7e12318285c916.svg", "index.html": "/index.html", "main.1a7488ce.css.map": "/static/css/main.1a7488ce.css.map", - "main.b81fd1ea.js.map": "/static/js/main.b81fd1ea.js.map", + "main.abe6afa1.js.map": "/static/js/main.abe6afa1.js.map", "runtime-main.e92969dd.js.map": "/static/js/runtime-main.e92969dd.js.map", "316.394ef80b.js.map": "/static/js/316.394ef80b.js.map" }, @@ -17360,7 +17360,7 @@ exports[`when working with a non-scoped app can generate a asset-manifest 1`] = "static/js/runtime-main.e92969dd.js", "static/js/316.394ef80b.js", "static/css/main.1a7488ce.css", - "static/js/main.b81fd1ea.js" + "static/js/main.abe6afa1.js" ] }" `; @@ -17370,7 +17370,7 @@ exports[`when working with a non-scoped app can generate a hashed main js chunk (self.webpackChunksample_app = self.webpackChunksample_app || []).push([ [179], { - 274: (e, t, a) => { + 354: (e, t, a) => { var r = a(784), l = a(316); const n = a.p + "static/media/logo.103b5fa18196d5665a7e12318285c916.svg"; @@ -17419,13 +17419,13 @@ exports[`when working with a non-scoped app can generate a hashed main js chunk }, (e) => { e.O(0, [316], () => { - return (t = 274), e((e.s = t)); + return (t = 354), e((e.s = t)); var t; }); e.O(); }, ]); -//# sourceMappingURL=main.b81fd1ea.js.map +//# sourceMappingURL=main.abe6afa1.js.map " `; @@ -25849,7 +25849,7 @@ exports[`when working with a non-scoped app can generate a index.html 1`] = ` })(); - + diff --git a/packages/modular-scripts/src/__tests__/app.node-env.test.ts b/packages/modular-scripts/src/__tests__/app.node-env.test.ts index 8a47f1713..413e9a6b6 100644 --- a/packages/modular-scripts/src/__tests__/app.node-env.test.ts +++ b/packages/modular-scripts/src/__tests__/app.node-env.test.ts @@ -52,9 +52,9 @@ describe('when working with a NODE_ENV app', () => { expect(tree(path.join(modularRoot, 'dist', 'node-env-app'))) .toMatchInlineSnapshot(` "node-env-app - ├─ asset-manifest.json #v9meuo + ├─ asset-manifest.json #5npfrr ├─ favicon.ico #6pu3rg - ├─ index.html #1d9ei2j + ├─ index.html #9j6678 ├─ logo192.png #1nez7vk ├─ logo512.png #1hwqvcc ├─ manifest.json #19gah8o @@ -62,13 +62,13 @@ describe('when working with a NODE_ENV app', () => { ├─ robots.txt #1sjb8b3 └─ static └─ js - ├─ main.6f2657b7.js #14cwcdk - ├─ main.6f2657b7.js.map #1snt4em + ├─ main.a482480b.js #1xwb1v + ├─ main.a482480b.js.map #4bcy8y ├─ runtime-main.97707f9d.js #15lezt9 └─ runtime-main.97707f9d.js.map #1qz5n9i" `); }); - it('can generate a js/main.5d879077.js', async () => { + it('can generate a js/main.a482480b.js', async () => { expect( prettier.format( String( @@ -79,12 +79,12 @@ describe('when working with a NODE_ENV app', () => { 'node-env-app', 'static', 'js', - 'main.6f2657b7.js', + 'main.a482480b.js', ), ), ), { - filepath: 'main.6f2657b7.js', + filepath: 'main.a482480b.js', }, ), ).toMatchSnapshot(); diff --git a/packages/modular-scripts/src/__tests__/app.test.ts b/packages/modular-scripts/src/__tests__/app.test.ts index 5bb4152d4..171beb460 100644 --- a/packages/modular-scripts/src/__tests__/app.test.ts +++ b/packages/modular-scripts/src/__tests__/app.test.ts @@ -72,9 +72,9 @@ describe('when working with a NODE_ENV app', () => { expect(tree(path.join(modularRoot, 'dist', 'node-env-app'))) .toMatchInlineSnapshot(` "node-env-app - ├─ asset-manifest.json #v9meuo + ├─ asset-manifest.json #5npfrr ├─ favicon.ico #6pu3rg - ├─ index.html #1d9ei2j + ├─ index.html #9j6678 ├─ logo192.png #1nez7vk ├─ logo512.png #1hwqvcc ├─ manifest.json #19gah8o @@ -82,8 +82,8 @@ describe('when working with a NODE_ENV app', () => { ├─ robots.txt #1sjb8b3 └─ static └─ js - ├─ main.6f2657b7.js #14cwcdk - ├─ main.6f2657b7.js.map #1ijkx7g + ├─ main.a482480b.js #1xwb1v + ├─ main.a482480b.js.map #wh4kdy ├─ runtime-main.97707f9d.js #15lezt9 └─ runtime-main.97707f9d.js.map #1qz5n9i" `); @@ -100,12 +100,12 @@ describe('when working with a NODE_ENV app', () => { 'node-env-app', 'static', 'js', - 'main.6f2657b7.js', + 'main.a482480b.js', ), ), ), { - filepath: 'main.6f2657b7.js', + filepath: 'main.a482480b.js', }, ), ).toMatchSnapshot(); @@ -127,9 +127,9 @@ describe('When working with a npm scoped app', () => { expect(tree(path.join(modularRoot, 'dist', 'scoped-sample-app'))) .toMatchInlineSnapshot(` "scoped-sample-app - ├─ asset-manifest.json #osrpxq + ├─ asset-manifest.json #1uspk39 ├─ favicon.ico #6pu3rg - ├─ index.html #8djvlp + ├─ index.html #ysfmfn ├─ logo192.png #1nez7vk ├─ logo512.png #1hwqvcc ├─ manifest.json #19gah8o @@ -143,8 +143,8 @@ describe('When working with a npm scoped app', () => { │ ├─ 316.74c894ba.js #euj72k │ ├─ 316.74c894ba.js.LICENSE.txt #eplx8h │ ├─ 316.74c894ba.js.map #3k9wqz - │ ├─ main.3eba3908.js #1mufyu1 - │ ├─ main.3eba3908.js.map #qj42wj + │ ├─ main.b44531b6.js #16ahtqz + │ ├─ main.b44531b6.js.map #10tofk7 │ ├─ runtime-main.de012fdc.js #1qz643h │ └─ runtime-main.de012fdc.js.map #v3az36 └─ media @@ -244,12 +244,12 @@ describe('When working with a npm scoped app', () => { 'scoped-sample-app', 'static', 'js', - 'main.3eba3908.js', + 'main.b44531b6.js', ), ), ), { - filepath: 'main.3eba3908.js', + filepath: 'main.b44531b6.js', }, ), ).toMatchSnapshot(); @@ -345,9 +345,9 @@ describe('when working with a non-scoped app', () => { expect(tree(path.join(modularRoot, 'dist', 'sample-app'))) .toMatchInlineSnapshot(` "sample-app - ├─ asset-manifest.json #1ivbfl8 + ├─ asset-manifest.json #620pei ├─ favicon.ico #6pu3rg - ├─ index.html #b10qpi + ├─ index.html #1vp7lky ├─ logo192.png #1nez7vk ├─ logo512.png #1hwqvcc ├─ manifest.json #19gah8o @@ -361,8 +361,8 @@ describe('when working with a non-scoped app', () => { │ ├─ 316.394ef80b.js #1mv4xg9 │ ├─ 316.394ef80b.js.LICENSE.txt #eplx8h │ ├─ 316.394ef80b.js.map #o90ydx - │ ├─ main.b81fd1ea.js #14cglcq - │ ├─ main.b81fd1ea.js.map #11wc7t3 + │ ├─ main.abe6afa1.js #t9np46 + │ ├─ main.abe6afa1.js.map #19l0z09 │ ├─ runtime-main.e92969dd.js #1is98ey │ └─ runtime-main.e92969dd.js.map #xx7n2r └─ media @@ -432,12 +432,12 @@ describe('when working with a non-scoped app', () => { 'sample-app', 'static', 'js', - 'main.b81fd1ea.js', + 'main.abe6afa1.js', ), ), ), { - filepath: 'main.b81fd1ea.js', + filepath: 'main.abe6afa1.js', }, ), ).toMatchSnapshot(); @@ -585,9 +585,9 @@ describe('When working with an app added in a custom directory', () => { expect(tree(path.join(modularRoot, 'dist', 'scoped-custom-app'))) .toMatchInlineSnapshot(` "scoped-custom-app - ├─ asset-manifest.json #19ivj4q + ├─ asset-manifest.json #dvvkwh ├─ favicon.ico #6pu3rg - ├─ index.html #1n7abt0 + ├─ index.html #6iz8a6 ├─ logo192.png #1nez7vk ├─ logo512.png #1hwqvcc ├─ manifest.json #19gah8o @@ -601,8 +601,8 @@ describe('When working with an app added in a custom directory', () => { │ ├─ 350.44eb2511.js #4ubhrm │ ├─ 350.44eb2511.js.LICENSE.txt #eplx8h │ ├─ 350.44eb2511.js.map #1yro3n5 - │ ├─ main.a1b87a25.js #1utnqo4 - │ ├─ main.a1b87a25.js.map #cc3byb + │ ├─ main.fba21b67.js #16haxht + │ ├─ main.fba21b67.js.map #bpgpf7 │ ├─ runtime-main.cef70e6c.js #1f77948 │ └─ runtime-main.cef70e6c.js.map #6vl4pa └─ media @@ -702,12 +702,12 @@ describe('When working with an app added in a custom directory', () => { 'scoped-custom-app', 'static', 'js', - 'main.a1b87a25.js', + 'main.fba21b67.js', ), ), ), { - filepath: 'main.a1b87a25.js', + filepath: 'main.fba21b67.js', }, ), ).toMatchSnapshot(); diff --git a/packages/modular-scripts/src/__tests__/esmView.test.ts b/packages/modular-scripts/src/__tests__/esmView.test.ts index 90521d21c..4ca11359d 100644 --- a/packages/modular-scripts/src/__tests__/esmView.test.ts +++ b/packages/modular-scripts/src/__tests__/esmView.test.ts @@ -205,6 +205,65 @@ describe('modular working with an esm-view', () => { }); }); + describe('WHEN starting a esm-view (webpack)', () => { + let browser: puppeteer.Browser; + let devServer: DevServer; + let port: string; + + beforeAll(async () => { + const launchArgs: puppeteer.LaunchOptions & + puppeteer.BrowserLaunchArgumentOptions = { + // always run in headless - if you want to debug this locally use the env var to + headless: !Boolean(process.env.NO_HEADLESS_TESTS), + args: ['--no-sandbox', '--disable-setuid-sandbox'], + }; + + browser = await puppeteer.launch(launchArgs); + port = '4000'; + devServer = await startApp( + targetedView, + { + env: { PORT: port }, + }, + tempModularRepo, + ); + // Wait two seconds to ensure app started fully + await new Promise((f) => setTimeout(f, 2000)); + }); + + afterAll(async () => { + if (browser) { + await browser.close(); + } + if (devServer) { + // this is the problematic bit, it leaves hanging node processes + // despite closing the parent process. Only happens in tests! + void devServer.kill(); + } + if (port) { + // kill all processes listening to the dev server port + exec(`yarnpkg kill-port ${port}`, (err) => { + if (err) { + console.log('err: ', err); + } + console.log(`Cleaned up processes on port ${port}`); + }); + } + }); + + it('THEN can start a esm-view', async () => { + const page = await browser.newPage(); + await page.goto(`http://localhost:${port}`, {}); + + // eslint-disable-next-line @typescript-eslint/unbound-method + const { findByTestId } = getQueriesForElement(await getDocument(page)); + + const form = await findByTestId('test-this'); + const text = await getNodeText(form); + expect(text).toBe('this is a modular esm-view'); + }); + }); + describe('WHEN building a esm-view with a custom ESM CDN', () => { beforeAll(async () => { setupMocks(tempModularRepo); diff --git a/yarn.lock b/yarn.lock index 0d64e8dfd..561a7f989 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5736,17 +5736,19 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" -esbuild-loader@3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/esbuild-loader/-/esbuild-loader-3.0.1.tgz#9871c0e8817c4c11b6249d1916832e75272e6c7e" - integrity sha512-aZfGybqTeuyCd4AsVvWOOfkhIuN+wfZFjMyh3gyQEU1Uvsl8L6vye9HqP93iRa0iTA+6Jclap514PJIC3cLnMA== - dependencies: - esbuild "^0.17.6" - get-tsconfig "^4.4.0" - loader-utils "^2.0.4" +esbuild-loader@^2.16.0: + version "2.21.0" + resolved "https://registry.yarnpkg.com/esbuild-loader/-/esbuild-loader-2.21.0.tgz#2698a3e565b0db2bb19a3dd91c2b6c9aad526c80" + integrity sha512-k7ijTkCT43YBSZ6+fBCW1Gin7s46RrJ0VQaM8qA7lq7W+OLsGgtLyFV8470FzYi/4TeDexniTBTPTwZUnXXR5g== + dependencies: + esbuild "^0.16.17" + joycon "^3.0.1" + json5 "^2.2.0" + loader-utils "^2.0.0" + tapable "^2.2.0" webpack-sources "^1.4.3" -esbuild@0.17.14, esbuild@^0.17.6: +esbuild@0.17.14, esbuild@^0.16.17: version "0.17.14" resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.17.14.tgz#d61a22de751a3133f3c6c7f9c1c3e231e91a3245" integrity sha512-vOO5XhmVj/1XQR9NQ1UPq6qvMYL7QFJU57J5fKBKBKxp17uDt5PgxFDb4A2nEiXhr1qQs4x0F5+66hVVw4ruNw== @@ -6650,11 +6652,6 @@ get-them-args@1.3.2: resolved "https://registry.npmjs.org/get-them-args/-/get-them-args-1.3.2.tgz" integrity sha512-LRn8Jlk+DwZE4GTlDbT3Hikd1wSHgLMme/+7ddlqKd7ldwR6LjJgTVWzBnR01wnYGe4KgrXjg287RaI22UHmAw== -get-tsconfig@^4.4.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.5.0.tgz#6d52d1c7b299bd3ee9cd7638561653399ac77b0f" - integrity sha512-MjhiaIWCJ1sAU4pIQ5i5OfOuHHxVo1oYeNsWTON7jxYkod8pHocXeh+SSbmu5OZZZK73B6cbJ2XADzXehLyovQ== - glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" @@ -8086,7 +8083,7 @@ jest@^29.5.0: import-local "^3.0.2" jest-cli "^29.5.0" -joycon@^3.1.1: +joycon@^3.0.1, joycon@^3.1.1: version "3.1.1" resolved "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz" integrity sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw== @@ -8205,7 +8202,7 @@ json5@^2.1.2, json5@^2.2.1: resolved "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz" integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== -json5@^2.2.3: +json5@^2.2.0, json5@^2.2.3: version "2.2.3" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== @@ -8405,7 +8402,7 @@ loader-utils@3.2.0: resolved "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.0.tgz" integrity sha512-HVl9ZqccQihZ7JM85dco1MvO9G+ONvxoGa9rkhzFsneGLKSUg1gJf9bWzhRhcvm2qChhWpebQhP44qxjKIUCaQ== -loader-utils@^2.0.0, loader-utils@^2.0.4: +loader-utils@^2.0.0: version "2.0.4" resolved "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz" integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw== From 319c91b1ea7e30b4e7b2d5b5df938789ac765421 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 15 May 2023 14:34:41 +0000 Subject: [PATCH 13/42] Version Packages --- .changeset/fifty-rats-add.md | 5 ----- packages/modular-scripts/CHANGELOG.md | 9 +++++++++ packages/modular-scripts/package.json | 2 +- 3 files changed, 10 insertions(+), 6 deletions(-) delete mode 100644 .changeset/fifty-rats-add.md diff --git a/.changeset/fifty-rats-add.md b/.changeset/fifty-rats-add.md deleted file mode 100644 index 301bb56a8..000000000 --- a/.changeset/fifty-rats-add.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'modular-scripts': patch ---- - -Fix esm-views not starting diff --git a/packages/modular-scripts/CHANGELOG.md b/packages/modular-scripts/CHANGELOG.md index 0e0f073b3..110f356a4 100644 --- a/packages/modular-scripts/CHANGELOG.md +++ b/packages/modular-scripts/CHANGELOG.md @@ -1,5 +1,14 @@ # modular-scripts +## 4.4.1 + +### Patch Changes + +- [#2385](https://github.com/jpmorganchase/modular/pull/2385) + [`5ba67bf`](https://github.com/jpmorganchase/modular/commit/5ba67bf81e737bae49c6aa9ee46c36b8986f6127) + Thanks [@AlbertoBrusa](https://github.com/AlbertoBrusa)! - Fix esm-views not + starting + ## 4.4.0 ### Minor Changes diff --git a/packages/modular-scripts/package.json b/packages/modular-scripts/package.json index 363840f5a..afd4bee19 100644 --- a/packages/modular-scripts/package.json +++ b/packages/modular-scripts/package.json @@ -1,6 +1,6 @@ { "name": "modular-scripts", - "version": "4.4.0", + "version": "4.4.1", "license": "Apache-2.0", "repository": { "type": "git", From 0a924739a5ba03c9a3bcf4a9e44d895b3e261f53 Mon Sep 17 00:00:00 2001 From: Alberto Brusa <94554131+AlbertoBrusa@users.noreply.github.com> Date: Tue, 16 May 2023 13:08:42 +0100 Subject: [PATCH 14/42] Update packages/modular-scripts/src/lint.ts Co-authored-by: Sam Brown --- packages/modular-scripts/src/lint.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/modular-scripts/src/lint.ts b/packages/modular-scripts/src/lint.ts index 932a54b48..9a29fa861 100644 --- a/packages/modular-scripts/src/lint.ts +++ b/packages/modular-scripts/src/lint.ts @@ -47,7 +47,7 @@ async function lint( if ((staged || diff || userRegexes.length) && isSelective) { logger.error( - "Can't specify --staged --diff --regex along with selective options", + "Can't specify --staged, --diff or --regex along with selective options", ); process.exit(-1); } From e657f4a28db7629235e19ccb9e5bd71853f234c8 Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Tue, 16 May 2023 15:40:24 +0100 Subject: [PATCH 15/42] Improve documentation of commands --- docs/commands/test.md | 3 ++- packages/modular-scripts/src/program.ts | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/commands/test.md b/docs/commands/test.md index 46ab62851..922766553 100644 --- a/docs/commands/test.md +++ b/docs/commands/test.md @@ -91,7 +91,8 @@ which files have changed when using the `changed` option. If this option is used without `changed`, the command will fail. `--regex `: Select all the test files matching the specified regular -expressions. Can be combined with all the other selective options. +expressions. When combined with selective options, it will run all tests +matching the selective options, and tests that match the regexes provided. `--verbose`: Activate debug logging. Useful to see which packages have been selected and which regular expression and arguments have been passed to the diff --git a/packages/modular-scripts/src/program.ts b/packages/modular-scripts/src/program.ts index 557201e7d..f3523fc16 100755 --- a/packages/modular-scripts/src/program.ts +++ b/packages/modular-scripts/src/program.ts @@ -207,7 +207,7 @@ program ) .option( '--regex ', - 'Specifies one or more test name regular expression', + 'Specifies one or more test name regular expression. When combined with selective options, it will run tests matching the regex as well as those matching the selective options', ) .option('--coverage', testOptions.coverage.description) .option('--forceExit', testOptions.forceExit.description) From 0605ea097b78599c84af221478e17a27335f46fb Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Wed, 17 May 2023 11:02:43 +0100 Subject: [PATCH 16/42] Workspace resolver respects .modularignore or .gitignore --- packages/workspace-resolver/package.json | 4 +- .../src/resolve-workspace.ts | 42 ++++++++++++++++--- yarn.lock | 12 ++++++ 3 files changed, 52 insertions(+), 6 deletions(-) diff --git a/packages/workspace-resolver/package.json b/packages/workspace-resolver/package.json index c5dafe0c9..61a07ad25 100644 --- a/packages/workspace-resolver/package.json +++ b/packages/workspace-resolver/package.json @@ -6,11 +6,13 @@ "dependencies": { "fs-extra": "^10.1.0", "globby": "11.1.0", + "parse-gitignore": "^1.0.1", "semver": "7.3.7" }, "devDependencies": { "@modular-scripts/modular-types": "1.2.0", - "@types/fs-extra": "^9.0.13" + "@types/fs-extra": "^9.0.13", + "@types/parse-gitignore": "^1.0.0" }, "scripts": { "build": "tsc && babel --source-maps --root-mode upward src --out-dir dist-cjs --extensions .ts --ignore **/__tests__", diff --git a/packages/workspace-resolver/src/resolve-workspace.ts b/packages/workspace-resolver/src/resolve-workspace.ts index 2f7b38465..a999c65f7 100644 --- a/packages/workspace-resolver/src/resolve-workspace.ts +++ b/packages/workspace-resolver/src/resolve-workspace.ts @@ -1,7 +1,8 @@ import path, { join } from 'path'; -import { readJson } from 'fs-extra'; +import { existsSync, readFileSync, readJson } from 'fs-extra'; import globby from 'globby'; import semver from 'semver'; +import parse from 'parse-gitignore'; import type { ModularPackageJson, ModularWorkspacePackage, @@ -17,7 +18,7 @@ function packageJsonPath(dir: string) { } function resolveWorkspacesDefinition( - cwd: string, + root: string, def: ModularPackageJson['workspaces'], ): string[] { if (!def) { @@ -30,13 +31,13 @@ function resolveWorkspacesDefinition( [`${path}/package.json`, '!**/node_modules/**/*', '!**/__tests__/**/*'], { absolute: false, - cwd, + cwd: root, }, ); }); } - return resolveWorkspacesDefinition(cwd, def.packages); + return resolveWorkspacesDefinition(root, def.packages); } function readPackageJson( @@ -138,7 +139,38 @@ export async function resolveWorkspace( child && pkg.children.push(child); } - return [collector, pkg]; + // Filter out workspaces covered by .modularignore or .gitignore + const filteredCollector = new Map(); + let ignorePatterns: string[] | undefined; + + const modularIgnorePath = path.join(root, '.modularignore'); + const gitIgnore = path.join(root, '.gitignore'); + + if (existsSync(modularIgnorePath)) { + ignorePatterns = parse(readFileSync(modularIgnorePath)); + } else if (existsSync(gitIgnore)) { + ignorePatterns = parse(readFileSync(gitIgnore)); + } + + if (ignorePatterns) { + collector.forEach((pkg, name) => { + let matches = false; + ignorePatterns?.forEach((pattern) => { + if (pattern.startsWith(path.sep)) { + matches = pkg.location.startsWith(pattern.substring(1)) + ? true + : matches; + } else { + matches = pkg.location.includes(pattern) ? true : matches; + } + }); + if (!matches) { + filteredCollector.set(name, pkg); + } + }); + } + + return [filteredCollector, pkg]; } export function analyzeWorkspaceDependencies( diff --git a/yarn.lock b/yarn.lock index 59b7d3afb..ffa5bc863 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3119,6 +3119,13 @@ "@types/npmlog" "*" "@types/ssri" "*" +"@types/parse-gitignore@^1.0.0": + version "1.0.0" + resolved "https://registry.npmjs.org/@types/parse-gitignore/-/parse-gitignore-1.0.0.tgz#782b2b6179cef4daaf9b8bd312bfe796fdc8aa18" + integrity sha512-GCL7NIxhUzJ1M5bp68T8DtDVTbQdw93MPIIII+YASs3icSozMEG9ZjX7pp7ldRJrVgrRtJBwy+/g+aBzCIttlg== + dependencies: + "@types/node" "*" + "@types/parse-json@^4.0.0": version "4.0.0" resolved "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz" @@ -9489,6 +9496,11 @@ parse-conflict-json@^3.0.0: just-diff "^5.0.1" just-diff-apply "^5.2.0" +parse-gitignore@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parse-gitignore/-/parse-gitignore-1.0.1.tgz#8b9dc57f17b810d495c5dfa62eb07caffe7758c7" + integrity sha512-UGyowyjtx26n65kdAMWhm6/3uy5uSrpcuH7tt+QEVudiBoVS+eqHxD5kbi9oWVRwj7sCzXqwuM+rUGw7earl6A== + parse-json@^5.0.0, parse-json@^5.2.0: version "5.2.0" resolved "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz" From 6209e17bbe90eaa0296c291ba26eafebf8a6591f Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Wed, 17 May 2023 11:12:34 +0100 Subject: [PATCH 17/42] Documentation and changeset --- .changeset/eight-bats-double.md | 6 ++++++ docs/configuration.md | 6 ++++++ 2 files changed, 12 insertions(+) create mode 100644 .changeset/eight-bats-double.md diff --git a/.changeset/eight-bats-double.md b/.changeset/eight-bats-double.md new file mode 100644 index 000000000..6f026939e --- /dev/null +++ b/.changeset/eight-bats-double.md @@ -0,0 +1,6 @@ +--- +'modular-scripts': major +--- + +Modular's workspace resolver now ignores a workspace if covered by a +.modularignore or .gitignore (.modularignore overrides .gitignore) diff --git a/docs/configuration.md b/docs/configuration.md index de0079828..a2ef48f54 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -121,3 +121,9 @@ _e.g._ The `package.json#modular.type` can be `"root"`, `"app"`, `"view"`, `"esm-view"`, `"source"`, `"template"` or `"package"`. Read more about Modular types in [this explainer](/docs/package-types). + +## `.modularignore` & `.gitignore` + +Modular respects `.gitignore` when identifying workspaces in the repository, +ignoring any workspaces covered by the repo's `.gitignore`. This behavior can be +overridden by providing a `.modularignore`. From 114b5d4e96d1125b3ed2ee0d4a4d1ad57222d960 Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Wed, 17 May 2023 11:18:56 +0100 Subject: [PATCH 18/42] Add .modularignore --- .modularignore | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 .modularignore diff --git a/.modularignore b/.modularignore new file mode 100644 index 000000000..e69de29bb From 49edc96615212a29f23ee565f507c68b04a9e5a0 Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Wed, 17 May 2023 15:04:47 +0100 Subject: [PATCH 19/42] Simplify with updated globby --- packages/workspace-resolver/package.json | 2 +- .../src/resolve-workspace.ts | 59 +++++++------------ yarn.lock | 16 +++++ 3 files changed, 39 insertions(+), 38 deletions(-) diff --git a/packages/workspace-resolver/package.json b/packages/workspace-resolver/package.json index 61a07ad25..32f95f3b3 100644 --- a/packages/workspace-resolver/package.json +++ b/packages/workspace-resolver/package.json @@ -5,7 +5,7 @@ "main": "src/index.ts", "dependencies": { "fs-extra": "^10.1.0", - "globby": "11.1.0", + "@esm2cjs/globby": "13.1.4", "parse-gitignore": "^1.0.1", "semver": "7.3.7" }, diff --git a/packages/workspace-resolver/src/resolve-workspace.ts b/packages/workspace-resolver/src/resolve-workspace.ts index a999c65f7..2a69b82ac 100644 --- a/packages/workspace-resolver/src/resolve-workspace.ts +++ b/packages/workspace-resolver/src/resolve-workspace.ts @@ -1,8 +1,7 @@ import path, { join } from 'path'; -import { existsSync, readFileSync, readJson } from 'fs-extra'; -import globby from 'globby'; +import { existsSync, readJson } from 'fs-extra'; +import { globbySync } from '@esm2cjs/globby'; import semver from 'semver'; -import parse from 'parse-gitignore'; import type { ModularPackageJson, ModularWorkspacePackage, @@ -20,24 +19,25 @@ function packageJsonPath(dir: string) { function resolveWorkspacesDefinition( root: string, def: ModularPackageJson['workspaces'], + ignoreFiles: string[], ): string[] { if (!def) { return []; } - if (Array.isArray(def)) { return def.flatMap((path: string) => { - return globby.sync( + return globbySync( [`${path}/package.json`, '!**/node_modules/**/*', '!**/__tests__/**/*'], { absolute: false, cwd: root, + ignoreFiles: ignoreFiles, }, ); }); } - return resolveWorkspacesDefinition(root, def.packages); + return resolveWorkspacesDefinition(root, def.packages, ignoreFiles); } function readPackageJson( @@ -129,48 +129,33 @@ export async function resolveWorkspace( } } - for (const link of resolveWorkspacesDefinition(root, json.workspaces)) { - const [, child] = await resolveWorkspace( - link, - workingDirToUse, - pkg, - collector, - ); - child && pkg.children.push(child); - } - // Filter out workspaces covered by .modularignore or .gitignore - const filteredCollector = new Map(); - let ignorePatterns: string[] | undefined; + const ignoreFiles: string[] = []; const modularIgnorePath = path.join(root, '.modularignore'); const gitIgnore = path.join(root, '.gitignore'); if (existsSync(modularIgnorePath)) { - ignorePatterns = parse(readFileSync(modularIgnorePath)); + ignoreFiles.push('.modularignore'); } else if (existsSync(gitIgnore)) { - ignorePatterns = parse(readFileSync(gitIgnore)); + ignoreFiles.push('.gitignore'); } - if (ignorePatterns) { - collector.forEach((pkg, name) => { - let matches = false; - ignorePatterns?.forEach((pattern) => { - if (pattern.startsWith(path.sep)) { - matches = pkg.location.startsWith(pattern.substring(1)) - ? true - : matches; - } else { - matches = pkg.location.includes(pattern) ? true : matches; - } - }); - if (!matches) { - filteredCollector.set(name, pkg); - } - }); + for (const link of resolveWorkspacesDefinition( + root, + json.workspaces, + ignoreFiles, + )) { + const [, child] = await resolveWorkspace( + link, + workingDirToUse, + pkg, + collector, + ); + child && pkg.children.push(child); } - return [filteredCollector, pkg]; + return [collector, pkg]; } export function analyzeWorkspaceDependencies( diff --git a/yarn.lock b/yarn.lock index ffa5bc863..073477d33 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1645,6 +1645,22 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" +"@esm2cjs/globby@13.1.4": + version "13.1.4" + resolved "https://registry.yarnpkg.com/@esm2cjs/globby/-/globby-13.1.4.tgz#38794c6b560654cb94e413b78ab568acf594bd6f" + integrity sha512-JES/VBjQfk78esAY7SSVk2c77v94UKVlOPPTP5HBFRjY5IIr0hjE6B3LzYzY98oaO9ygYVy5CURGdxasDVGv1g== + dependencies: + "@esm2cjs/slash" "^4.0.0" + dir-glob "^3.0.1" + fast-glob "^3.2.11" + ignore "^5.2.0" + merge2 "^1.4.1" + +"@esm2cjs/slash@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@esm2cjs/slash/-/slash-4.0.0.tgz#5101e35a912eeb308c34f448c81cf353048d59b5" + integrity sha512-UUTg4pcAaq1D3R4yj0T+up/eBnZko6nE0ToBq6m6c0rHmpYPIGh/UrNMEeZV2hkLKpXBg6i1Zr9tJgmXq1T2BA== + "@floating-ui/core@^0.7.3": version "0.7.3" resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-0.7.3.tgz#d274116678ffae87f6b60e90f88cc4083eefab86" From 3212041d4a5e8ec510ac0e31d6955aebe3990794 Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Wed, 17 May 2023 15:31:15 +0100 Subject: [PATCH 20/42] Remove unused packages --- packages/workspace-resolver/package.json | 6 ++---- yarn.lock | 12 ------------ 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/packages/workspace-resolver/package.json b/packages/workspace-resolver/package.json index 32f95f3b3..0e69310a3 100644 --- a/packages/workspace-resolver/package.json +++ b/packages/workspace-resolver/package.json @@ -4,15 +4,13 @@ "license": "Apache-2.0", "main": "src/index.ts", "dependencies": { - "fs-extra": "^10.1.0", "@esm2cjs/globby": "13.1.4", - "parse-gitignore": "^1.0.1", + "fs-extra": "^10.1.0", "semver": "7.3.7" }, "devDependencies": { "@modular-scripts/modular-types": "1.2.0", - "@types/fs-extra": "^9.0.13", - "@types/parse-gitignore": "^1.0.0" + "@types/fs-extra": "^9.0.13" }, "scripts": { "build": "tsc && babel --source-maps --root-mode upward src --out-dir dist-cjs --extensions .ts --ignore **/__tests__", diff --git a/yarn.lock b/yarn.lock index 073477d33..134a3b7d3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3135,13 +3135,6 @@ "@types/npmlog" "*" "@types/ssri" "*" -"@types/parse-gitignore@^1.0.0": - version "1.0.0" - resolved "https://registry.npmjs.org/@types/parse-gitignore/-/parse-gitignore-1.0.0.tgz#782b2b6179cef4daaf9b8bd312bfe796fdc8aa18" - integrity sha512-GCL7NIxhUzJ1M5bp68T8DtDVTbQdw93MPIIII+YASs3icSozMEG9ZjX7pp7ldRJrVgrRtJBwy+/g+aBzCIttlg== - dependencies: - "@types/node" "*" - "@types/parse-json@^4.0.0": version "4.0.0" resolved "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz" @@ -9512,11 +9505,6 @@ parse-conflict-json@^3.0.0: just-diff "^5.0.1" just-diff-apply "^5.2.0" -parse-gitignore@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/parse-gitignore/-/parse-gitignore-1.0.1.tgz#8b9dc57f17b810d495c5dfa62eb07caffe7758c7" - integrity sha512-UGyowyjtx26n65kdAMWhm6/3uy5uSrpcuH7tt+QEVudiBoVS+eqHxD5kbi9oWVRwj7sCzXqwuM+rUGw7earl6A== - parse-json@^5.0.0, parse-json@^5.2.0: version "5.2.0" resolved "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz" From 034cc2976416453f877c9fc2ee126af0c6cfbc33 Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Wed, 17 May 2023 17:04:44 +0100 Subject: [PATCH 21/42] Fix changeset --- .changeset/eight-bats-double.md | 1 + 1 file changed, 1 insertion(+) diff --git a/.changeset/eight-bats-double.md b/.changeset/eight-bats-double.md index 6f026939e..f1dbb2adf 100644 --- a/.changeset/eight-bats-double.md +++ b/.changeset/eight-bats-double.md @@ -1,5 +1,6 @@ --- 'modular-scripts': major +'@modular-scripts/workspace-resolver': major --- Modular's workspace resolver now ignores a workspace if covered by a From ffcadd8b64d10b9abd6bcc1a5b21c8fa6cd1b656 Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Thu, 18 May 2023 10:19:44 +0100 Subject: [PATCH 22/42] Documentation improvements --- docs/commands/lint.md | 30 ++++++++------ docs/commands/test.md | 83 ++++++++++++++++++-------------------- docs/commands/typecheck.md | 18 ++++++++- 3 files changed, 73 insertions(+), 58 deletions(-) diff --git a/docs/commands/lint.md b/docs/commands/lint.md index b8f580a25..1918479ab 100644 --- a/docs/commands/lint.md +++ b/docs/commands/lint.md @@ -29,23 +29,33 @@ status of each file (`PASS` or `FAIL`). If a file has a lint warning, the command will be marked as failed, with printed eslint errors for each warning/error. -## Default behaviour +## Default behavior `modular lint` without arguments or options will lint all packages in the repository, and run any `lint` scripts specified in the `package.json` of any non-modular packages. -## Options: +### Lint Unique Options: -`--staged`: Lints only files staged on git (not compatible with `--all` and with -the Selective Options) - -`--diff`: Lints only files that have changed compared to the default branch or -branch specified with `--compareBranch` +These options are unique to the lint command and differ to other Modular command +options. `--fix`: Allows eslint to fix the errors and warnings that do not require manual intervention wherever possible. Restages any fixed files that were previously -staged when used in combination with `--staged`. +staged when used in combination with `--staged`. Can be combined with any other +option. + +`--compareBranch `: Specify the comparison branch used to determine +which files have changed when using the `changed` or `diff` option. If this +option is used without `changed` or `diff`, the command will fail. + +The following options are not compatible with selective options, and cannot be +combined with each other. + +`--staged`: Lints only files staged on git + +`--diff`: Lints only files that have changed compared to the default branch or +branch specified with `--compareBranch` `--regex [regexes...]`: A list of one or more regexes to select files to lint. @@ -63,7 +73,3 @@ to the lint list. changed, calculated comparing the current state of the git repository with the branch specified by `compareBranch` or, if `compareBranch` is not set, with the default branch. - -`--compareBranch `: Specify the comparison branch used to determine -which files have changed when using the `changed` option. If this option is used -without `changed`, the command will fail. diff --git a/docs/commands/test.md b/docs/commands/test.md index 922766553..afaf02b68 100644 --- a/docs/commands/test.md +++ b/docs/commands/test.md @@ -7,28 +7,25 @@ title: modular test Search workspaces based on their `name` field in the `package.json` and test: -- Modular packages, according to their respective `modular.type`. In this case, +- Modular packages (packages with a `modular` field in their `package.json`). `modular test` will act as an opinionated wrapper around - [`jest`](https://jestjs.io/), which comes with out-of-the-box configuration. -- Non-Modular packages (i.e. packages without a `modular` configuration), only - if they have a `test` + [`jest`](https://jestjs.io/), with a predefined Modular configuration. +- Non-Modular packages (packages without a `modular` field in their + `package.json`), only if they have a `test` [script](https://docs.npmjs.com/cli/v9/configuring-npm/package-json#scripts), by running `yarn test` on the package's [workspace](https://classic.yarnpkg.com/en/docs/cli/workspace). When the `[packages...]` argument is empty and no selective option has been -specified (for example when running `yarn modular test`), tests will be run for -all testable packages in the repo. When the `[packages...]` argument contains -one or more non-existing package name, the non-existing packages will be ignored -without an error. If any package or selective option have been defined but -Modular can't find any package to test, Modular will warn on `stdout` and exit -with code `0`. - -Test order is unspecified by design, so please don't rely on the assumption that -certain tests will run before others, that Modular tests will run before -non-Modular tests, or that they will run sequentially. An exception to this, -valid only for Modular tests (that are run by Jest), is when -[the `--runinband` option is specified](https://jestjs.io/docs/cli#--runinband). +specified (ie `yarn modular test`), all packages will be tested. When the +`[packages...]` argument contains one or more non-existing package name, the +non-existing packages will be ignored without an error. If Modular can't find +any package to test, Modular will warn on `stdout` and exit with code `0`. + +Test order is unspecified, so don't rely on Modular to run certain tests before +others, that Modular tests will run before non-Modular tests, or that they will +run sequentially unless running Modular tests with +[the `--runinband` option](https://jestjs.io/docs/cli#--runinband). ## Configuration @@ -46,20 +43,16 @@ This contains the setup for tests corresponding to ### Arguments -`[packages ...]`: List of packages to test. Can be combined with multiple -selective options (`--ancestors`, `--descendants`, `--changed` and `--regex`). -Modular will generate a list of regular expressions that satisfies all options -passed which are then passed to Jest. The tests will run in non-predictable -order. When `packages` is empty and no selective options have been specified -(for example when running `yarn modular test`), all tests in the monorepo will -be executed. When `packages` contains one or more non-existing package name, the -non-existing packages will be ignored without an error. If any package or -selective option have been defined but the final set of regular expressions is -empty, Modular will write a message to `stdout` and exit with code `0`. +`[packages ...]`: Packages to test. Can be combined with multiple selective +options (`--ancestors`, `--descendants`, `--changed` and `--regex`). Modular +will pass a list of regular expressions that satisfies all options to Jest. + +### Test Unique Options: -### Modular-specific options +These options are unique to the test command and differ to other Modular command +options. -`--bypass`: Bypass Modular selective behaviour and flags, and send all provided +`--bypass`: Bypass Modular selective behavior and flags, and send all provided flags and options directly to the Jest process with Modular configuration. Useful when running `modular test` from IntelliJ. @@ -68,6 +61,24 @@ of babel + ts-jest. Brings significant performance improvements, but ignores ts-config in favour of its own configuration file, [.swcrc](https://swc.rs/docs/configuration/swcrc). +`--debug`: Add the `--inspect-brk` option to the Node.js process executing Jest +to allow a debugger to be attached to the running process. For more information, +[see the Node.js debugging guide](https://nodejs.org/en/docs/guides/debugging-getting-started/). + +`--compareBranch `: Specify the comparison branch used to determine +which files have changed when using the `changed` option. If this option is used +without `changed`, the command will fail. + +`--verbose`: Activate debug logging. Useful to see which packages have been +selected and which regular expression and arguments have been passed to the +underlying Jest process. + +`--regex `: Select all the test files matching the specified regular +expressions. When combined with selective options, it will run all tests +matching the selective options, and tests that match the regexes provided. + +### Selective Options + `--ancestors`: Take the packages specified by the user via arguments or options and add their ancestors (i.e. the packages that have a direct or indirect dependency on them) to the test list. @@ -82,22 +93,6 @@ calculated comparing the current state of the git repository with the branch specified by `compareBranch` or, if `compareBranch` is not set, with the default branch. -`--debug`: Add the `--inspect-brk` option to the Node.js process executing Jest -to allow a debugger to be attached to the running process. For more information, -[see the Node.js debugging guide](https://nodejs.org/en/docs/guides/debugging-getting-started/). - -`--compareBranch `: Specify the comparison branch used to determine -which files have changed when using the `changed` option. If this option is used -without `changed`, the command will fail. - -`--regex `: Select all the test files matching the specified regular -expressions. When combined with selective options, it will run all tests -matching the selective options, and tests that match the regexes provided. - -`--verbose`: Activate debug logging. Useful to see which packages have been -selected and which regular expression and arguments have been passed to the -underlying Jest process. - ### Jest CLI Options `modular test` additionally supports passing diff --git a/docs/commands/typecheck.md b/docs/commands/typecheck.md index f21435e8b..99177ba4d 100644 --- a/docs/commands/typecheck.md +++ b/docs/commands/typecheck.md @@ -47,9 +47,19 @@ There are certain exceptions for practical use cases. The current allowlist is: Some use cases may warrant new exceptions. If this is you, please file an issue with the project for consideration. -## Options: +## Command line options and arguments -`--verbose`: Enables verbose logging within modular +### Default Behavior + +`modular typecheck` without any options will typecheck all packages + +### Non Modular Packages + +If non modular packages (packages without a `modular` field in their +`package.json`) are included in the selection, Modular will attempt to run the +`typecheck` script in their `package.json` if specified. + +### Selective Options `--descendants`: Typecheck the packages specified by the `[packages...]` argument and/or the `--changed` option and additionally typecheck all their @@ -67,3 +77,7 @@ of the repository with the branch specified by `compareBranch` or, if `--compareBranch`: Specify the comparison branch used to determine which files have changed when using the `changed` option. If this option is used without `changed`, the command will fail. + +### Other options + +`--verbose`: Enables verbose logging within modular From 0fbc74778747165abca4272f0a621425948c3b94 Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Thu, 18 May 2023 10:52:49 +0100 Subject: [PATCH 23/42] update caniuse --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index a3394d8fb..a3ba0e08a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4507,9 +4507,9 @@ caniuse-api@^3.0.0: lodash.uniq "^4.5.0" caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001332, caniuse-lite@^1.0.30001400, caniuse-lite@^1.0.30001426: - version "1.0.30001434" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001434.tgz" - integrity sha512-aOBHrLmTQw//WFa2rcF1If9fa3ypkC1wzqqiKHgfdrXTWcU8C4gKVZT77eQAPWN1APys3+uQ0Df07rKauXGEYA== + version "1.0.30001488" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001488.tgz" + integrity sha512-NORIQuuL4xGpIy6iCCQGN4iFjlBXtfKWIenlUuyZJumLRIindLb7wXM+GO8erEhb7vXfcnf4BAg2PrSDN5TNLQ== capital-case@^1.0.4: version "1.0.4" From e69149b9a26dccb9ebb1993e125c16b3be5815bf Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Thu, 18 May 2023 12:00:19 +0100 Subject: [PATCH 24/42] Update snapshots --- .../createEsbuildBrowserslistTarget.test.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/modular-scripts/src/__tests__/utils/createEsbuildBrowserslistTarget.test.ts b/packages/modular-scripts/src/__tests__/utils/createEsbuildBrowserslistTarget.test.ts index fd8d077ee..613ae0680 100644 --- a/packages/modular-scripts/src/__tests__/utils/createEsbuildBrowserslistTarget.test.ts +++ b/packages/modular-scripts/src/__tests__/utils/createEsbuildBrowserslistTarget.test.ts @@ -34,9 +34,9 @@ describe('createEsbuildBrowserslistTarget', () => { const result = createEsbuildBrowserslistTarget(process.cwd()); expect(result).toMatchInlineSnapshot(` [ - "chrome107", - "firefox107", - "safari16.1", + "chrome113", + "firefox113", + "safari16.4", ] `); }); @@ -59,9 +59,9 @@ describe('createEsbuildBrowserslistTarget', () => { const result = createEsbuildBrowserslistTarget(process.cwd()); expect(result).toMatchInlineSnapshot(` [ - "chrome107", - "firefox107", - "safari16.1", + "chrome113", + "firefox113", + "safari16.4", ] `); }); @@ -84,9 +84,9 @@ describe('createEsbuildBrowserslistTarget', () => { const result = createEsbuildBrowserslistTarget(process.cwd()); expect(result).toMatchInlineSnapshot(` [ - "chrome107", - "firefox107", - "safari16.1", + "chrome113", + "firefox113", + "safari16.4", ] `); }); From 1f7eec8e5e6dec841ed63a2cd73521cc3f965b4f Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Fri, 19 May 2023 17:06:46 +0100 Subject: [PATCH 25/42] Fix bypass command --- packages/modular-scripts/src/program.ts | 2 +- packages/modular-scripts/src/test/index.ts | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/packages/modular-scripts/src/program.ts b/packages/modular-scripts/src/program.ts index df62d8efc..75c8fc916 100755 --- a/packages/modular-scripts/src/program.ts +++ b/packages/modular-scripts/src/program.ts @@ -174,7 +174,7 @@ program .command('test [packages...]') .option( '--bypass', - 'Bypass all modular specific selective behaviour and pass all flags and options directly to Jest. Ensures modular test behaves exactly like calling Jest directly, but with Modular configuration applied. Use with IntelliJ Jest configurations.', + 'Bypass all modular specific selective behavior and pass all flags and options directly to Jest, except for --verbose, --swc & --env which can be used with --bypass. Ensures modular test behaves exactly like calling Jest directly, but with Modular configuration applied. Use with IntelliJ Jest configurations.', false, ) .option( diff --git a/packages/modular-scripts/src/test/index.ts b/packages/modular-scripts/src/test/index.ts index 97f2fbb6f..0ec907cfb 100644 --- a/packages/modular-scripts/src/test/index.ts +++ b/packages/modular-scripts/src/test/index.ts @@ -118,12 +118,14 @@ async function test(options: TestOptions, packages?: string[]): Promise { let nonModularTargets; let modularTargets; + // If --bypass, pass on all options to jest if (bypass) { - // pass on all options + // Modular flags compatible with --bypass that shouldn't be passed to Jest + const bypassCompatibleFlags = ['verbose', 'env', 'swc', 'bypass']; cleanArgv.push( ...Object.entries(options) .filter(([key, v]) => { - return key !== 'jest' && key !== 'env'; + return !bypassCompatibleFlags.some((option) => key === option); }) .map(([key, v]) => { const booleanValue = /^(true)$/.exec(String(v)); @@ -133,10 +135,7 @@ async function test(options: TestOptions, packages?: string[]): Promise { // Get the options that have been incorrectly placed in packages[] if (packages) { - const additionalOptions: string[] = []; - const cleanPackages: string[] = []; - extractOptions(packages, cleanPackages, additionalOptions); - cleanArgv.push(...additionalOptions); + cleanArgv.push(...packages); } } else { // pass on jest programatic options From e4f583fbe1e30212d88d2b51b5ab0dd549a77e6d Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Fri, 19 May 2023 17:08:27 +0100 Subject: [PATCH 26/42] changeset --- .changeset/beige-toes-invent.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/beige-toes-invent.md diff --git a/.changeset/beige-toes-invent.md b/.changeset/beige-toes-invent.md new file mode 100644 index 000000000..c840c8faf --- /dev/null +++ b/.changeset/beige-toes-invent.md @@ -0,0 +1,5 @@ +--- +'modular-scripts': patch +--- + +Fix --bypass flag in test command From 12e1bc4b94fb32d987d1508591c301e4777a7ed6 Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Fri, 19 May 2023 17:13:36 +0100 Subject: [PATCH 27/42] update browserlist --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 561a7f989..3ea23f11f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4514,9 +4514,9 @@ caniuse-api@^3.0.0: lodash.uniq "^4.5.0" caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001332, caniuse-lite@^1.0.30001400, caniuse-lite@^1.0.30001426: - version "1.0.30001434" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001434.tgz" - integrity sha512-aOBHrLmTQw//WFa2rcF1If9fa3ypkC1wzqqiKHgfdrXTWcU8C4gKVZT77eQAPWN1APys3+uQ0Df07rKauXGEYA== + version "1.0.30001488" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001488.tgz" + integrity sha512-NORIQuuL4xGpIy6iCCQGN4iFjlBXtfKWIenlUuyZJumLRIindLb7wXM+GO8erEhb7vXfcnf4BAg2PrSDN5TNLQ== capital-case@^1.0.4: version "1.0.4" From f9c398167c8ec33780f67f001e830493b2e33f4f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 19 May 2023 16:34:41 +0000 Subject: [PATCH 28/42] Version Packages --- .changeset/beige-toes-invent.md | 5 ----- packages/modular-scripts/CHANGELOG.md | 9 +++++++++ packages/modular-scripts/package.json | 2 +- 3 files changed, 10 insertions(+), 6 deletions(-) delete mode 100644 .changeset/beige-toes-invent.md diff --git a/.changeset/beige-toes-invent.md b/.changeset/beige-toes-invent.md deleted file mode 100644 index c840c8faf..000000000 --- a/.changeset/beige-toes-invent.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'modular-scripts': patch ---- - -Fix --bypass flag in test command diff --git a/packages/modular-scripts/CHANGELOG.md b/packages/modular-scripts/CHANGELOG.md index 110f356a4..4b62397e5 100644 --- a/packages/modular-scripts/CHANGELOG.md +++ b/packages/modular-scripts/CHANGELOG.md @@ -1,5 +1,14 @@ # modular-scripts +## 4.4.2 + +### Patch Changes + +- [#2393](https://github.com/jpmorganchase/modular/pull/2393) + [`e4f583f`](https://github.com/jpmorganchase/modular/commit/e4f583fbe1e30212d88d2b51b5ab0dd549a77e6d) + Thanks [@AlbertoBrusa](https://github.com/AlbertoBrusa)! - Fix --bypass flag + in test command + ## 4.4.1 ### Patch Changes diff --git a/packages/modular-scripts/package.json b/packages/modular-scripts/package.json index afd4bee19..95e2583de 100644 --- a/packages/modular-scripts/package.json +++ b/packages/modular-scripts/package.json @@ -1,6 +1,6 @@ { "name": "modular-scripts", - "version": "4.4.1", + "version": "4.4.2", "license": "Apache-2.0", "repository": { "type": "git", From e6a0d0f6af5d115ef50a9de47d95133d2a248de5 Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Wed, 31 May 2023 10:53:15 +0100 Subject: [PATCH 29/42] Add release notes & update command descriptions --- docs/releases/5.0.x.md | 47 +++++++++++++++++++++++++ packages/modular-scripts/src/program.ts | 18 +++++++--- 2 files changed, 60 insertions(+), 5 deletions(-) create mode 100644 docs/releases/5.0.x.md diff --git a/docs/releases/5.0.x.md b/docs/releases/5.0.x.md new file mode 100644 index 000000000..06179f710 --- /dev/null +++ b/docs/releases/5.0.x.md @@ -0,0 +1,47 @@ +--- +parent: Release Notes +title: 5.0.x +--- + +# Modular 5.0.0 + +## New Features + +- Node 20 Support. Modular is now tested against Node 20, and has added it to + the supported engines field +- Build output now targets ES2017 (Previously ES2016) +- Standardized Modular command behavior: + - [`modular lint`](../commands/lint.md) now fully supports selective behavior, + taking packages instead of regexes as the default arguments, bringing it in + line with other modular commands + - [`modular lint`](../commands/lint.md) now runs `lint` script on selected + non-modular packages by default, if specified in the package's + `package.json` + - [`modular typecheck`](../commands/typecheck.md) now runs `typecheck` script + selected non-modular packages, if specified in the package's `package.json` + - Modular's workspace resolver now respects a repo's `.gitignore`, overridden + by an optional `.modularignore`. Ignored workspaces will be skipped by + Modular commands and won't cause errors from Modular checks + +## Breaking Changes + +- Dropped Node 14 from supported engines in line with the end of + [LTS](https://github.com/nodejs/release#release-schedule). Modular is no + longer tested against Node 14 and can't guarantee compatibility +- Build output now targets ES2017 (Previously ES2016) +- Changed default behavior and options for [`modular lint`](../commands/lint.md) + and [`modular typecheck`](../commands/typecheck.md). All functionality has + been retained, but the command interface has been changed +- Modular's workspace resolver now respects `.gitignore`. This behavior, if + breaking, can be overridden by adding an empty `.modularignore` to the repos's + root. + +# Merged Changes + +TODO: fill + +# Patch Versions + +Patch versions of this release do not have a dedicated summary. For details of +patch releases, please visit +[the GitHub releases page](https://github.com/jpmorganchase/modular/releases). diff --git a/packages/modular-scripts/src/program.ts b/packages/modular-scripts/src/program.ts index d00d5b819..59a042a61 100755 --- a/packages/modular-scripts/src/program.ts +++ b/packages/modular-scripts/src/program.ts @@ -286,20 +286,26 @@ program const lintStagedFlag = '--staged'; program .command('lint [packages...]') - .option('--regex [regexes...]', 'Only lint selected packages') + .description( + 'lint provided packages. When run without any arguments, lints the whole repository', + ) + .option( + '--regex [regexes...]', + 'Only lint packages matching the provided regexes', + ) .option( '--ancestors', - 'Lint workspaces that depend on workspaces that have changed', + 'Additionally lint workspaces that depend on workspaces that have changed', false, ) .option( '--descendants', - 'Lint workspaces that directly or indirectly depend on the specified packages', + 'Additionally lint workspaces that directly or indirectly depend on the specified packages', false, ) .option( '--changed', - 'Lint workspaces that have changed compared to the branch specified in --compareBranch', + 'Additionally lint workspaces that have changed compared to the branch specified in --compareBranch', ) .option( '--compareBranch ', @@ -328,7 +334,9 @@ program program .command('typecheck [packages...]') - .description('Typechecks the entire project') + .description( + 'Typecheck provided packages. If run without any additional arguments, typechecks the entire project', + ) .option('--verbose', 'Enables verbose logging within modular.') .option( '--ancestors', From 4308141144a7b9b2d630dcc56e10240dbf0d7745 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 31 May 2023 11:05:42 +0000 Subject: [PATCH 30/42] Version Packages --- .changeset/eight-bats-double.md | 7 ----- .changeset/moody-mayflies-lick.md | 7 ----- .changeset/spotty-hornets-hug.md | 7 ----- .../create-modular-react-app/CHANGELOG.md | 9 +++++++ .../create-modular-react-app/package.json | 2 +- .../eslint-config-modular-app/CHANGELOG.md | 9 +++++++ .../eslint-config-modular-app/package.json | 2 +- packages/modular-scripts/CHANGELOG.md | 27 +++++++++++++++++++ packages/modular-scripts/package.json | 4 +-- packages/workspace-resolver/CHANGELOG.md | 10 +++++++ packages/workspace-resolver/package.json | 2 +- 11 files changed, 60 insertions(+), 26 deletions(-) delete mode 100644 .changeset/eight-bats-double.md delete mode 100644 .changeset/moody-mayflies-lick.md delete mode 100644 .changeset/spotty-hornets-hug.md diff --git a/.changeset/eight-bats-double.md b/.changeset/eight-bats-double.md deleted file mode 100644 index f1dbb2adf..000000000 --- a/.changeset/eight-bats-double.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'modular-scripts': major -'@modular-scripts/workspace-resolver': major ---- - -Modular's workspace resolver now ignores a workspace if covered by a -.modularignore or .gitignore (.modularignore overrides .gitignore) diff --git a/.changeset/moody-mayflies-lick.md b/.changeset/moody-mayflies-lick.md deleted file mode 100644 index e4d01817e..000000000 --- a/.changeset/moody-mayflies-lick.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'modular-scripts': major ---- - -Standardized lint and typecheck commands to bring them in line with other -modular selective behaviour. Now lints and typechecks non-modular packages by -default diff --git a/.changeset/spotty-hornets-hug.md b/.changeset/spotty-hornets-hug.md deleted file mode 100644 index 74a6249fe..000000000 --- a/.changeset/spotty-hornets-hug.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'create-modular-react-app': major -'eslint-config-modular-app': major -'modular-scripts': major ---- - -Dropped Node 14 support, added Node 20 support. Changed target to ES2017 diff --git a/packages/create-modular-react-app/CHANGELOG.md b/packages/create-modular-react-app/CHANGELOG.md index b863c200e..78f3af721 100644 --- a/packages/create-modular-react-app/CHANGELOG.md +++ b/packages/create-modular-react-app/CHANGELOG.md @@ -1,5 +1,14 @@ # create-modular-react-app +## 6.0.0 + +### Major Changes + +- [#2370](https://github.com/jpmorganchase/modular/pull/2370) + [`ef63eb3`](https://github.com/jpmorganchase/modular/commit/ef63eb3982e5984f72b7ea326a8c1da034c83253) + Thanks [@AlbertoBrusa](https://github.com/AlbertoBrusa)! - Dropped Node 14 + support, added Node 20 support. Changed target to ES2017 + ## 5.1.0 ### Minor Changes diff --git a/packages/create-modular-react-app/package.json b/packages/create-modular-react-app/package.json index 97eb0546d..1a5436dd0 100644 --- a/packages/create-modular-react-app/package.json +++ b/packages/create-modular-react-app/package.json @@ -1,6 +1,6 @@ { "name": "create-modular-react-app", - "version": "5.1.0", + "version": "6.0.0", "license": "Apache-2.0", "bin": { "create-modular-react-app": "build/cli.js" diff --git a/packages/eslint-config-modular-app/CHANGELOG.md b/packages/eslint-config-modular-app/CHANGELOG.md index 581c4c3ec..63282f57f 100644 --- a/packages/eslint-config-modular-app/CHANGELOG.md +++ b/packages/eslint-config-modular-app/CHANGELOG.md @@ -1,5 +1,14 @@ # eslint-config-modular-app +## 5.0.0 + +### Major Changes + +- [#2370](https://github.com/jpmorganchase/modular/pull/2370) + [`ef63eb3`](https://github.com/jpmorganchase/modular/commit/ef63eb3982e5984f72b7ea326a8c1da034c83253) + Thanks [@AlbertoBrusa](https://github.com/AlbertoBrusa)! - Dropped Node 14 + support, added Node 20 support. Changed target to ES2017 + ## 4.1.0 ### Minor Changes diff --git a/packages/eslint-config-modular-app/package.json b/packages/eslint-config-modular-app/package.json index 3af8f8cd1..bb8a12135 100644 --- a/packages/eslint-config-modular-app/package.json +++ b/packages/eslint-config-modular-app/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-modular-app", - "version": "4.1.0", + "version": "5.0.0", "license": "Apache-2.0", "main": "index.js", "engines": { diff --git a/packages/modular-scripts/CHANGELOG.md b/packages/modular-scripts/CHANGELOG.md index 4b62397e5..b5d701113 100644 --- a/packages/modular-scripts/CHANGELOG.md +++ b/packages/modular-scripts/CHANGELOG.md @@ -1,5 +1,32 @@ # modular-scripts +## 5.0.0 + +### Major Changes + +- [#2391](https://github.com/jpmorganchase/modular/pull/2391) + [`6209e17`](https://github.com/jpmorganchase/modular/commit/6209e17bbe90eaa0296c291ba26eafebf8a6591f) + Thanks [@AlbertoBrusa](https://github.com/AlbertoBrusa)! - Modular's workspace + resolver now ignores a workspace if covered by a .modularignore or .gitignore + (.modularignore overrides .gitignore) + +- [#2384](https://github.com/jpmorganchase/modular/pull/2384) + [`1e9c8cb`](https://github.com/jpmorganchase/modular/commit/1e9c8cb09c523169d196116c5335c04ec6fe9fac) + Thanks [@AlbertoBrusa](https://github.com/AlbertoBrusa)! - Standardized lint + and typecheck commands to bring them in line with other modular selective + behaviour. Now lints and typechecks non-modular packages by default + +- [#2370](https://github.com/jpmorganchase/modular/pull/2370) + [`ef63eb3`](https://github.com/jpmorganchase/modular/commit/ef63eb3982e5984f72b7ea326a8c1da034c83253) + Thanks [@AlbertoBrusa](https://github.com/AlbertoBrusa)! - Dropped Node 14 + support, added Node 20 support. Changed target to ES2017 + +### Patch Changes + +- Updated dependencies + [[`6209e17`](https://github.com/jpmorganchase/modular/commit/6209e17bbe90eaa0296c291ba26eafebf8a6591f)]: + - @modular-scripts/workspace-resolver@2.0.0 + ## 4.4.2 ### Patch Changes diff --git a/packages/modular-scripts/package.json b/packages/modular-scripts/package.json index 4ec8753b3..d53d87130 100644 --- a/packages/modular-scripts/package.json +++ b/packages/modular-scripts/package.json @@ -1,6 +1,6 @@ { "name": "modular-scripts", - "version": "4.4.2", + "version": "5.0.0", "license": "Apache-2.0", "repository": { "type": "git", @@ -28,7 +28,7 @@ }, "dependencies": { "@babel/code-frame": "7.18.6", - "@modular-scripts/workspace-resolver": "1.2.0", + "@modular-scripts/workspace-resolver": "2.0.0", "@npmcli/arborist": "^6.1.0", "@rollup/plugin-babel": "5.3.1", "@rollup/plugin-commonjs": "22.0.0", diff --git a/packages/workspace-resolver/CHANGELOG.md b/packages/workspace-resolver/CHANGELOG.md index 2d50b063a..bc90ae033 100644 --- a/packages/workspace-resolver/CHANGELOG.md +++ b/packages/workspace-resolver/CHANGELOG.md @@ -1,5 +1,15 @@ # @modular-scripts/workspace-resolver +## 2.0.0 + +### Major Changes + +- [#2391](https://github.com/jpmorganchase/modular/pull/2391) + [`6209e17`](https://github.com/jpmorganchase/modular/commit/6209e17bbe90eaa0296c291ba26eafebf8a6591f) + Thanks [@AlbertoBrusa](https://github.com/AlbertoBrusa)! - Modular's workspace + resolver now ignores a workspace if covered by a .modularignore or .gitignore + (.modularignore overrides .gitignore) + ## 1.2.0 ### Minor Changes diff --git a/packages/workspace-resolver/package.json b/packages/workspace-resolver/package.json index 0e69310a3..9337549c9 100644 --- a/packages/workspace-resolver/package.json +++ b/packages/workspace-resolver/package.json @@ -1,6 +1,6 @@ { "name": "@modular-scripts/workspace-resolver", - "version": "1.2.0", + "version": "2.0.0", "license": "Apache-2.0", "main": "src/index.ts", "dependencies": { From 4b2e74044b63dd064548ba535667bd084dddcf56 Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Wed, 31 May 2023 12:24:46 +0100 Subject: [PATCH 31/42] Add detailed changeset for 5.0 release --- docs/releases/5.0.x.md | 49 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/docs/releases/5.0.x.md b/docs/releases/5.0.x.md index 06179f710..16b2547e8 100644 --- a/docs/releases/5.0.x.md +++ b/docs/releases/5.0.x.md @@ -38,7 +38,54 @@ title: 5.0.x # Merged Changes -TODO: fill +## create-modular-react-app@6.0.0 + +### Major Changes + +- [#2370](https://github.com/jpmorganchase/modular/pull/2370) + [`ef63eb3`](https://github.com/jpmorganchase/modular/commit/ef63eb3982e5984f72b7ea326a8c1da034c83253) + Thanks [@AlbertoBrusa](https://github.com/AlbertoBrusa)! - Dropped Node 14 + support, added Node 20 support + +## eslint-config-modular-app@5.0.0 + +### Major Changes + +- [#2370](https://github.com/jpmorganchase/modular/pull/2370) + [`ef63eb3`](https://github.com/jpmorganchase/modular/commit/ef63eb3982e5984f72b7ea326a8c1da034c83253) + Thanks [@AlbertoBrusa](https://github.com/AlbertoBrusa)! - Dropped Node 14 + support, added Node 20 support + +## modular-scripts@5.0.0 + +### Major Changes + +- [#2391](https://github.com/jpmorganchase/modular/pull/2391) + [`6209e17`](https://github.com/jpmorganchase/modular/commit/6209e17bbe90eaa0296c291ba26eafebf8a6591f) + Thanks [@AlbertoBrusa](https://github.com/AlbertoBrusa)! - Modular's workspace + resolver now ignores a workspace if covered by a .modularignore or .gitignore + (.modularignore overrides .gitignore) + +- [#2384](https://github.com/jpmorganchase/modular/pull/2384) + [`1e9c8cb`](https://github.com/jpmorganchase/modular/commit/1e9c8cb09c523169d196116c5335c04ec6fe9fac) + Thanks [@AlbertoBrusa](https://github.com/AlbertoBrusa)! - Standardized lint + and typecheck commands to bring them in line with other modular selective + behavior. Now lints and typechecks non-modular packages by default + +- [#2370](https://github.com/jpmorganchase/modular/pull/2370) + [`ef63eb3`](https://github.com/jpmorganchase/modular/commit/ef63eb3982e5984f72b7ea326a8c1da034c83253) + Thanks [@AlbertoBrusa](https://github.com/AlbertoBrusa)! - Dropped Node 14 + support, added Node 20 support. Changed target to ES2017 + +## @modular-scripts/workspace-resolver@2.0.0 + +### Major Changes + +- [#2391](https://github.com/jpmorganchase/modular/pull/2391) + [`6209e17`](https://github.com/jpmorganchase/modular/commit/6209e17bbe90eaa0296c291ba26eafebf8a6591f) + Thanks [@AlbertoBrusa](https://github.com/AlbertoBrusa)! - Modular's workspace + resolver now ignores a workspace if covered by a .modularignore or .gitignore + (.modularignore overrides .gitignore) # Patch Versions From 9a2dcfeba9c33d0331b1b249081f1bad8d6c3caf Mon Sep 17 00:00:00 2001 From: Benjamin Pryke Date: Thu, 22 Jun 2023 15:49:35 +0100 Subject: [PATCH 32/42] Ensure modular-types package states its dependencies explicitly (#2421) * fix: ensure modular-types package states its dependencies explicitly * chore: add changeset --- .changeset/young-icons-notice.md | 5 +++++ packages/modular-types/package.json | 3 +++ 2 files changed, 8 insertions(+) create mode 100644 .changeset/young-icons-notice.md diff --git a/.changeset/young-icons-notice.md b/.changeset/young-icons-notice.md new file mode 100644 index 000000000..562526589 --- /dev/null +++ b/.changeset/young-icons-notice.md @@ -0,0 +1,5 @@ +--- +'@modular-scripts/modular-types': patch +--- + +Ensure modular-types states its dependencies explicitly diff --git a/packages/modular-types/package.json b/packages/modular-types/package.json index 818569e25..350d89867 100644 --- a/packages/modular-types/package.json +++ b/packages/modular-types/package.json @@ -5,5 +5,8 @@ "types": "src/types.ts", "publishConfig": { "access": "public" + }, + "dependencies": { + "@schemastore/package": "0.0.6" } } From ba459182140431a4880adc1d17b40c376d03efea Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 22 Jun 2023 17:35:12 +0100 Subject: [PATCH 33/42] Version Packages (#2422) Co-authored-by: github-actions[bot] --- .changeset/young-icons-notice.md | 5 ----- packages/modular-scripts/package.json | 2 +- packages/modular-types/CHANGELOG.md | 9 +++++++++ packages/modular-types/package.json | 2 +- packages/workspace-resolver/package.json | 2 +- 5 files changed, 12 insertions(+), 8 deletions(-) delete mode 100644 .changeset/young-icons-notice.md diff --git a/.changeset/young-icons-notice.md b/.changeset/young-icons-notice.md deleted file mode 100644 index 562526589..000000000 --- a/.changeset/young-icons-notice.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@modular-scripts/modular-types': patch ---- - -Ensure modular-types states its dependencies explicitly diff --git a/packages/modular-scripts/package.json b/packages/modular-scripts/package.json index d53d87130..58674cc44 100644 --- a/packages/modular-scripts/package.json +++ b/packages/modular-scripts/package.json @@ -158,7 +158,7 @@ "*.js" ], "devDependencies": { - "@modular-scripts/modular-types": "1.2.0", + "@modular-scripts/modular-types": "1.2.1", "@schemastore/package": "0.0.6", "@schemastore/tsconfig": "0.0.9", "@types/js-yaml": "^4.0.5", diff --git a/packages/modular-types/CHANGELOG.md b/packages/modular-types/CHANGELOG.md index 89cddbe5d..987ef7174 100644 --- a/packages/modular-types/CHANGELOG.md +++ b/packages/modular-types/CHANGELOG.md @@ -1,5 +1,14 @@ # @modular-scripts/modular-types +## 1.2.1 + +### Patch Changes + +- [#2421](https://github.com/jpmorganchase/modular/pull/2421) + [`9a2dcfe`](https://github.com/jpmorganchase/modular/commit/9a2dcfeba9c33d0331b1b249081f1bad8d6c3caf) + Thanks [@benpryke](https://github.com/benpryke)! - Ensure modular-types states + its dependencies explicitly + ## 1.2.0 ### Minor Changes diff --git a/packages/modular-types/package.json b/packages/modular-types/package.json index 350d89867..6a74da846 100644 --- a/packages/modular-types/package.json +++ b/packages/modular-types/package.json @@ -1,6 +1,6 @@ { "name": "@modular-scripts/modular-types", - "version": "1.2.0", + "version": "1.2.1", "license": "Apache-2.0", "types": "src/types.ts", "publishConfig": { diff --git a/packages/workspace-resolver/package.json b/packages/workspace-resolver/package.json index 9337549c9..51f542042 100644 --- a/packages/workspace-resolver/package.json +++ b/packages/workspace-resolver/package.json @@ -9,7 +9,7 @@ "semver": "7.3.7" }, "devDependencies": { - "@modular-scripts/modular-types": "1.2.0", + "@modular-scripts/modular-types": "1.2.1", "@types/fs-extra": "^9.0.13" }, "scripts": { From f1a1e0ae0d318d8de92a0fdff745ca19b5b3d9fc Mon Sep 17 00:00:00 2001 From: Benjamin Pryke Date: Thu, 29 Jun 2023 12:55:25 +0100 Subject: [PATCH 34/42] Add CORS plugin to modular serve (#2427) * feat: add CORS plugin to modular serve * chore: add changeset --- .changeset/polite-adults-roll.md | 6 ++++++ packages/modular-scripts/package.json | 2 ++ packages/modular-scripts/src/serve.ts | 2 ++ yarn.lock | 19 +++++++++++++++++-- 4 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 .changeset/polite-adults-roll.md diff --git a/.changeset/polite-adults-roll.md b/.changeset/polite-adults-roll.md new file mode 100644 index 000000000..a57a73831 --- /dev/null +++ b/.changeset/polite-adults-roll.md @@ -0,0 +1,6 @@ +--- +'modular-scripts': patch +--- + +Allow assets served locally via `modular serve` to be loaded cross-domain via +the cors plugin diff --git a/packages/modular-scripts/package.json b/packages/modular-scripts/package.json index 58674cc44..752ab3f75 100644 --- a/packages/modular-scripts/package.json +++ b/packages/modular-scripts/package.json @@ -57,6 +57,7 @@ "chalk": "4.1.2", "change-case": "4.1.2", "commander": "9.4.0", + "cors": "^2.8.5", "cosmiconfig": "^8.0.0", "cross-spawn": "7.0.3", "css-loader": "6.7.1", @@ -161,6 +162,7 @@ "@modular-scripts/modular-types": "1.2.1", "@schemastore/package": "0.0.6", "@schemastore/tsconfig": "0.0.9", + "@types/cors": "^2.8.13", "@types/js-yaml": "^4.0.5", "@types/loader-utils": "^2.0.3", "@types/validate-npm-package-name": "^4.0.0", diff --git a/packages/modular-scripts/src/serve.ts b/packages/modular-scripts/src/serve.ts index aa9afc80d..aeea31412 100644 --- a/packages/modular-scripts/src/serve.ts +++ b/packages/modular-scripts/src/serve.ts @@ -1,5 +1,6 @@ import express from 'express'; import * as fs from 'fs-extra'; +import cors from 'cors'; import determineTargetPaths from './build-scripts/common-scripts/determineTargetPaths'; import actionPreflightCheck from './utils/actionPreflightCheck'; import getWorkspaceLocation from './utils/getLocation'; @@ -17,6 +18,7 @@ async function serve(target: string, port = 3000): Promise { if (fs.existsSync(paths.appBuild)) { const app = express(); + app.use(cors()); app.use(express.static(paths.appBuild)); app.listen(port, () => { logger.log(`Serving ${target} on ${port}`); diff --git a/yarn.lock b/yarn.lock index deea1c01b..556ac7ea8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2833,6 +2833,13 @@ dependencies: "@types/node" "*" +"@types/cors@^2.8.13": + version "2.8.13" + resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.13.tgz#b8ade22ba455a1b8cb3b5d3f35910fd204f84f94" + integrity sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA== + dependencies: + "@types/node" "*" + "@types/cross-spawn@^6.0.2": version "6.0.2" resolved "https://registry.npmjs.org/@types/cross-spawn/-/cross-spawn-6.0.2.tgz" @@ -4961,6 +4968,14 @@ core-util-is@~1.0.0: resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz" integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== +cors@^2.8.5: + version "2.8.5" + resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" + integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== + dependencies: + object-assign "^4" + vary "^1" + cosmiconfig@^7.0.0, cosmiconfig@^7.0.1: version "7.1.0" resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz" @@ -9180,7 +9195,7 @@ nwsapi@^2.2.2: resolved "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.2.tgz" integrity sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw== -object-assign@^4.1.0, object-assign@^4.1.1: +object-assign@^4, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== @@ -12330,7 +12345,7 @@ validate-npm-package-name@^5.0.0: dependencies: builtins "^5.0.0" -vary@~1.1.2: +vary@^1, vary@~1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz" integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== From bd3e79c0e8fce8c9986097588c3f8aaec30e0d66 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 29 Jun 2023 13:05:59 +0100 Subject: [PATCH 35/42] Version Packages (#2428) Co-authored-by: github-actions[bot] --- .changeset/polite-adults-roll.md | 6 ------ packages/modular-scripts/CHANGELOG.md | 9 +++++++++ packages/modular-scripts/package.json | 2 +- 3 files changed, 10 insertions(+), 7 deletions(-) delete mode 100644 .changeset/polite-adults-roll.md diff --git a/.changeset/polite-adults-roll.md b/.changeset/polite-adults-roll.md deleted file mode 100644 index a57a73831..000000000 --- a/.changeset/polite-adults-roll.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'modular-scripts': patch ---- - -Allow assets served locally via `modular serve` to be loaded cross-domain via -the cors plugin diff --git a/packages/modular-scripts/CHANGELOG.md b/packages/modular-scripts/CHANGELOG.md index b5d701113..780404810 100644 --- a/packages/modular-scripts/CHANGELOG.md +++ b/packages/modular-scripts/CHANGELOG.md @@ -1,5 +1,14 @@ # modular-scripts +## 5.0.1 + +### Patch Changes + +- [#2427](https://github.com/jpmorganchase/modular/pull/2427) + [`f1a1e0a`](https://github.com/jpmorganchase/modular/commit/f1a1e0ae0d318d8de92a0fdff745ca19b5b3d9fc) + Thanks [@benpryke](https://github.com/benpryke)! - Allow assets served locally + via `modular serve` to be loaded cross-domain via the cors plugin + ## 5.0.0 ### Major Changes diff --git a/packages/modular-scripts/package.json b/packages/modular-scripts/package.json index 752ab3f75..a8042af9c 100644 --- a/packages/modular-scripts/package.json +++ b/packages/modular-scripts/package.json @@ -1,6 +1,6 @@ { "name": "modular-scripts", - "version": "5.0.0", + "version": "5.0.1", "license": "Apache-2.0", "repository": { "type": "git", From 757217d6ed5362c077b3b524e4374fd68ce14ef6 Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Tue, 4 Jul 2023 10:29:33 +0100 Subject: [PATCH 36/42] Make swc jest configurable without a flag --- .changeset/polite-chefs-boil.md | 6 ++++++ docs/configuration.md | 15 +++++++++++++-- package.json | 5 +++-- packages/modular-scripts/src/test/index.ts | 11 ++++++++++- packages/modular-scripts/src/utils/config.ts | 8 ++++++++ 5 files changed, 40 insertions(+), 5 deletions(-) create mode 100644 .changeset/polite-chefs-boil.md diff --git a/.changeset/polite-chefs-boil.md b/.changeset/polite-chefs-boil.md new file mode 100644 index 000000000..08e7d3a5d --- /dev/null +++ b/.changeset/polite-chefs-boil.md @@ -0,0 +1,6 @@ +--- +'modular-scripts': minor +--- + +Use of swc Jest for testing can now be configured through modular configuration +file diff --git a/docs/configuration.md b/docs/configuration.md index a2ef48f54..4d695ed92 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -40,6 +40,7 @@ module.exports = { externalAllowList: ['**'], publicUrl: '', generateSourceMap: true, + swcJest: false, }; ``` @@ -69,8 +70,8 @@ esm.sh. 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. +[customize bundle strategy](./esm-views/customize-bundle-strategy.md). Defaults +to none. Only applies to ESM Views. ### externalAllowList @@ -103,6 +104,16 @@ 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. +### swcJest + +**Type**: `boolean` + +**Default**: `false` + +Use Rust based SWC Jest runner instead of ts-jest & babel for performance +improvements. Can be breaking for certain tests and configurations. Cannot be +configured per package, must be configured at root. + ## `package.json#modular` _NOTE: This property is created automatically and is described here for diff --git a/package.json b/package.json index be7f2cd35..7bb81d064 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "lint:fix": "yarn lint --fix", "create-modular-react-app": "ts-node packages/create-modular-react-app/src/cli.ts", "modular": "ts-node packages/modular-scripts/src/cli.ts", - "test": "cross-env NODE_OPTIONS=--max_old_space_size=5120 yarn modular test --swc --runInBand --env=node", + "test": "cross-env NODE_OPTIONS=--max_old_space_size=5120 yarn modular test --runInBand --env=node", "build": "yarn workspace @modular-scripts/workspace-resolver build && yarn workspace create-modular-react-app build && yarn workspace modular-scripts build && yarn modular build @modular-scripts/remote-view && yarn prepare:remote-view", "prepare": "is-ci || husky install", "prepare:remote-view:copy": "cp -R dist/modular-scripts-remote-view packages/remote-view/dist", @@ -106,7 +106,8 @@ "coverageProvider": "v8" }, "modular": { - "type": "root" + "type": "root", + "swcJest": true }, "lint-staged": { "*.{js,ts,tsx,mjs,md,yml,json}": "yarn prettier --write -l", diff --git a/packages/modular-scripts/src/test/index.ts b/packages/modular-scripts/src/test/index.ts index 0ec907cfb..fdd84559d 100644 --- a/packages/modular-scripts/src/test/index.ts +++ b/packages/modular-scripts/src/test/index.ts @@ -13,6 +13,7 @@ import { computeRegexesFromPackageNames, partitionPackages, } from '../utils/unobtrusiveModular'; +import { getConfig } from '../utils/config'; export interface TestOptions { bypass: boolean; @@ -91,10 +92,18 @@ async function test(options: TestOptions, packages?: string[]): Promise { // pass in jest configuration const { createJestConfig } = await import('./config'); + const configuredSwc = swc ? swc : getConfig('swcJest', getModularRoot()); + console.error( + 'CONFIGURED SWC: ', + JSON.stringify(getConfig('swcJest', getModularRoot())), + ); + + if (configuredSwc) console.error('USING SWC'); + cleanArgv.push( '--config', generateJestConfig( - createJestConfig({ reporters, testResultsProcessor }, swc), + createJestConfig({ reporters, testResultsProcessor }, configuredSwc), ), ); diff --git a/packages/modular-scripts/src/utils/config.ts b/packages/modular-scripts/src/utils/config.ts index 388c1f5c0..9eed4e877 100644 --- a/packages/modular-scripts/src/utils/config.ts +++ b/packages/modular-scripts/src/utils/config.ts @@ -28,6 +28,7 @@ interface Config { externalAllowList: string[]; publicUrl: string; generateSourceMap: boolean; + swcJest: boolean; } type ConfigDefs = { @@ -77,6 +78,13 @@ const defs: ConfigDefs = { ? process.env.GENERATE_SOURCEMAP === 'true' : undefined, }, + swcJest: { + default: false, + override: + process.env.SWC_JEST === 'true' || process.env.SWC_JEST === 'false' + ? process.env.SWC_JEST === 'true' + : undefined, + }, }; const explorer = cosmiconfigSync('modular', { searchPlaces }); From aaf1bea7dabab8840a7d6e61bede8e0c2d9f377b Mon Sep 17 00:00:00 2001 From: Alberto Brusa Date: Tue, 4 Jul 2023 10:38:52 +0100 Subject: [PATCH 37/42] remove debug logs --- packages/modular-scripts/src/test/index.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/packages/modular-scripts/src/test/index.ts b/packages/modular-scripts/src/test/index.ts index fdd84559d..a1d607a1a 100644 --- a/packages/modular-scripts/src/test/index.ts +++ b/packages/modular-scripts/src/test/index.ts @@ -93,12 +93,6 @@ async function test(options: TestOptions, packages?: string[]): Promise { const { createJestConfig } = await import('./config'); const configuredSwc = swc ? swc : getConfig('swcJest', getModularRoot()); - console.error( - 'CONFIGURED SWC: ', - JSON.stringify(getConfig('swcJest', getModularRoot())), - ); - - if (configuredSwc) console.error('USING SWC'); cleanArgv.push( '--config', From 666031da63a99d0329e66525148241c84275119a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 7 Jul 2023 11:24:09 +0100 Subject: [PATCH 38/42] Version Packages (#2434) Co-authored-by: github-actions[bot] --- .changeset/polite-chefs-boil.md | 6 ------ packages/modular-scripts/CHANGELOG.md | 9 +++++++++ packages/modular-scripts/package.json | 2 +- 3 files changed, 10 insertions(+), 7 deletions(-) delete mode 100644 .changeset/polite-chefs-boil.md diff --git a/.changeset/polite-chefs-boil.md b/.changeset/polite-chefs-boil.md deleted file mode 100644 index 08e7d3a5d..000000000 --- a/.changeset/polite-chefs-boil.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'modular-scripts': minor ---- - -Use of swc Jest for testing can now be configured through modular configuration -file diff --git a/packages/modular-scripts/CHANGELOG.md b/packages/modular-scripts/CHANGELOG.md index 780404810..9274813f1 100644 --- a/packages/modular-scripts/CHANGELOG.md +++ b/packages/modular-scripts/CHANGELOG.md @@ -1,5 +1,14 @@ # modular-scripts +## 5.1.0 + +### Minor Changes + +- [#2433](https://github.com/jpmorganchase/modular/pull/2433) + [`757217d`](https://github.com/jpmorganchase/modular/commit/757217d6ed5362c077b3b524e4374fd68ce14ef6) + Thanks [@AlbertoBrusa](https://github.com/AlbertoBrusa)! - Use of swc Jest for + testing can now be configured through modular configuration file + ## 5.0.1 ### Patch Changes diff --git a/packages/modular-scripts/package.json b/packages/modular-scripts/package.json index a8042af9c..853cacd47 100644 --- a/packages/modular-scripts/package.json +++ b/packages/modular-scripts/package.json @@ -1,6 +1,6 @@ { "name": "modular-scripts", - "version": "5.0.1", + "version": "5.1.0", "license": "Apache-2.0", "repository": { "type": "git", From 84a4c827a1ac280d650816c6e641a7998eba6a4f Mon Sep 17 00:00:00 2001 From: Sam Brown Date: Fri, 21 Jul 2023 13:22:13 +0100 Subject: [PATCH 39/42] RemoteView: support a wider range of potential asset URLs (#2439) --- .changeset/nasty-pans-cough.md | 5 + docs/components/remote-view.md | 82 ++++++ ...efault-remote-view-error-fallback.test.tsx | 2 +- .../src/__tests__/get-urls.test.tsx | 238 ++++++++++++++++++ .../src/__tests__/remote-view.test.tsx | 4 +- .../default-remote-view-error-fallback.tsx | 2 +- .../components/remote-view-error-boundary.tsx | 2 +- .../src/components/remote-view-provider.tsx | 32 ++- .../remote-view/src/hooks/useRemoteView.tsx | 2 +- packages/remote-view/src/index.ts | 2 +- packages/remote-view/src/types.ts | 2 +- ...callyImport.tsx => dynamically-import.tsx} | 6 +- packages/remote-view/src/utils/get-urls.ts | 78 ++++++ ...emoteViewError.ts => remote-view-error.ts} | 0 14 files changed, 439 insertions(+), 18 deletions(-) create mode 100644 .changeset/nasty-pans-cough.md create mode 100644 packages/remote-view/src/__tests__/get-urls.test.tsx rename packages/remote-view/src/utils/{dynamicallyImport.tsx => dynamically-import.tsx} (55%) create mode 100644 packages/remote-view/src/utils/get-urls.ts rename packages/remote-view/src/utils/{remoteViewError.ts => remote-view-error.ts} (100%) diff --git a/.changeset/nasty-pans-cough.md b/.changeset/nasty-pans-cough.md new file mode 100644 index 000000000..04939acd0 --- /dev/null +++ b/.changeset/nasty-pans-cough.md @@ -0,0 +1,5 @@ +--- +'@modular-scripts/remote-view': minor +--- + +Add support for a wider range of asset URLs diff --git a/docs/components/remote-view.md b/docs/components/remote-view.md index 6b62dfe94..2d6ef8406 100644 --- a/docs/components/remote-view.md +++ b/docs/components/remote-view.md @@ -105,6 +105,88 @@ whereas Modular [Apps](https://modular.js.org/package-types/app/) are loaded into an iframe. For more information on Modular types, check out the [Package Types breakdown](https://modular.js.org/package-types/). +## Providing ESM View URLs + +`` expects an array of URLs which are expected to point at +CDN-hosted ESM Views. + +URLs should either be absolute URLs or relative paths from `/` and point at the +root of your CDN-hosted ESM Views. + +### Supported ESM View URLs + +```javascript +// Absolute URLs, with optional trailing / +'https://localhost:3030/my-card-view', +'https://localhost:3030/my-card-view/', +// HTTP also allowed +'http://localhost:3030/my-card-view', +'http://localhost:3030/my-card-view/', +// Absolute URLs with deep paths +'https://cdn.example.com/subpath/foo/my-card-view', +'https://cdn.example.com/subpath/foo/my-card-view/', +// Root-relative URLs +'/my-card-view', +'/my-card-view/', +// Root-relative URLs with deep paths +'/subpath/foo/my-card-view', +'/subpath/foo/my-card-view/', +``` + +### Unsupported ESM View URLs + +```javascript +// Plain / +'/', +// Relative path from current location +'./relpath/my-card-view', +'./relpath/my-card-view/', +// No protocol, but no leading / +'foo/my-card-view', +'foo/my-card-view/', +// Unsupported protocols +'file:///Users/foo/subpath/my-card-view', +'file:///Users/foo/subpath/my-card-view/', +``` + +The expected method of composing an application that uses ESM Views with +RemoteView is that each ESM View and it's static assets (namely `module` and +`style` paths in `package.json`) all exist under the relevant ESM View's root +URL. For example, let's say you have a Card ESM View: + +- Root path of the ESM View: `https://cdn.example.com/my-card-view/` +- Path to the Card's `package.json`: + `https://cdn.example.com/my-card-view/package.json` +- Path to the Card's ES module: + `https://cdn.example.com/my-card-view/static/card.js` +- Path to the Card's CSS: `https://cdn.example.com/my-card-view/static/card.css` + +Where the Card's `package.json` contains: + +```json +{ + "module": "./static/card.js", + "style": "./static/card.css" +} +``` + +However, it is also possible to supply absolute URLs for `module` and `style`. +This might be useful if you are consuming view assets from a different origin +than the host application. + +Supported `module` and `style` values: + +- `./` prefix: `./static/js/foo.js`, `./static/css/foo.css` +- `/` prefix: `/static/js/foo.js`, `/static/css/foo.css` +- unprefixed: `static/js/foo.js`, `static/css/foo.css` +- absolute: `https://cdn.example/js/foo.js`, + `https://cdn.example.com/css/foo.css` + +A value such as `/../static/js/foo.js` is **not supported**. + +By default, Modular ESM Views automatically generate RemoteView-compatible +values. + ## Fall back to iframes It is also possible to load [ESM Views](https://modular.js.org/esm-views) (in diff --git a/packages/remote-view/src/__tests__/default-remote-view-error-fallback.test.tsx b/packages/remote-view/src/__tests__/default-remote-view-error-fallback.test.tsx index 1b52ff308..fcc82aad9 100644 --- a/packages/remote-view/src/__tests__/default-remote-view-error-fallback.test.tsx +++ b/packages/remote-view/src/__tests__/default-remote-view-error-fallback.test.tsx @@ -5,7 +5,7 @@ import React from 'react'; import { render, screen, waitFor } from '@testing-library/react'; import { DefaultRemoteViewErrorFallback } from '../components/default-remote-view-error-fallback'; -import { RemoteViewError } from '../utils/remoteViewError'; +import { RemoteViewError } from '../utils/remote-view-error'; const mockRemoteViewError = new RemoteViewError( 'Some example error', diff --git a/packages/remote-view/src/__tests__/get-urls.test.tsx b/packages/remote-view/src/__tests__/get-urls.test.tsx new file mode 100644 index 000000000..1b0a01bf2 --- /dev/null +++ b/packages/remote-view/src/__tests__/get-urls.test.tsx @@ -0,0 +1,238 @@ +import { + esmViewUrlIsValid, + getRemoteAssetUrl, + getRemotePackageJsonUrl, +} from '../utils/get-urls'; + +const VALID_INPUTS = [ + // Absolute URLs, with optional trailing / + 'https://localhost:3030/my-card-view', + 'https://localhost:3030/my-card-view/', + // HTTP also allowed + 'http://localhost:3030/my-card-view', + 'http://localhost:3030/my-card-view/', + // Absolute URLs with deep paths + 'https://cdn.example.com/subpath/foo/my-card-view', + 'https://cdn.example.com/subpath/foo/my-card-view/', + // Root-relative URLs + '/my-card-view', + '/my-card-view/', + // Root-relative URLs with deep paths + '/subpath/foo/my-card-view', + '/subpath/foo/my-card-view/', +]; + +const INVALID_INPUTS = [ + // Plain / + '/', + // Relative path from current location + './relpath/my-card-view', + './relpath/my-card-view/', + // No protocol, but no leading / + 'foo/my-card-view', + 'foo/my-card-view/', + // Unsupported protocol + 'file:///Users/foo/subpath/my-card-view', + 'file:///Users/foo/subpath/my-card-view/', +]; + +describe('getUrls', () => { + describe('should validate URLs supplied from user input', () => { + describe('URLs considered valid', () => { + VALID_INPUTS.forEach((remoteViewUrl) => { + it(`allows ${remoteViewUrl}`, () => { + expect(esmViewUrlIsValid(remoteViewUrl)).toBe(true); + }); + }); + }); + + describe('URLs considered invalid', () => { + INVALID_INPUTS.forEach((remoteViewUrl) => { + it(`prohibits ${remoteViewUrl}`, () => { + expect(esmViewUrlIsValid(remoteViewUrl)).toBe(false); + }); + }); + }); + }); + + describe('should correctly point to package.json', () => { + const EXPECTED_OUTCOMES = [ + 'https://localhost:3030/my-card-view/package.json', + 'https://localhost:3030/my-card-view/package.json', + 'http://localhost:3030/my-card-view/package.json', + 'http://localhost:3030/my-card-view/package.json', + 'https://cdn.example.com/subpath/foo/my-card-view/package.json', + 'https://cdn.example.com/subpath/foo/my-card-view/package.json', + '/my-card-view/package.json', + '/my-card-view/package.json', + '/subpath/foo/my-card-view/package.json', + '/subpath/foo/my-card-view/package.json', + ]; + + VALID_INPUTS.forEach((validBaseUrl, index) => { + it(`given the valid ESM View URL of "${validBaseUrl}", correctly points to package.json`, () => { + expect(getRemotePackageJsonUrl(validBaseUrl)).toBe( + EXPECTED_OUTCOMES[index], + ); + }); + }); + }); + + const SUPPORTED_ASSET_PATHS = { + PRECEDING_SLASH: '/static/foo/bar.js', + PRECEDING_DOT_SLASH: './static/foo/bar.js', + ABSOLUTE_URL: 'https://cdn.example.com/foo/bar/module.js', + NO_PREFIX: 'foo/bar/module.js', + }; + + const EXPECTED_ASSET_OUTPUTS: Record> = { + 'https://localhost:3030/my-card-view': { + [SUPPORTED_ASSET_PATHS.PRECEDING_SLASH]: + 'https://localhost:3030/my-card-view/static/foo/bar.js', + [SUPPORTED_ASSET_PATHS.PRECEDING_DOT_SLASH]: + 'https://localhost:3030/my-card-view/static/foo/bar.js', + [SUPPORTED_ASSET_PATHS.ABSOLUTE_URL]: + 'https://cdn.example.com/foo/bar/module.js', + [SUPPORTED_ASSET_PATHS.NO_PREFIX]: + 'https://localhost:3030/my-card-view/foo/bar/module.js', + }, + 'https://localhost:3030/my-card-view/': { + [SUPPORTED_ASSET_PATHS.PRECEDING_SLASH]: + 'https://localhost:3030/my-card-view/static/foo/bar.js', + [SUPPORTED_ASSET_PATHS.PRECEDING_DOT_SLASH]: + 'https://localhost:3030/my-card-view/static/foo/bar.js', + [SUPPORTED_ASSET_PATHS.ABSOLUTE_URL]: + 'https://cdn.example.com/foo/bar/module.js', + [SUPPORTED_ASSET_PATHS.NO_PREFIX]: + 'https://localhost:3030/my-card-view/foo/bar/module.js', + }, + 'http://localhost:3030/my-card-view': { + [SUPPORTED_ASSET_PATHS.PRECEDING_SLASH]: + 'http://localhost:3030/my-card-view/static/foo/bar.js', + [SUPPORTED_ASSET_PATHS.PRECEDING_DOT_SLASH]: + 'http://localhost:3030/my-card-view/static/foo/bar.js', + [SUPPORTED_ASSET_PATHS.ABSOLUTE_URL]: + 'https://cdn.example.com/foo/bar/module.js', + [SUPPORTED_ASSET_PATHS.NO_PREFIX]: + 'http://localhost:3030/my-card-view/foo/bar/module.js', + }, + 'http://localhost:3030/my-card-view/': { + [SUPPORTED_ASSET_PATHS.PRECEDING_SLASH]: + 'http://localhost:3030/my-card-view/static/foo/bar.js', + [SUPPORTED_ASSET_PATHS.PRECEDING_DOT_SLASH]: + 'http://localhost:3030/my-card-view/static/foo/bar.js', + [SUPPORTED_ASSET_PATHS.ABSOLUTE_URL]: + 'https://cdn.example.com/foo/bar/module.js', + [SUPPORTED_ASSET_PATHS.NO_PREFIX]: + 'http://localhost:3030/my-card-view/foo/bar/module.js', + }, + 'https://cdn.example.com/subpath/foo/my-card-view': { + [SUPPORTED_ASSET_PATHS.PRECEDING_SLASH]: + 'https://cdn.example.com/subpath/foo/my-card-view/static/foo/bar.js', + [SUPPORTED_ASSET_PATHS.PRECEDING_DOT_SLASH]: + 'https://cdn.example.com/subpath/foo/my-card-view/static/foo/bar.js', + [SUPPORTED_ASSET_PATHS.ABSOLUTE_URL]: + 'https://cdn.example.com/foo/bar/module.js', + [SUPPORTED_ASSET_PATHS.NO_PREFIX]: + 'https://cdn.example.com/subpath/foo/my-card-view/foo/bar/module.js', + }, + 'https://cdn.example.com/subpath/foo/my-card-view/': { + [SUPPORTED_ASSET_PATHS.PRECEDING_SLASH]: + 'https://cdn.example.com/subpath/foo/my-card-view/static/foo/bar.js', + [SUPPORTED_ASSET_PATHS.PRECEDING_DOT_SLASH]: + 'https://cdn.example.com/subpath/foo/my-card-view/static/foo/bar.js', + [SUPPORTED_ASSET_PATHS.ABSOLUTE_URL]: + 'https://cdn.example.com/foo/bar/module.js', + [SUPPORTED_ASSET_PATHS.NO_PREFIX]: + 'https://cdn.example.com/subpath/foo/my-card-view/foo/bar/module.js', + }, + '/my-card-view': { + [SUPPORTED_ASSET_PATHS.PRECEDING_SLASH]: + '/my-card-view/static/foo/bar.js', + [SUPPORTED_ASSET_PATHS.PRECEDING_DOT_SLASH]: + '/my-card-view/static/foo/bar.js', + [SUPPORTED_ASSET_PATHS.ABSOLUTE_URL]: + 'https://cdn.example.com/foo/bar/module.js', + [SUPPORTED_ASSET_PATHS.NO_PREFIX]: '/my-card-view/foo/bar/module.js', + }, + '/my-card-view/': { + [SUPPORTED_ASSET_PATHS.PRECEDING_SLASH]: + '/my-card-view/static/foo/bar.js', + [SUPPORTED_ASSET_PATHS.PRECEDING_DOT_SLASH]: + '/my-card-view/static/foo/bar.js', + [SUPPORTED_ASSET_PATHS.ABSOLUTE_URL]: + 'https://cdn.example.com/foo/bar/module.js', + [SUPPORTED_ASSET_PATHS.NO_PREFIX]: '/my-card-view/foo/bar/module.js', + }, + '/subpath/foo/my-card-view': { + [SUPPORTED_ASSET_PATHS.PRECEDING_SLASH]: + '/subpath/foo/my-card-view/static/foo/bar.js', + [SUPPORTED_ASSET_PATHS.PRECEDING_DOT_SLASH]: + '/subpath/foo/my-card-view/static/foo/bar.js', + [SUPPORTED_ASSET_PATHS.ABSOLUTE_URL]: + 'https://cdn.example.com/foo/bar/module.js', + [SUPPORTED_ASSET_PATHS.NO_PREFIX]: + '/subpath/foo/my-card-view/foo/bar/module.js', + }, + '/subpath/foo/my-card-view/': { + [SUPPORTED_ASSET_PATHS.PRECEDING_SLASH]: + '/subpath/foo/my-card-view/static/foo/bar.js', + [SUPPORTED_ASSET_PATHS.PRECEDING_DOT_SLASH]: + '/subpath/foo/my-card-view/static/foo/bar.js', + [SUPPORTED_ASSET_PATHS.ABSOLUTE_URL]: + 'https://cdn.example.com/foo/bar/module.js', + [SUPPORTED_ASSET_PATHS.NO_PREFIX]: + '/subpath/foo/my-card-view/foo/bar/module.js', + }, + }; + + describe('should build static asset URLs corectly', () => { + VALID_INPUTS.forEach((validBaseUrl) => { + describe(`given an ESM View URL of ${validBaseUrl}`, () => { + const expectedA = + EXPECTED_ASSET_OUTPUTS[validBaseUrl][ + SUPPORTED_ASSET_PATHS.PRECEDING_SLASH + ]; + it(`given the assetPath of "${SUPPORTED_ASSET_PATHS.PRECEDING_SLASH}", produces "${expectedA}"`, () => { + expect( + getRemoteAssetUrl( + validBaseUrl, + SUPPORTED_ASSET_PATHS.PRECEDING_SLASH, + ), + ).toBe(expectedA); + }); + + const expectedB = + EXPECTED_ASSET_OUTPUTS[validBaseUrl][ + SUPPORTED_ASSET_PATHS.PRECEDING_DOT_SLASH + ]; + it(`given the assetPath of "${SUPPORTED_ASSET_PATHS.PRECEDING_DOT_SLASH}", produces "${expectedB}"`, () => { + expect( + getRemoteAssetUrl( + validBaseUrl, + SUPPORTED_ASSET_PATHS.PRECEDING_DOT_SLASH, + ), + ).toBe(expectedB); + }); + + const expectedC = + EXPECTED_ASSET_OUTPUTS[validBaseUrl][ + SUPPORTED_ASSET_PATHS.ABSOLUTE_URL + ]; + it(`given the assetPath of "${SUPPORTED_ASSET_PATHS.ABSOLUTE_URL}", produces "${expectedC}"`, () => { + expect( + getRemoteAssetUrl(validBaseUrl, SUPPORTED_ASSET_PATHS.ABSOLUTE_URL), + ).toBe(expectedC); + }); + + const expectedD = + EXPECTED_ASSET_OUTPUTS[validBaseUrl][SUPPORTED_ASSET_PATHS.NO_PREFIX]; + it(`given the assetPath of "${SUPPORTED_ASSET_PATHS.NO_PREFIX}", produces "${expectedD}"`, () => { + expect( + getRemoteAssetUrl(validBaseUrl, SUPPORTED_ASSET_PATHS.NO_PREFIX), + ).toBe(expectedD); + }); + }); + }); + }); +}); diff --git a/packages/remote-view/src/__tests__/remote-view.test.tsx b/packages/remote-view/src/__tests__/remote-view.test.tsx index 984062686..9d43fbaed 100644 --- a/packages/remote-view/src/__tests__/remote-view.test.tsx +++ b/packages/remote-view/src/__tests__/remote-view.test.tsx @@ -14,7 +14,7 @@ import { RemoteViewErrorBoundary, RemoteViewProvider, } from '../components'; -import { RemoteViewError } from '../utils/remoteViewError'; +import { RemoteViewError } from '../utils/remote-view-error'; function FakeComponentA() { return
Faked dynamically imported module A
; @@ -59,7 +59,7 @@ const badManifestB = { }, }; -jest.mock('../utils/dynamicallyImport', () => { +jest.mock('../utils/dynamically-import', () => { let n = 0; return { dynamicallyImport: async () => { diff --git a/packages/remote-view/src/components/default-remote-view-error-fallback.tsx b/packages/remote-view/src/components/default-remote-view-error-fallback.tsx index 384e41fd9..a08b770f5 100644 --- a/packages/remote-view/src/components/default-remote-view-error-fallback.tsx +++ b/packages/remote-view/src/components/default-remote-view-error-fallback.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { RemoteViewError } from '../utils/remoteViewError'; +import { RemoteViewError } from '../utils/remote-view-error'; export function DefaultRemoteViewErrorFallback({ error, diff --git a/packages/remote-view/src/components/remote-view-error-boundary.tsx b/packages/remote-view/src/components/remote-view-error-boundary.tsx index 21f22bcc3..8570ac744 100644 --- a/packages/remote-view/src/components/remote-view-error-boundary.tsx +++ b/packages/remote-view/src/components/remote-view-error-boundary.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { RemoteViewError } from '../utils/remoteViewError'; +import { RemoteViewError } from '../utils/remote-view-error'; import { DefaultRemoteViewErrorFallback } from './default-remote-view-error-fallback'; import { DefaultUnknownErrorFallback } from './default-unknown-error-fallback'; diff --git a/packages/remote-view/src/components/remote-view-provider.tsx b/packages/remote-view/src/components/remote-view-provider.tsx index 1f1993e41..613eb50df 100644 --- a/packages/remote-view/src/components/remote-view-provider.tsx +++ b/packages/remote-view/src/components/remote-view-provider.tsx @@ -1,8 +1,13 @@ import React, { useEffect, useMemo, useState } from 'react'; import { ErrorContext, ViewsContext } from '../context'; -import { RemoteViewError } from '../utils/remoteViewError'; -import { dynamicallyImport } from '../utils/dynamicallyImport'; +import { RemoteViewError } from '../utils/remote-view-error'; +import { dynamicallyImport } from '../utils/dynamically-import'; import { loading } from '../utils/symbol'; +import { + esmViewUrlIsValid, + getRemoteAssetUrl, + getRemotePackageJsonUrl, +} from '../utils/get-urls'; import type { ManifestCheck, RemoteViewErrorsContext, @@ -22,7 +27,8 @@ async function loadRemoteView( ): Promise { let manifest: MicrofrontendManifest | undefined; try { - const response = await fetch(`${baseUrl}/package.json`); + const packageJsonUrl = getRemotePackageJsonUrl(baseUrl); + const response = await fetch(packageJsonUrl); manifest = (await response.json()) as MicrofrontendManifest; } catch (e) { throw new RemoteViewError( @@ -50,7 +56,8 @@ async function loadRemoteView( (loadWithIframeFallback && loadWithIframeFallback(manifest)) ) { const iframeTitle = manifest.name; - return () =>