Skip to content
This repository has been archived by the owner on May 9, 2022. It is now read-only.

Latest commit

 

History

History
158 lines (110 loc) · 9.3 KB

README-mono.md

File metadata and controls

158 lines (110 loc) · 9.3 KB

react4xp-npm

React4xp logo

React4xp monorepo for the NPM dependency packages required by both lib-react4xp and parent projects running react4xp (for example the react4xp starter and anything derived from it).

These packages (with this project's package names in italics) are:

Moved to it's own repository:

These packages don't need separate installation, they are bundled as dependencies of the main react4xp package (react4xp).



Usage

Not intended for standalone installation or use. See the docs of each unique package, in the links above.



Development

You'll need Gradle 5+ (a 6.2.1 gradle wrapper is included), Java JDK 11, Enonic XP 7+, and Node.

Use Node 12 for development in this project and in all projects when using npm link for linking to these packages locally. Usually, that's when developing lib-react4xp.

Commands:

  • npm install (or gradlew npmInstall): basic setup
  • npm clean: remove npm folders
  • gradlew build: build (includes npmInstall)
  • gradlew clean: clean built files
  • gradlew test: test build
  • gradlew npmLink: for local development; testing these packages in consuming projects before releasing:
    • This runs npm link in all subpackages.
    • After this command, run the /getlinks.sh bash script at the root (windows script is missing for now, sorry) _from the root of a consuming project (/relative/path/getlinks.sh etc) and after running npm install in that project.

NPM packages

Under the packages/ folder are:

  • one "mother packages", react4xp. This corresponds to the react4xp NPM package.
  • several subpackages.

The packages/react4xp mother package has 3 main purposes:

  • It lists all react4xp-* subpackages as dependencies, so that one version of the react4xp package imports and locks in a working combination of all the react4xp subpackages in any consuming project.
  • It supplies the NPM dependencies for all the subpackages in one place (see the important part below) so that subpackages can simply list them under peerDependencies.
  • It supplies a few .gradle files, which can be used to aid the react4xp build in a consuming project.

IMPORTANT: NPM and maintainability

All the sub-packages mentioned above are dependencies of this main react4xp package. In addition react4xp-buildconstants is a dependency of react4xp-runtime-nashornpolyfills:

To avoid falling back into interdependency hell (e.g. dependabot updating the same dependencies in different subpackages, which depend on one another and requiring a lot of extra work for maintaining!), follow these rules:

  • As far as possible, none of the subpackages should any dependencies or devDependencies in their package.json. Instead, this is handled by the package.json files in the root project and packages/react4xp/, like this:
    • A dependency in a subpackage must be listed as a peerDependency in that package, and as a dependency in packages/react4xp/packages.json. It must also be listed in devDependencies (or dependencies) in the root project's package.json.
    • A devDependency in a subpackages must only be listed in devDependencies (or dependencies) in the root project's package.json.
  • If adding/removing subpackages:
    • Update the list under dependencies in packages/react4xp/package.json.
  • If a subpackage is a dev-time dependency of another subpackage (eg. in testing), it should be handled with symlinks (eg. to avoid that testing happens with the downloaded-from-NPM-version of the subpackage instead of actually using locally changed code).
    • Symlink-dir is used to automate this during dev build, in a crossplatform way and directly after npm install. See the postinstall scripts in the root package.json. The result should be this:
    • All subpackages exist as symlinks to their folders, under /packages/react4xp/node_modules.
    • In addition, subpackages that are dev-time required by other subpackages, have similar symlinks under /node_modules.

IMPORTANT: git

When committing to git, please follow the conventional commits pattern in your messages, at least use feat: and BREAKING CHANGE. Also leave tags and all versioning to lerna with the version NPM script (see below) - which depends on using git this way.

Terminal commands

NPM setup

From the project root, handles the entire file structure: triggers the same tasks in subprojects under /packages/, where needed. Only sets up NPM basis, ready for actual project building.

  • npm run setup: initial NPM install, run this first. When this is done, node_modules have been installed across all subprojects, and interlinked.

  • npm run npmInstall (or gradlew npmInstall): When npm run setup has been run once and node_modules exists in the project root, using the npmInstall script updates and re-links the NPM packages but skips initial boilerplate setup to save a little time.

  • npm run clean: NPM cleanup. Removes links and node_modules across all subprojects, including the project root. Does not clean up any files from the actual project build.

NPM structure

After the NPM script npmInstall (and setup, which runs it after installing boilerplate), the state is ready for local development of this project and for local development of lib-react4xp which uses all these projects - and usually downloads them from NPM but can now use npm link react4xp etc for using these packages without having to publish them to NPM before seeing them in action.

Thins ready state should be:

  • All NPM packages for both main project setup and all subprojects are found in (project root)/node_modules.
  • node_modules in all subpackages ar symlinked to (project root)/node_modules ( using symlink-dir for cross-platform symlinking).
  • Each of the subprojects have their own symlink under (project root)/node_modules - taking care of cross-dependencies.

NOTE:

This creates a circular graph of symlinks under node_modules in the different packages. This is fine most of the time, but important to know for two reasons:

  1. Occasionally, this will cause the error message Maximum call stack size exceeded, preventing further progress. If this happens, rebuild completely, in this order: >
  • gradlew clean
  • npm run clean
  • rm -rf node_modules build .gradle
  • npm run setup
  • gradlew build > > (or if these steps are hampered too, do it manually: delete node_modules at root and in all packages and preferrably built files as described in each package's package.json, under files, before finally running setup and build again)
  1. The packages must never be published with this circular graph. For this reason, the versionAndPublish task assumes it's at a ready-to-publish state (where everything is built and tested already: run gradlew build test first), and starts by wiping all these symlinks before proceding to publish.

Building

Again, these commands are only used from the project root:

  • gradlew build: main build command: builds file structure ready for testing and publishing to NPM

  • gradlew test: main test command

  • gradlew clean: deletes everything built by gradle (but leaves the NPM structure alone).

Publishing

  • gradlew versionAndPublish [ -Pdry ] [ -Pmessage='...' ]: Auto-versions all changed packages, and publishes to NPM, after updating internal cross-dependency references. After committing your changes, run this to let lerna handle independent versioning in the packages, by tracking changes across them (use conventional-commit flags from your commit messages to track major:minor:patch versions), tagging the commit and auto-updating version tags everywhere. IMPORTANT: before running version, you should have run the test task. And after versionAndPublish, verify that the react4xp-* references in all packages/*/package-lock.json files are up-to-date (i.e. don't still refer to the previous versions for their dependencies). Further description in comments in versionAndPublish.gradle. Optional parameters:
    • -Pdry: dry-run
    • -Pmessage='...': Common description of the entire release for all changed packages, will be used in commit messages to clarify and group the multiple commits that will occur during the process.