-
Notifications
You must be signed in to change notification settings - Fork 21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[UIE-94] Multi-package MVP #3992
Conversation
f3967fc
to
a3f551b
Compare
- run: yarn run build | ||
- run: yarn eslint --max-warnings=0 . | ||
- run: yarn test --coverage --maxWorkers=2 | ||
- run: yarn workspaces foreach --exclude terra-integration-tests run test --coverage --maxWorkers=2 --passWithNoTests | ||
- run: yarn check-types | ||
- run: DISABLE_ESLINT_PLUGIN=true yarn build # already linted above |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ESLint and tests require the packages to be built first so that imports from the packages can be resolved.
@@ -13,4 +13,4 @@ node_modules | |||
.vscode | |||
coverage | |||
vite.config.js | |||
jest/* | |||
packages/*/lib |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ignore build outputs.
@@ -5,9 +5,12 @@ node_modules | |||
|
|||
# testing | |||
/coverage | |||
packages/*/coverage |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A coverage report is generated for each package.
|
||
# production | ||
/build | ||
packages/*/lib | ||
tsconfig.tsbuildinfo |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ignore build outputs.
- path: .yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs | ||
spec: "@yarnpkg/plugin-workspace-tools" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This plugin provides yarn workspaces foreach ...
.
https://yarnpkg.com/cli/workspaces/foreach
@@ -1,7 +1,9 @@ | |||
FROM node:18.10 | |||
|
|||
COPY . /terra-ui/ | |||
RUN cd /terra-ui && yarn build | |||
RUN cd terra-ui \ | |||
&& PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true yarn install --immutable \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Run yarn install
to build "unplugged" packages (such as ESBuild).
Without PUPPETEER_SKIP_CHROMIUM_DOWNLOAD =true
, Puppeteer's build failed because "The chromium binary is not available for arm64.".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yarn install
is currently being run from the yarn build
script, but this PR removes it from that step.
"@terra-ui-packages/components": "*", | ||
"@terra-ui-packages/core-utils": "*", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Terra UI app depends on the latest code in each package. Yarn resolves imports from these packages to the files in the packages directory.
@@ -64,20 +66,22 @@ | |||
}, | |||
"scripts": { | |||
"analyze": "yarn build && source-map-explorer 'build/static/js/*.js' --gzip", | |||
"build": "yarn install && env $(yarn setenv) vite build && rm build/config.json", | |||
"build": "tsc --build && env $(yarn setenv) vite build && rm build/config.json", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tsc --build
builds each package and checks types. The packages must be built so that Vite can resolve imports from them.
"serve": "vite preview", | ||
"start": "env $(yarn setenv) vite", | ||
"start": "concurrently \"tsc --build --watch\" \"env $(yarn setenv) vite\"", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tsc --build --watch
watches for changes to packages code and rebuilds them. vite
watches for changes to Terra UI code and packages build output and rebuilds Terra UI.
"check-types": "check-dts types/**/*.ts", | ||
"test": "jest", | ||
"check-dts": "check-dts types/**/*.ts", | ||
"check-types": "yarn workspaces foreach run check-dts", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@terra-ui-packages/core-utils
includes type helpers and also has a check-dts
script to check those.
"version": "0.0.1", | ||
"private": true, | ||
"scripts": { | ||
"build": "tsc && tsc -p tsconfig.cjs.json", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We build two different versions of each package (ES Modules and CommonJS).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this have a comment inline describing why we need two versions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Off the top of my head, I'm not sure if NPM / Yarn can tolerate comments in package.json files. This could probably be clarified some by having the first tsc
explicitly state the config file (tsconfig.json
) vs relying on the default. The tsconfig files have comments about what they are for.
"type": "module", | ||
"module": "./lib/es/index.js", | ||
"main": "./lib/cjs/index.js", | ||
"exports": { | ||
".": { | ||
"import": "./lib/es/index.js", | ||
"require": "./lib/cjs/index.js" | ||
} | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Configure exports for using this package via import
(ES Modules) or require
(CommonJS). The package API is the same either way, but they resolve to different files.
"files": [ | ||
"lib/cjs/**", | ||
"lib/es/**" | ||
], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only include build outputs in the published package.
@@ -0,0 +1,3 @@ | |||
export const delay = (ms: number): Promise<void> => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
delay
was pulled into this PR because a type-utils test depends on it.
type LoadedState<S, E = Error> = NoneState | LoadingState<S> | ReadyState<S> | ErrorState<S, E>; | ||
|
||
export default LoadedState; | ||
export type LoadedState<S, E = Error> = NoneState | LoadingState<S> | ReadyState<S> | ErrorState<S, E>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since all imports will be from the package (import { LoadedState } from '@terra-ui-packages/core-utils';
), all exports must be named.
"rootDir": "src" | ||
}, | ||
"include": ["src"], | ||
"exclude": ["src/**/*.types.ts", "src/**/*.errors.ts"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Exclude the files used by check-dts
. lodash-fp-types.errors.ts
intentionally includes invalid code and if it were included, the project would not build.
sonar.javascript.lcov.reportPaths=coverage/lcov.info | ||
sonar.javascript.lcov.reportPaths=coverage/lcov.info,packages/*/coverage/lcov.info |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Each package now has its own coverage report. Upload them all to SonarCloud.
|
||
# Only scan code under src. | ||
sonar.sources=src | ||
sonar.sources=packages,src |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The packages directory now also contains source code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Base TypeScript configuration for all packages and Terra UI itself.
3a7f125
to
77ef903
Compare
Rebased to resolve merge conflict. |
@@ -16,7 +16,9 @@ module.exports = { | |||
} | |||
}, | |||
wrapScriptExecution(executor, project, locator, scriptName) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is what shows the
╔══════════════════════════════════════════════════════════════════════════════╗
║ Be sure to copy a config/xxx.json to build/config.json if you're planning to ║
║ deploy this build. ║
╚══════════════════════════════════════════════════════════════════════════════╝
notice after running a build. We only want to show that on app builds, not package builds.
There's definitely easier ways to show this notice than a Yarn hook, but I'll leave it be here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The copying over happens as part of our build process? I guess I'm wondering why we have this warning at all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it's done in CI.
Line 117 in ecc6bf1
- run: cp config/<< parameters.env >>.json build/config.json |
https://github.com/DataBiosphere/saturn-ui-prod-deploy/blob/44b4565a4dc118482be63e12d6497ab62271fcb0/.circleci/config.yml#L76
Yeah, we could probably get rid of this altogether. Though it might be worth keeping just for the rare case of manual deploys.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is exactly why it is there. If I had the time, I'd instead move this warning into an error message that shows up when the UI attempts to pull that file and finds it absent. This warning was added specifically because the mechanism for resolving that error isn't particularly obvious.
b76a958
to
34f9b83
Compare
packages/components/package.json
Outdated
], | ||
"dependencies": { | ||
"lodash": "^4.17.21", | ||
"react-hyperscript-helpers": "^2.0.0" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see where it uses react-hyperscirpt-helpers
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, it doesn't. I think I intended to use it for Interactive, but then ran into a stumbling block: #3992 (comment).
I can remove it, but any future components added to this package will likely use it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would tend to not including it until it's actually used, but given that I was OK with leaving the test-utils dependency in even though it isn't used yet I guess it's not a big deal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed in 83b8c59.
Kudos, SonarCloud Quality Gate passed! 0 Bugs 26.7% Coverage The version of Java (11.0.11) you have used to run this analysis is deprecated and we will stop accepting it soon. Please update to at least Java 17. |
https://broadworkbench.atlassian.net/browse/UIE-94
This sets up the infrastructure for and begins splitting up Terra UI into multiple packages. As a proof of concept / MVP, this extracts the Interactive component into
@terra-ui-packages/components
and the contents ofsrc/libs/type-utils
into@terra-ui-packages/core-utils
.There are several pieces involved in letting us
import { Interactive } from '@terra-ui-packages/components'
in Terra UI application code...Yarn workspaces are used to have imports from
@terra-ui-packages/components
in Terra UI resolve to that package's directory within the packages directory (./packages/components
).https://yarnpkg.com/features/workspaces
exports
,module
, andmain
configuration in each package's package.json file control how imports of the package are resolved to a file. Each package is configured to have two versions: an ES Module version in lib/es/index.js and a CommonJS version in lib/cjs/index.js. We want the ES Module version to use with a bundler (Vite) and the CommonJS version to use with Jest (since Jest doesn't yet support modules). So with the package.json configuration,import { ... } from '@terra-ui-packages/components'
resolves to./packages/components/lib/es/index.js
andrequire('@terra-ui-packages/components')
resolves to./packages/components/lib/cjs/index.js
.https://www.typescriptlang.org/docs/handbook/esm-node.html#packagejson-exports-imports-and-self-referencing
The files in the lib directory are outputs from a build. Each package has a
build
script configured in package.json. That build script runstsc
twice: once to produce the ES Module output and once to produce the CommonJS output. Those outputs are configured in two TS project files: tsconfig.json has configuration for ES Modules and contains any package specific TS settings that are needed. tsconfig.cjs.json extends tsconfig.json and overrides themodule
andoutDir
settings. Each package's tsconfig.json extends from tsconfig.base.json at the workspace root so that all packages can share common base compiler settings.There's also a tsconfig.json at the workspace root. Currently, it has two functions... It serves as the TS project for the Terra UI application itself (ideally, the application would be a separate package instead of mingled with the workspace root). It also contains references to the TS projects for each package. This allows building all packages from the workspace root with
tsc --build
.https://www.typescriptlang.org/docs/handbook/project-references.html
To have changes to packages code automatically built and reloaded in the browser, as we're used to with application code, the
start
script now runs two things: the Vite dev server andtsc --build --watch
.Changes to development workflow:
yarn run build
does not changeyarn start
is used as before, though now it runs an additional process (tsc --build --watch
)yarn test
...yarn run build
oryarn start
) before running tests for the first time.To run a script for a specific package, use
yarn workspace
. For example, to run tests for core-utils, useyarn workspace '@terra-ui-packages/core-utils' test
.https://yarnpkg.com/cli/workspace
To run a script for all packages, use
yarn workspaces foreach
. For example, to run unit tests for all packages and Terra UI, useyarn workspaces foreach --exclude terra-integration-tests run test
.https://yarnpkg.com/cli/workspaces/foreach