Skip to content
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

Add support for new ENTRY_PATH and PUBLIC_PATH advanced configuration variables #11729

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

blazheskidejan
Copy link

@blazheskidejan blazheskidejan commented Dec 8, 2021

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 the index.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 the package.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

  • Multiple build and start scripts for each mini-app

    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 with BUILD_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 with ENTRY_PATH and BUILD_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",
      }
    }
  • Github Workflow

    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 in package.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",
      }
    }
  • Folder structure

folder-structure

public-assets

@facebook-github-bot
Copy link

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!

@facebook-github-bot
Copy link

Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks!

@facebook-github-bot
Copy link

Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks!

@blazheskidejan blazheskidejan changed the title Add support for new ENTRY_PATH advanced configuration variable Add support for new ENTRY_PATH and PUBLIC_PATH advanced configuration variables Dec 9, 2021
@raix
Copy link
Contributor

raix commented Dec 10, 2021

Not sure I completely follow - when talking about micro front-ends we do have module federation on our radar #11241
or is it regarding adding workspace support in CRA? (I can see your proposed solution but would like to know a bit more about the problem domain)

@blazheskidejan
Copy link
Author

blazheskidejan commented Dec 11, 2021

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 and BUILD_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.

@raix
Copy link
Contributor

raix commented Dec 11, 2021

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

@blazheskidejan
Copy link
Author

blazheskidejan commented Dec 12, 2021

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.

@raix
Copy link
Contributor

raix commented Dec 12, 2021

Great! 🙂 - we might close it in spring cleaning, lets see

@doooby
Copy link

doooby commented Feb 22, 2022

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.

@volatilization
Copy link

This is exactly what i did when first time create react app

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants