Created by: dblazheski96
Summary
Add support for a new environment variables, ENTRY_PATH
and PUBLIC_PATH
, which may be used to override the default entry point src/index
and the default public path public
. It opens new possiblities for developing mini-apps within a container app without actually doing eject
, hence almost config-less micro-frontend architecure.
Configuring
PUBLIC_PATH
will also update theindex.html
path respectively
Benefits
- The default behaviour is persisted.
- Can be configuired for a different entry point if you like it.
- Can be configuired for a different public path if you like it.
- Not doing
eject
for just a couple of paths (keeping thepackage.json
clean)
If developing mini-apps are in mind
- Shared resources, all in one container app (configurations, rule-sets and even components)
- Great overview of the whole project
- Can be used in CI/CD build piplines
- Again not doing
eject
Examples
-
ENTRY_PATH
configured for each mini-app{ "scripts": { "start": "ENTRY_PATH=src/customer/index react-scripts start", "start:business": "ENTRY_PATH=src/business/index react-scripts start", "start:admin": "ENTRY_PATH=src/admin/index react-scripts start", }, }
ENTRY_PATH
can be used in conjunction withBUILD_PATH
for a nicer output structure{ "scripts": { "build": "ENTRY_PATH=src/customer/index BUILD_PATH=build/customer react-scripts build", "build:business": "ENTRY_PATH=src/business/index BUILD_PATH=build/business react-scripts build", "build:admin": "ENTRY_PATH=src/admin/index BUILD_PATH=build/admin react-scripts build", } }
PUBLIC_PATH
used in conjunction withENTRY_PATH
andBUILD_PATH
{ "scripts": { "build": "ENTRY_PATH=src/customer/index PUBLIC_PATH=public/customer BUILD_PATH=build/customer react-scripts build", "build:business": "ENTRY_PATH=src/business/index PUBLIC_PATH=public/business BUILD_PATH=build/business react-scripts build", "build:admin": "ENTRY_PATH=src/admin/index PUBLIC_PATH=public/admin BUILD_PATH=build/admin react-scripts build", } }
-
on: push: branches: - main paths-ignore: - 'src/customer/**' - 'src/admin/**' <!-- rest of configuration --> env: ENTRY_PATH: src/business/index PUBLIC_PATH: public/business BUILD_PATH: build/business
For this workflow example, only the default
build
script inpackage.json
is necessary, others can be used for development purposes.{ "scripts": { "build": "react-scripts build", "build:customer": "ENTRY_PATH=src/customer/index PUBLIC_PATH=public/customer BUILD_PATH=build/customer react-scripts build", "build:business": "ENTRY_PATH=src/business/index PUBLIC_PATH=public/business BUILD_PATH=build/business react-scripts build", "build:admin": "ENTRY_PATH=src/admin/index PUBLIC_PATH=public/admin BUILD_PATH=build/admin react-scripts build", } }
-
Activity
requested review from @root
requested review from @root
Created by: facebook-github-bot
Hi @dblazeski96!
Thank you for your pull request and welcome to our community.
Action Required
In order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you.
Process
In order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA.
Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with
CLA signed
. The tagging process may take up to 1 hour after signing. Please give it that time before contacting us about it.If you have received this in error or have any questions, please contact us at cla@fb.com. Thanks!
added CLA Signed label
Created by: dblazheski96
Thanks @raix for getting back to me, I would be happy to provide more info, well I guess I should start at the problem domain:
I need to come up with a solution to develop 3 separate client applications which are part of the same system, each app will control it's own business sub-domain (customer sub-domain, business sub-domain and admin sub-domain). Each sub-domain is fairly different from one another, that means the apps will have fairly different features (in this case anyway), but most of the base components (maybe even more complex components), packages, configurations and rule-sets will be exactly the same, so I want to share those things between the apps all in one place (without copy-paste into 3 different projects). I found and tried a few solutions, but ether required lots of configs or didn't work as I would excepted. I was looking for something simpler and I also felt like it wasn't worth all that configurations.
Eventually I realized that for all 3 apps I'm looking at the same project, but with different business/domain logic. So I tried to do exactly that: create 1 container project where all shared assets will be located, and try to separate the business/domain logic of all 3 apps into their own separate locations within the container project. And came up with this solution, by combining
ENTRY_PATH
,PUBLIC_PATH
andBUILD_PATH
I can get different "build pipelines/branches/paths" where each of these "build pipeline/branch/path" will represent a way to build the app with the required shared assets of the container project and it's own business/domain logic.Also one difference between module federation and this solution is that, as I understood it right (maybe not, but correct me if I'm wrong) module federation is sharing the components on runtime and would require all shared apps to be running for full shared experience, while this solution is actually building a self-contained apps (note only used shared assets are built, other are ignored)
Using this solution would be helpful if the real difference between the apps is the business logic, while most of the assets are the same like components, configurations (rc, json, js, etc.), even some routes, etc. It gives a nice overview of all apps, but still keeps them separate. And it doesn't let you worry about maintaining another package just for shared assets.
There is definitely a room for improvement, for example maybe a separate configuration could be added, or react-scripts could take these as arguments so
package.json
would look cleaner.Created by: raix
We are trying to keep the number of configurations down to a minimum in CRA, it seems like this issue could be solved by:
- Make them 3 projects with their own builds - packages could be shared using yarn/npm workspaces
- If it should build as one big application, then have one entry point and code split the rest using lazy loading
Let me know if I misunderstood the problem
Created by: dblazheski96
No actually, you understood it just right.
I wasn't very familiar with the npm/yarn workspaces concept, so I took a good look yesterday and made a few test projects. It seems to me that this is by far the best solution for my problem, so thank you for pointing out that to me. I see now that create-react-app is using the same concept, I taught it was just a folder structure decision.
Well this pull request was primarily opened for my multi-app issue, which is now resolved, I still think these two ENV variables can be useful in some cases, and they are optional. So I guess if you guys think these two are just bloat, I will close this pull request, else I will leave it open.
added tag: documentation label
Created by: doooby
Hello, I'd like you to reconsider discarding of this configuration options.
Our app is inserted into a web page. For development we have a mock index.html and few files of vendor js & css to simulate the parent page on locale. For production there's a plain index.tml with just a single div as app's root, i.e. different set of files in public directory. In this scenario we are switching the public directory in file system before each start/build. So I hope you see how having an option to set PUBLIC_PATH would make it so much simpler.
It seems that implementing this configuration option is a very small addition to the code. And ejecting to achieve it feels so wrong.