Skip to content

Commit 45db6dc

Browse files
authored
chore: Make Feast UI importable as a NPM Module (#2370)
* Make FeastUI publishable as NPM Module Signed-off-by: Tony Chu <tonyhschu@gmail.com> * Fixes tests Signed-off-by: Tony Chu <tonyhschu@gmail.com> * Add Feature Flags as Config Signed-off-by: Tony Chu <tonyhschu@gmail.com> * Update package.json Signed-off-by: Tony Chu <tonyhschu@gmail.com> * Make where to fetch projects configurable. Signed-off-by: Tony Chu <tonyhschu@gmail.com> * Match Feast's License Signed-off-by: Tony Chu <tonyhschu@gmail.com> * Better error messages for missing Project List Signed-off-by: Tony Chu <tonyhschu@gmail.com> * Fix typo and remove gitignore Signed-off-by: Tony Chu <tonyhschu@gmail.com> * Add customization instructions to the README Signed-off-by: Tony Chu <tonyhschu@gmail.com> * Add back tests and document publishing Signed-off-by: Tony Chu <tonyhschu@gmail.com>
1 parent ab5daae commit 45db6dc

File tree

80 files changed

+2928
-2013
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+2928
-2013
lines changed

infra/scripts/release/files_to_bump.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@ infra/charts/feast/charts/feature-server/values.yaml
99
infra/charts/feast/README.md
1010
infra/charts/feast-python-server/Chart.yaml
1111
infra/charts/feast-python-server/README.md
12-
java/pom.xml
12+
java/pom.xml
13+
ui/package.json

ui/.babelrc.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports = {
2+
presets: [["@babel/preset-env"], ["@babel/preset-react"]],
3+
};

ui/PUBLISHING_TO_NPM.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Publishing the Feast Package to NPM
2+
3+
The Feast UI is published as a module to NPM and can be found here: https://www.npmjs.com/package/@feast-dev/feast-ui
4+
5+
To publish a new version of the module, you will need to be part of the @feast-dev team in NPM. Ask Tony to add you if necessary. You will also need to [login to your NPM account on the command line](https://docs.npmjs.com/cli/v8/commands/npm-adduser).
6+
7+
## Steps for Publishing
8+
9+
1. Make sure tests are passing. Run tests with `yarn tests` in the ui directory.
10+
2. Bump the version number in `package.json` as appropriate.
11+
3. Package the modules for distributions. Run the library build script with `yarn build:lib`. We use [Rollup](https://rollupjs.org/) for building the module, and the configs are in the `rollup.config.js` file.
12+
4. Publish the package to NPM. Run `npm publish`
13+
5. [Check NPM to see that the package was properly publish](https://www.npmjs.com/package/@feast-dev/feast-ui).

ui/README.md

Lines changed: 112 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,46 +16,135 @@ available for the rest of the UI.
1616
- `src/custom-tabs` includes sample custom tabs. This is a WIP plugin system where users can inject their own tabs and
1717
data to the UI.
1818

19+
## Usage
20+
21+
There are two modes of usage: importing the UI as a module, or running the entire build as a React app.
22+
23+
### Importing the UI as a module
24+
25+
This is the recommended way to use Feast UI for teams maintaining their own internal UI for their deployment of Feast.
26+
27+
Start with bootstrapping a React app with `create-react-app`
1928

20-
## Available Scripts
29+
```
30+
npx create-react-app your-feast-ui
31+
```
2132

22-
In the project directory, you can run:
33+
Then, in your app folder, install Feast UI and its peer dependencies. Assuming you use yarn
2334

24-
### `yarn start`
35+
```
36+
yarn add @feast-dev/feast-ui
37+
yarn add @elastic/eui @elastic/datemath @emotion/react moment prop-types inter-ui react-query react-router-dom use-query-params zod typescript query-string d3 @types/d3
38+
```
2539

26-
Runs the app in the development mode.\
27-
Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
40+
Edit `index.js` in the React app to use Feast UI.
2841

29-
The page will reload if you make edits.\
30-
You will also see any lint errors in the console.
42+
```js
43+
import React from "react";
44+
import ReactDOM from "react-dom";
45+
import "./index.css";
3146

32-
### `yarn test`
47+
import FeastUI from "@feast-dev/feast-ui";
48+
import "@feast-dev/feast-ui/dist/feast-ui.css";
3349

34-
Launches the test runner in the interactive watch mode.\
35-
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
50+
ReactDOM.render(
51+
<React.StrictMode>
52+
<FeastUI />
53+
</React.StrictMode>,
54+
document.getElementById("root")
55+
);
56+
```
57+
58+
When you start the React app, it will look for `project-list.json` to find a list of your projects. The JSON should looks something like this.
59+
60+
```json
61+
{
62+
"projects": [
63+
{
64+
"name": "Credit Score Project",
65+
"description": "Project for credit scoring team and associated models.",
66+
"id": "credit_score_project",
67+
"registryPath": "/registry.json"
68+
},
69+
]
70+
}
71+
```
72+
73+
```
74+
// Start the React App
75+
yarn start
76+
```
77+
78+
#### Customization
79+
80+
The advantage of importing Feast UI as a module is in the ease of customization. The `<FeastUI>` component exposes a `feastUIConfigs` prop thorough which you can customize the UI. Currently it supports a few parameters.
81+
82+
##### Fetching the Project List
3683

37-
### `yarn build`
84+
You can use `projectListPromise` to provide a promise that overrides where the Feast UI fetches the project list from.
3885

39-
Builds the app for production to the `build` folder.\
40-
It correctly bundles React in production mode and optimizes the build for the best performance.
86+
```jsx
87+
<FeastUI
88+
feastUIConfigs={{
89+
projectListPromise: fetch(SOME_PATH, {
90+
headers: {
91+
"Content-Type": "application/json",
92+
},
93+
}).then((res) => {
94+
return res.json();
95+
})
96+
}}
97+
/>
98+
```
4199

42-
The build is minified and the filenames include the hashes.\
43-
Your app is ready to be deployed!
100+
##### Custom Tabs
44101

45-
See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
102+
You can add custom tabs for any of the core Feast objects through the `tabsRegistry`.
46103

47-
### `yarn eject`
104+
```
105+
const tabsRegistry = {
106+
RegularFeatureViewCustomTabs: [
107+
{
108+
label: "Custom Tab Demo", // Navigation Label for the tab
109+
path: "demo-tab", // Subpath for the tab
110+
Component: RFVDemoCustomTab, // a React Component
111+
},
112+
]
113+
}
48114
49-
**Note: this is a one-way operation. Once you `eject`, you can’t go back!**
115+
<FeastUI
116+
feastUIConfigs={{
117+
tabsRegistry: tabsRegistry,
118+
}}
119+
/>
120+
```
50121

51-
If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
122+
Examples of custom tabs can be found in the `/custom-tabs` folder.
52123

53-
Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.
124+
### Alternative: Run this Repo
125+
126+
If you would like to simply try things out and see how the UI works, you can simply run the code in this repo. First:
127+
128+
### `yarn install`
129+
130+
That will install the all the dependencies that the UI needs, as well as development dependencies. Then in the project directory, you can run:
131+
132+
### `yarn start`
133+
134+
Runs the app in the development mode.\
135+
Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
136+
137+
The page will reload if you make edits.\
138+
You will also see any lint errors in the console.
139+
140+
### `yarn test`
141+
142+
Launches the test runner in the interactive watch mode.\
143+
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
54144

55-
You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.
56145

57-
## Learn More
146+
## On React and Create React App
58147

59-
You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
148+
This project was bootstrapped with Create React App, and uses its scripts to simplify UI development. You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
60149

61150
To learn React, check out the [React documentation](https://reactjs.org/).

ui/package.json

Lines changed: 77 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,58 @@
11
{
2-
"name": "feast-ui",
3-
"version": "0.1.0",
4-
"private": true,
5-
"dependencies": {
2+
"name": "@feast-dev/feast-ui",
3+
"version": "0.19.0",
4+
"private": false,
5+
"files": [
6+
"dist"
7+
],
8+
"main": "./dist/feast-ui.cjs",
9+
"module": "./dist/feast-ui.module.js",
10+
"peerDependencies": {
611
"@elastic/datemath": "^5.0.3",
7-
"@elastic/eui": "^50.0.0",
8-
"@emotion/react": "^11.8.1",
9-
"@testing-library/jest-dom": "^5.16.2",
10-
"@testing-library/react": "^12.1.3",
11-
"@testing-library/user-event": "^13.5.0",
12+
"@elastic/eui": "^46.1.0",
13+
"@emotion/react": "^11.7.1",
1214
"@types/d3": "^7.1.0",
13-
"@types/jest": "^27.4.1",
14-
"@types/node": "^17.0.21",
15-
"@types/react": "^17.0.39",
16-
"@types/react-dom": "^17.0.13",
15+
"@types/react": "^17.0.20",
16+
"@types/react-dom": "^17.0.9",
1717
"d3": "^7.3.0",
1818
"inter-ui": "^3.19.3",
1919
"moment": "^2.29.1",
2020
"prop-types": "^15.8.1",
2121
"query-string": "^7.1.1",
2222
"react": "^17.0.2",
2323
"react-dom": "^17.0.2",
24-
"react-query": "^3.34.16",
24+
"react-query": "^3.34.12",
25+
"react-router-dom": "6",
26+
"react-scripts": "^5.0.0",
27+
"typescript": "^4.4.2",
28+
"use-query-params": "^1.2.3",
29+
"zod": "^3.11.6"
30+
},
31+
"dependencies": {
32+
"@elastic/datemath": "^5.0.3",
33+
"@elastic/eui": "^46.1.0",
34+
"@emotion/react": "^11.7.1",
35+
"@types/d3": "^7.1.0",
36+
"@types/jest": "^27.0.1",
37+
"@types/node": "^16.7.13",
38+
"@types/react": "^17.0.20",
39+
"@types/react-dom": "^17.0.9",
40+
"d3": "^7.3.0",
41+
"inter-ui": "^3.19.3",
42+
"moment": "^2.29.1",
43+
"prop-types": "^15.8.1",
44+
"query-string": "^7.1.1",
45+
"react-query": "^3.34.12",
2546
"react-router-dom": "6",
26-
"react-scripts": "5.0.0",
27-
"typescript": "^4.6.2",
47+
"react-scripts": "^5.0.0",
2848
"use-query-params": "^1.2.3",
29-
"web-vitals": "^2.1.4",
30-
"zod": "^3.13.4"
49+
"zod": "^3.11.6"
3150
},
3251
"scripts": {
3352
"start": "react-scripts start",
3453
"build": "react-scripts build",
54+
"build:lib": "rimraf ./dist && tsc && rollup -c",
55+
"build:lib-dev": "rimraf ./dist && tsc && rollup -c && yalc publish -f",
3556
"test": "react-scripts test",
3657
"eject": "react-scripts eject"
3758
},
@@ -59,6 +80,43 @@
5980
]
6081
},
6182
"devDependencies": {
62-
"msw": "^0.38.2"
83+
"@babel/core": "^7.17.5",
84+
"@babel/preset-env": "^7.16.11",
85+
"@babel/preset-react": "^7.16.7",
86+
"@rollup/plugin-babel": "^5.3.1",
87+
"@rollup/plugin-commonjs": "^21.0.2",
88+
"@rollup/plugin-json": "^4.1.0",
89+
"@rollup/plugin-node-resolve": "^13.1.3",
90+
"@rollup/plugin-typescript": "^8.3.1",
91+
"@testing-library/jest-dom": "^5.14.1",
92+
"@testing-library/react": "^12.0.0",
93+
"@testing-library/user-event": "^13.2.1",
94+
"msw": "^0.36.8",
95+
"react": "^17.0.2",
96+
"react-dom": "^17.0.2",
97+
"rimraf": "^3.0.2",
98+
"rollup": "^2.68.0",
99+
"rollup-plugin-copy": "^3.4.0",
100+
"rollup-plugin-import-css": "^3.0.2",
101+
"rollup-plugin-svg": "^2.0.0",
102+
"rollup-plugin-svgo": "^1.1.0",
103+
"rollup-plugin-terser": "^7.0.2",
104+
"tslib": "^2.3.1",
105+
"typescript": "^4.4.2"
106+
},
107+
"description": "Web UI for the [Feast Feature Store](https://feast.dev/)",
108+
"repository": {
109+
"type": "git",
110+
"url": "git+https://github.com/feast-dev/feast.git"
111+
},
112+
"keywords": [
113+
"Feast",
114+
"Feature",
115+
"Store"
116+
],
117+
"author": "tony@tecton.ai",
118+
"license": "Apache-2.0",
119+
"bugs": {
120+
"url": "https://github.com/feast-dev/feast/issues"
63121
}
64122
}

ui/public/manifest.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
2-
"short_name": "React App",
3-
"name": "Create React App Sample",
2+
"short_name": "Feast UI",
3+
"name": "Feast UI",
44
"icons": [
55
{
66
"src": "favicon.ico",

0 commit comments

Comments
 (0)