bigtest
bigtest copied to clipboard
Standardize all building and packaging
- Reference Issues: (#750)
- Implementation PR: (leave this empty)
Summary
Standardize the building and packaging of all bigtest compiled artefacts.
Basic example
The build tooling should live at a higher level than the bigtest monorepo with as little configuration required as possible apart from existing configuration files such as package.json and tsconfig.json.
An executable file of some description will create the correct compiled artefacts with as few instructions as possible, e.g.
yarn frontside build esm commonjs umd
The executable API should hide any individual bundler information.
Motivation
At the time of writing, all build configuration is set in individual npm build scripts called prepack.
For example, @bigtest/interactor and @bigtest/client both have this prepack script:
"prepack": "tsc --build && tsc --outdir dist/esm --module es2015 && tsc --outdir dist/cjs --module commonjs"
While most other packages have a more bare-bones preack script:
"prepack": "tsc --outdir dist --declaration --sourcemap"
There is too much configuration in each prepack script and no consistency.
There is no standardisation or reuse across existing packages.
Requirements
For this issue/RFC, the requirements are to standardise building only. We can iterate on further requirements after we have one feature complete.
- The build tool should require no additional configuration if possible. The tool should be able to infer a lot from the existing
package.jsonfile,tsconfig.jsonfile etc. - for example, the
exportssection of thepackage.jsonshould tell us which types of build are required. - All
package.jsonfiles should utilise the new exports field. - All bigtest packages should be esm packages by default.
- The
@frontside/tsconfigbase tsconfig file should state that each package starts life as an esm package:
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "node",
"strict": true,
- Each package under bigtest should be capable of creating one or all of the following builds:
- ESM build
- commonjs build
- umd
There are 2 separate concerns with regards to building. There is building in the context of running the tests and there is building in the context of pre-publishing. Currently, we do not test the different outputs so yarn build should only perform the default configured build and not produce different targetted outputs.
- Executing
yarn buildat a monorepo root should build all packages in the monorepo and executingyarn buildat the subpackage level should build only that package. The executable running thebuildcommand should know what to do by reading the nearestpackage.jsonfile. - Publishing packages should execute a
preparestep that will build the various outputs such asesm,commonjs,umd. The executable can ascertain what is required by reading the package.json file.
Detailed Design
An executable of some description should be installed into the node_modules/.bin directory that executes the following commands.
The | character below defines a choice of one or a combination of any of the choices.
- yarn frontside build esm | commonjs | umd | static-web | srr-web | all -mode watch | headless | CI
- yarn frontside test unit | integration | e2e | all
- yarn frontside lint ts | js | all
- yarn frontside watch
Commands should be short and snappy and give no clues as to how the commands are implemented or any attached framework. Convention over configuration should be favoured over endless configuration.
Any new package that is added as a direct child of ./packages/ should be included in root level builds of all packages.
Drawbacks
There is a danger of trying to boil the ocean. The solution should concentrate only on bigtest's current needs and not the world at large. Any more significant enhancements are added later in incremental PRs outside of bigtest.
- Scope creep
- Are we making things better?
Alternatives
- find an existing solution, either open source or closed source, such as
- snowpack
- ultra runner
- rushjs
- nx has a great plugin architecture and might be a good fit
Let's add linting to the mix. I feel like it's important that we not need to include eslint and @frontside/eslint-config in each project.
Let's add linting to the mix. I feel like it's important that we not need to include
eslintand@frontside/eslint-configin each project.
agreed and I've updated the text.
I think also in the alternatives section, there are some monorepo management solutinos like rushjs that may have some overlap with anything that we would develop in-house
I think also in the alternatives section, there are some monorepo management solutinos like
rushjsthat may have some overlap with anything that we would develop in-house
Good idea. Getting something that required 0 development would be nice.
I'll have a scan and update the doc.
I'd like to try and capture as much as possible what the developer experience would look like. For example, the current setup, which has now been enhanced with #764 to have clean scripts, watch scripts, etc... should also be part of this document. How would our custom build executable handle all these cases?
Other DX questions we should address:
- Let's say we wanted to add a new package to the
/packagesworkspace. What would be the steps to hook that into the build? - If I'm creating a new repo that is going to use this tool, how do I set up CI to compile my sources for publication?
- Can we enumerate some of the development scenarios and what workflows this too should support. I'm thinking things like
- adding feature to
@bigtest/server - extracting function from
@bigtest/effectionto@effection/thing - adding feature to
@bigtest/agentweb application
- adding feature to
@cowboyd I would like to see how far we can get with no config and see if we can tell what needs to be done from the package.json and the tsconfig.json and the whole cast of other .config files that are now part of javascript development.
I'd also be wary of adding too many requirements at this stage and instead focus on just one right now which is the building capability first and then we can create see how that went and iterate on the next and create a new issue/RFC, if you are OK with that? If not I will update further.
I have updated the requirements, let me know if this is sufficient
@dagda1 Much of this can be speculative, but if we're talking about embarking on a custom build tool, then I want to make sure that we don't end up painting ourselves into any local maxima.
We don't have to implement everything at once, but since this is an RFC level discussion, it pays to rove a bit farther into the future.
@cowboyd I'ved added a Detailed design section. Please feel free add or change anything.