- @rapid-eth/3box-platform
The development environment is managed via Lerna. Libraries and modules are seperated into individual packages and managed individually. However, during development all dependencies are managed locally. Creating an enjoyable developer experience.
Get Started The easiest way to first get started is to run the monorepo init command.
yarn ; yarn $
The init command (yarn $
) will setup all package dependencies, and run the watch
and start
commands in parrelel. Allowing developers to quickly start editing files and reviewing changes in the default start application.
The yarn $
should only be run when the monorep needs to be completely rebuilt.
On consecutive development sessions running the command yarn dev
will restart the development envrionment.
Developers can run tests, build and watch process for all packages from the root level. Minimal terminal count.
$ yarn watch // Watch file changes and build dist package.
$ yarn build // Build dist package.
$ yarn test // Run code coverage tests.
To review the full list of developer commands review the package.json file.
"scripts": {
"bootstrap": "lerna bootstrap",
"build": "lerna run build",
"clean": "lerna clean",
"deploy": " lerna run deploy",
"watch": "lerna run --parallel watch",
"start": "lerna run start",
"dev": "yarn watch > /dev/null | yarn start",
"$": "yarn clean ; yarn bootstrap ; yarn setupPackages ; yarn dev",
"setup": "yarn clean ; yarn bootstrap ; yarn setupPackages ; yarn dev",
"setupPackages": "lerna exec -- yarn install",
"test": "FORCE_COLOR=true lerna run lint && CI=true FORCE_COLOR=true lerna run test -- --coverage"
}
Manage the Lerna packaging and hoisting
"workspaces": {
"packages": [
"packages/applications/*",
"packages/components/*",
"packages/external/*",
"packages/libraries/*",
"packages/storybook"
],
"nohoist": [
"**/webpack-dev-server",
"**/babel-loader",
"**/babel-jest",
"**/cross-env",
"**/@react-workspaces/react-scripts"
]
},
- Yarn 1.13.0
- Node 11.14.0
git clone git@github.com:react-workspaces/cra-workspaces-playground
cd cra-workspaces-playground
yarn
cd packages/apps/app-one
yarn start
cd packages/storybook
yarn storybook
cd <workspace-root>
yarn test
Update the homepage
URL in app-one/package.json
to reflect your GitHub Pages URL.
{
"name": "@project/app-one",
"private": true,
"homepage": "https://react-workspaces.github.io/react-workspaces-playground",
"scripts": {
"deploy": "gh-pages -d build"
}
}
Run the deploy script.
cd <workspace-root>
yarn deploy
Use Create React App's --scripts-version
to create a new React App with Yarn Workspaces support.
create-react-app --scripts-version @react-workspaces/react-scripts my-app
React Workspaces Playground uses a custom version of react-scripts
under the hood. The custom react-scripts
is an NPM package to use in place of the react-scripts
dependency that usually ships with Create React App. See: (@react-workspaces/react-scripts) on NPM.
Support for Yarn Workspaces was added by:
-
Adding yarn-workspaces.js file to resolve workspaces modules.
-
Updating the Webpack config:
-
Use
main:src
inpackage.json
for loading development source code. -
Use
production
ordevelopment
settings based on youryarn workspaces
settings in your<workspaces-root>/package.json
:{ "workspaces": { "packages": [ "packages/apps/*", "packages/components", "packages/storybook" ], "production": true, "development": true, "package-entry": "main:src" } }
-
Minimal updates to the Webpack config were required.
Diff: webpack.config.js
--- a/./facebook/react-scripts/config/webpack.config.js
+++ b/react-workspaces/react-scripts/config/webpack.config.js
@@ -9,7 +9,6 @@
'use strict';
const fs = require('fs');
const isWsl = require('is-wsl');
const path = require('path');
const webpack = require('webpack');
const resolve = require('resolve');
@@ -28,15 +27,14 @@ const WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeM
const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
const getCSSModuleLocalIdent = require('react-dev-utils/getCSSModuleLocalIdent');
const paths = require('./paths');
const modules = require('./modules');
+const workspaces = require('./workspaces');
const getClientEnvironment = require('./env');
const ModuleNotFoundPlugin = require('react-dev-utils/ModuleNotFoundPlugin');
const ForkTsCheckerWebpackPlugin = require('react-dev-utils/ForkTsCheckerWebpackPlugin');
const typescriptFormatter = require('react-dev-utils/typescriptFormatter');
// @remove-on-eject-begin
const getCacheIdentifier = require('react-dev-utils/getCacheIdentifier');
// @remove-on-eject-end
// Source maps are resource heavy and can cause out of memory issue for large source files.
const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false';
@@ -53,12 +51,22 @@ const cssModuleRegex = /\.module\.css$/;
const sassRegex = /\.(scss|sass)$/;
const sassModuleRegex = /\.module\.(scss|sass)$/;
+const workspacesConfig = workspaces.init(paths);
+
// This is the production and development configuration.
// It is focused on developer experience, fast rebuilds, and a minimal bundle.
module.exports = function(webpackEnv) {
const isEnvDevelopment = webpackEnv === 'development';
const isEnvProduction = webpackEnv === 'production';
+ const workspacesMainFields = [workspacesConfig.packageEntry, 'main'];
+ const mainFields =
+ isEnvDevelopment && workspacesConfig.development
+ ? workspacesMainFields
+ : isEnvProduction && workspacesConfig.production
+ ? workspacesMainFields
+ : undefined;
+
// Webpack uses `publicPath` to determine where the app is being served from.
// It requires a trailing slash, or the file assets will get an incorrect path.
// In development, we always serve from the root. This makes config easier.
@@ -279,6 +282,7 @@ module.exports = function(webpackEnv) {
extensions: paths.moduleFileExtensions
.map(ext => `.${ext}`)
.filter(ext => useTypeScript || !ext.includes('ts')),
+ mainFields,
alias: {
// Support React Native Web
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
@@ -330,7 +335,11 @@ module.exports = function(webpackEnv) {
loader: require.resolve('eslint-loader'),
},
],
- include: paths.appSrc,
+ include: isEnvDevelopment && workspacesConfig.development
+ ? [paths.appSrc, workspacesConfig.paths]
+ : isEnvProduction && workspacesConfig.production
+ ? [paths.appSrc, workspacesConfig.paths]
+ : paths.appSrc,
},
{
// "oneOf" will traverse all following loaders until one will
@@ -352,7 +361,12 @@ module.exports = function(webpackEnv) {
// The preset includes JSX, Flow, TypeScript, and some ESnext features.
{
test: /\.(js|mjs|jsx|ts|tsx)$/,
- include: paths.appSrc,
+ include:
+ isEnvDevelopment && workspacesConfig.development
+ ? [paths.appSrc, workspacesConfig.paths]
+ : isEnvProduction && workspacesConfig.production
+ ? [paths.appSrc, workspacesConfig.paths]
+ : paths.appSrc,
loader: require.resolve('babel-loader'),
options: {
customize: require.resolve(