Skip to content

Conversation

@willhuang1997
Copy link
Contributor

@willhuang1997 willhuang1997 commented May 15, 2023

This PR is to separate the designated streamlit components to a library. The apis that can should be consumed from this library will be VerticalBlock, ElementNodeRenderer and themes from Streamlit if need be. For full api, visit frontend/lib/index.ts.

In order to do this, import paths, github actions, local development flows will change and packaging of the library must happen.

  • import paths
    • import paths will be changed from src/app to app/src. The same will happen to lib.
  • Github Actions
    • Nothing super significant will change here. Things will get a little slower because we have to run make protobuf and make frontend-lib and some directories will be changed.
  • Local Development flows
    • yarn
      • The changes here now use yarn workspaces. app still uses CRA but lib has its own bundling and compilation.
        • yarn buildLib
          • The way that lib bundles and compiles is through babel and tsc. Babel is so our tyepscript code can be used in the browser by transforming our typescript code into browser javascript. Tsc is to emit type declarations so that another person can use our library as typescript. We also do a cp command that copies our auto-generated proto files to our library.
        • yarn build
          • Uses the build command from CRA so essentially the same except we have to run yarn buildLib first.
      • yarn start
        • This will somewhat similar. You can do yarn start; however, you will also have to run python scripts/watch_frontend_lib.py or make watch-frontend-lib from the streamlit root directory to hot reload the lib code. This occurs because @streamlit/lib is its own library. We shall iterate on this workflow later on.

lib and app will also have separate jest configs (though they are pretty similar) and tsconfig.json (typescript checks).

…derer (#6623)

This PR is the first milestone to determine the minimal number of exports needed for app to consume + VerticalBlock + ElementNodeRenderer.

Most of the changes are import path changes. Some of the more notable changes to look through are

How the @streamlit/lib is built. It's built through the monorepo config for babel (https://babeljs.io/docs/config-files/#monorepos).
a. The babel process works by using a custom preset that is mainly babel-preset-react-app but slightly modified in order to make sure glide data grid code is es6 compatible and hard coding isTypeScriptEnabled to True.
b. The other keys are adding in the emotion plugin for styled-components, ignoring proto, vendor, test files, and telling babel that frontend is the root directory for babel config.
The actual index.ts that is added to frontend/lib
Some things to note that will be punt down but worked on later:

We also need to look into why protobuf can't be compiled through tsc.

Cleaning frontend/app/package.json
Cleaning frontend/app/yarn.lock
Cleaning frontend/lib/scripts/create.js
Determine what's going wrong with globalStyles typing
Determine what's going wrong with styled-components typing for EmotionTheme
…ied through cp command. (#6635)

Tim noticed that I was copying the protobuf.js and protobuf.d.ts instead of compiling it through babel. That causes problems because then you have to import by doing import { ... } from "@streamlit/lib/dist/proto" which doesn't make any sense.
The reason why I did that was because I was getting an error on first try:

`src/proto.js:4:1 - error TS9005: Declaration emit for this file requires using private name 'Radii'. An explicit type annotation may unblock declaration emit.

4 import * as $protobuf from "protobufjs/minimal";
  ~~~~~~

src/proto.js:4:1 - error TS9005: Declaration emit for this file requires using private name 'Radio'. An explicit type annotation may unblock declaration emit.

4 import * as $protobuf from "protobufjs/minimal";`
I just removed the proto files and did a make protobuf and then tried exporting and that worked, as it should.
There are going to be 2 emotion.d.ts. Our @streamlit/lib has our own theming and then our app will simply just be consuming from @streamlit/lib which makes sense.
The current folder structure is frontend/app/src/app. We should make it so that it's frontend/app/src and remove the extra app directory.
This PR also fixes the audit_license script.
This PR is to fix eslint for app and lib. This also adds dependencies that are necessary to lib's package.json. This is done through eslint noticing the necessary dependencies. This PR also does some linting and also does a merge from develop as we need the BaseButton refactoring to stop duplication of exports from the root index.ts.

In addition, this PR fixes the type checking github actions by adding new commands.
This is to fix yarn test. This simply adds new scripts through the yarn workspace command to run app and lib tests.
Currently, the lib testing works by mainly using the same scripts that CRA uses for transpiling typescript to javascript.

There is one other thing to note: It looks like if you were to upgrade to 17.0.1 supposedly for react-dom, it would fix jest tests for app to not hang (facebook/react#20756 (comment)). However, jest was still hanging so I just did a delete MessageChannel within src/setupTests.js and we can remove that when we upgrade to React 18.
* Remove unused app dep / dev dep and declarations.d.ts

* Remove d3 color resolution (#6714)

* Add dependencies removed from app to lib/package.json

* Add pbjs cli

* Readd notices
Since @streamlit/lib is separated out to be its own separate lib, we need a script to constantly rebuild when the files change.

Will also need to update the contributing wiki after this is merged to develop.
@willhuang1997 willhuang1997 added the security-assessment-completed Security assessment has been completed for PR label May 24, 2023
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like this does belong but not sure why this is saying it's added

Copy link
Contributor Author

@willhuang1997 willhuang1997 May 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can see that this snapshot is here deleted

Copy link
Collaborator

@lukasmasuch lukasmasuch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall LGTM. But I wasn't following this project too closely, so I don't have too much context on this.

Some questions:

  1. What exactly will be our new development workflow with this change? E.g. I usually have the following setup: One terminal with streamlit run ... and one terminal with yarn start in frontend. And it will hot reload whenever I do any frontend change.

  2. How do I build a distribution with this change? I currently do: 1. make protobuf 2. make frontend 3. make distribution in the Streamlit root folder.

  3. This isn't necessarily something specific to this change. But I think the three snapshot files that I have commented on above are kind of broken and we should eventually remove those. I believe there isn't any real value in doing a snapshot on the enzyme mount as done in those cases. But this could also be done in a separate PR.

Copy link
Collaborator

@lukasmasuch lukasmasuch Jun 28, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we remove this? See comment above.

@willhuang1997
Copy link
Contributor Author

What exactly will be our new development workflow with this change? E.g. I usually have the following setup: One terminal with streamlit run ... and one terminal with yarn start in frontend. And it will hot reload whenever I do any frontend change.

one terminal for streamlit run ..., one terminal for yarn start, one terminal for make watch-frontend-lib.
make watch-frontend-lib is not currently perfectly hot-reloading but I will be adding a fast-follow PR to improve that experience. The page browser needs to be reloaded right now manually but it does recompile files automatically on save.

How do I build a distribution with this change? I currently do: 1. make protobuf 2. make frontend 3. make distribution in the Streamlit root folder.

I just tried make package and the flow you suggested. they both should work.

This isn't necessarily something specific to this change. But I think the three snapshot files that I have commented on above are kind of broken and we should eventually remove those. I believe there isn't any real value in doing a snapshot on the enzyme mount as done in those cases. But this could also be done in a separate PR.

I will make a separate PR!

@lukasmasuch
Copy link
Collaborator

I will make a separate PR!

I have added a discussion topic on that for our next standup. So no rush to get a PR on that out :)

The page browser needs to be reloaded right now manually but it does recompile files automatically on save.

Does this mean that I need to refresh the browser manually to see the change?

@sfc-gh-wihuang
Copy link
Contributor

sfc-gh-wihuang commented Jun 28, 2023

Does this mean that I need to refresh the browser manually to see the change?

Yes :/. I was planning to add a fast-follow PR to look through tabs with localhost:3000 with pyautogui and refresh it.

@lukasmasuch
Copy link
Collaborator

lukasmasuch commented Jun 28, 2023

I'm not too worried about manually refreshing the tab on changes. But I still see some risk that it negatively impacts the overall frontend development flow. E.g. how fast does it compile after a change? Is it about the same as in the current hot reloading? Do we see the full stack traces on frontend exceptions, or only the minified versions? ...

We definitely should take that into the next standup discussion before merging. And maybe you giving a demo of how local frontend development will work with these changes.

@willhuang1997
Copy link
Contributor Author

I'm not too worried about manually refreshing the tab on changes. But I still see some risk that it negatively impacts the overall frontend development flow. E.g. how fast does it compile after a change? Is it about the same as in the current hot reloading? Do we see the full stack traces on frontend exceptions, or only the minified versions? ...

We definitely should take that into the next standup discussion before merging. And maybe you giving a demo of how local frontend development will work with these changes.

Sure I can give a demo.

E.g. how fast does it compile after a change? Is it about the same as in the current hot reloading?

I would say the compilation time is a good amount slower since you have to build the library which in itself is just slow and expected to be some what slow. I would say the compilation will likely take a 30 seconds - a minute.

Do we see the full stack traces on frontend exceptions, or only the minified versions?

Let me test that and get back to you or write up something during standup.

)

<!--
⚠️ BEFORE CONTRIBUTING PLEASE READ OUR CONTRIBUTING GUIDELINES!
https://github.com/streamlit/streamlit/wiki/Contributing
-->

## Describe your changes
- Change imports for `app` to `@streamlit/app/src...` as we removed the `ModuleScopePlugin` which allows us to import out of `app/src`. 
- Change imports for `lib` to absolute imports
- add `tsconfig.dev.json` that is specifically for developement
- change `tsconfig.json` for `lib` and `app`
- change `.eslintrc` to `.eslintrc.js` in order to gain access to `__dirname` to make typescript configs relative to each project

## GitHub Issue Link (if applicable)

## Testing Plan
Manually testing
- Explanation of why no additional tests are needed
- Unit Tests (JS and/or Python)
- E2E Tests
- Any manual testing needed?
yes

https://github.com/streamlit/streamlit/assets/16749069/cc0a5f96-f8cd-487b-b70e-6a4e5823f0e7


---

**Contribution License Agreement**

By submitting this pull request you agree that all contributions to this project are made under the Apache 2.0 license.
})
// Remove ModuleScopePlugin which throws when we try to import something
// outside of src/.
webpackConfig.resolve.plugins.pop()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer a more specific search to remove by name. See further up in the code.

This will make this more resilient to react-scripts.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will make a separate PR to develop after merging.

@willhuang1997 willhuang1997 merged commit add33a6 into develop Jul 10, 2023
tconkling added a commit to tconkling/streamlit that referenced this pull request Jul 12, 2023
* develop:
  Feature: st.toast (streamlit#6783)
  Bump semver from 5.7.1 to 5.7.2 in /frontend (streamlit#6982)
  Add host communication e2e tests  (streamlit#6806)
  Re-add homepage to package.json (streamlit#6987)
  Remove unnecessary code and Add rm commands to make clean (streamlit#6980)
  Allow setting placeholder for st.selectbox (streamlit#6913)
  Allow setting placeholder for st.multiselect (streamlit#6901)
  Also use bottom padding in embedded mode for chat input (streamlit#6979)
  Feature/st lib (streamlit#6692)
  Remove unused import (streamlit#6977)
  Release 1.24.1 (streamlit#6965)
  Update st.audio/st.video docstrings (streamlit#6964)
  Slightly simplify bug report template (streamlit#6972)
  Fix baseweb warnings by using longhand properties (streamlit#6976)
@vdonato vdonato deleted the feature/st-lib branch November 1, 2023 23:57
asmeralt pushed a commit to asmeralt/streamlit that referenced this pull request Sep 29, 2025
* Minimal exports for app to consume + VerticalBlock and ElementNodeRenderer (streamlit#6623)

This PR is the first milestone to determine the minimal number of exports needed for app to consume + VerticalBlock + ElementNodeRenderer.

Most of the changes are import path changes. Some of the more notable changes to look through are

How the @streamlit/lib is built. It's built through the monorepo config for babel (https://babeljs.io/docs/config-files/#monorepos).
a. The babel process works by using a custom preset that is mainly babel-preset-react-app but slightly modified in order to make sure glide data grid code is es6 compatible and hard coding isTypeScriptEnabled to True.
b. The other keys are adding in the emotion plugin for styled-components, ignoring proto, vendor, test files, and telling babel that frontend is the root directory for babel config.
The actual index.ts that is added to frontend/lib
Some things to note that will be punt down but worked on later:

We also need to look into why protobuf can't be compiled through tsc.

Cleaning frontend/app/package.json
Cleaning frontend/app/yarn.lock
Cleaning frontend/lib/scripts/create.js
Determine what's going wrong with globalStyles typing
Determine what's going wrong with styled-components typing for EmotionTheme

* Change exports for protobuf to be included in index.ts instead of copied through cp command. (streamlit#6635)

Tim noticed that I was copying the protobuf.js and protobuf.d.ts instead of compiling it through babel. That causes problems because then you have to import by doing import { ... } from "@streamlit/lib/dist/proto" which doesn't make any sense.
The reason why I did that was because I was getting an error on first try:

`src/proto.js:4:1 - error TS9005: Declaration emit for this file requires using private name 'Radii'. An explicit type annotation may unblock declaration emit.

4 import * as $protobuf from "protobufjs/minimal";
  ~~~~~~

src/proto.js:4:1 - error TS9005: Declaration emit for this file requires using private name 'Radio'. An explicit type annotation may unblock declaration emit.

4 import * as $protobuf from "protobufjs/minimal";`
I just removed the proto files and did a make protobuf and then tried exporting and that worked, as it should.

* Simple fix for globalStyles (streamlit#6651)

* Fix typing issues for styled-components (streamlit#6652)

There are going to be 2 emotion.d.ts. Our @streamlit/lib has our own theming and then our app will simply just be consuming from @streamlit/lib which makes sense.

* remove extra app directory in frontend dir (streamlit#6653)

The current folder structure is frontend/app/src/app. We should make it so that it's frontend/app/src and remove the extra app directory.
This PR also fixes the audit_license script.

* Remove unnecessary files

* Fix naming of directories and files

* Fix BaseColorPicker directory

* Add Fixes that should exist in feature/st-lib

* Fix Eslint and Type-checking for st-lib (streamlit#6675)

This PR is to fix eslint for app and lib. This also adds dependencies that are necessary to lib's package.json. This is done through eslint noticing the necessary dependencies. This PR also does some linting and also does a merge from develop as we need the BaseButton refactoring to stop duplication of exports from the root index.ts.

In addition, this PR fixes the type checking github actions by adding new commands.

* Fix notices (streamlit#6676)

* Clean up audit_frontend_licenses

* Fix/yarn test (streamlit#6681)

This is to fix yarn test. This simply adds new scripts through the yarn workspace command to run app and lib tests.
Currently, the lib testing works by mainly using the same scripts that CRA uses for transpiling typescript to javascript.

There is one other thing to note: It looks like if you were to upgrade to 17.0.1 supposedly for react-dom, it would fix jest tests for app to not hang (facebook/react#20756 (comment)). However, jest was still hanging so I just did a delete MessageChannel within src/setupTests.js and we can remove that when we upgrade to React 18.

* Fix regex that I accidentally forgot to commit (streamlit#6698)

* Fix/cypress (streamlit#6699)

* Remove unused app dep / dev dep and declarations.d.ts (streamlit#6713)

* Remove unused app dep / dev dep and declarations.d.ts

* Remove d3 color resolution (streamlit#6714)

* Add dependencies removed from app to lib/package.json

* Add pbjs cli

* Readd notices

* Add watch lib script (streamlit#6730)

Since @streamlit/lib is separated out to be its own separate lib, we need a script to constantly rebuild when the files change.

Will also need to update the contributing wiki after this is merged to develop.

* Get rid of yarn start warnings and clean Makefile (streamlit#6739)

* Remove streamlit.css. I'm not sure where it came from

* Fix yarn buildLib

* Fix eslintrc

* Fix codeql

* Add notices and yarn.lock

* Fix glide-data-grid versions

* Fix nits

* Fix nits

* Lint and cleanup

* Minor cleanup for Block utils as comments got removed

* Remove accidentally committed file

* Revert "Remove accidentally committed file"

This reverts commit 87b7f13.

* Fix yarn lock

* Fix compilation errors

* Fix lint

* Fix notices

* Remove unnecessary package.json dependencies

* Fix package.json versions

* Fix yarn.lock and streamlit dialog snapshots

* Fix notices

* Have faster hot reloading and absolute imports for @streamlit/lib (streamlit#6961)

<!--
⚠️ BEFORE CONTRIBUTING PLEASE READ OUR CONTRIBUTING GUIDELINES!
https://github.com/streamlit/streamlit/wiki/Contributing
-->

## Describe your changes
- Change imports for `app` to `@streamlit/app/src...` as we removed the `ModuleScopePlugin` which allows us to import out of `app/src`. 
- Change imports for `lib` to absolute imports
- add `tsconfig.dev.json` that is specifically for developement
- change `tsconfig.json` for `lib` and `app`
- change `.eslintrc` to `.eslintrc.js` in order to gain access to `__dirname` to make typescript configs relative to each project

## GitHub Issue Link (if applicable)

## Testing Plan
Manually testing
- Explanation of why no additional tests are needed
- Unit Tests (JS and/or Python)
- E2E Tests
- Any manual testing needed?
yes

https://github.com/streamlit/streamlit/assets/16749069/cc0a5f96-f8cd-487b-b70e-6a4e5823f0e7


---

**Contribution License Agreement**

By submitting this pull request you agree that all contributions to this project are made under the Apache 2.0 license.

* Fix minor comments from Lukas
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

change:refactor PR contains code refactoring without behavior change impact:internal PR changes only affect internal code security-assessment-completed Security assessment has been completed for PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants