-
Notifications
You must be signed in to change notification settings - Fork 40
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
SWC-7242 #5630
base: develop
Are you sure you want to change the base?
SWC-7242 #5630
Conversation
@@ -0,0 +1,26 @@ | |||
/** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Vite will bundle this file, and the bundled asset will be emitted in the Portal HTML.
This will replace the various UMD bundles that many packages are no longer providing.
@@ -1,6 +1,13 @@ | |||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While it looks like we added a bunch of new dependencies, most of these are not new. With yarn v1, we could directly depend on artifacts from transitive dependencies. pnpm does not let you do this, so we have to add add those previously-transitive dependencies that we currently directly depend on.
"markdown-it-sub": "^2.0.0", | ||
"markdown-it-sup": "^2.0.0", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These were not used. We were already using the -alt
packages, they just were not explicitly listed as dependencies.
"vite": "^6.0.11", | ||
"vite-plugin-node-polyfills": "0.17.0", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add Vite
"dev:codeserver": "mvn clean gwt:run-codeserver", | ||
"dev:watcher": "wait-on tcp:127.0.0.1:9876 && mvn fizzed-watcher:run", | ||
"dev:tomcat": "wait-on tcp:127.0.0.1:9876 && docker pull tomcat:9.0; docker run --name swc-dev --rm -p 8888:8080 -v \"/$(pwd)/target/portal-develop-SNAPSHOT/:/usr/local/tomcat/webapps/ROOT/\" -v \"/$HOME/.m2/settings.xml\":/root/.m2/settings.xml tomcat:9.0", | ||
"dev:tomcat": "wait-on tcp:127.0.0.1:9876 && docker pull tomcat:9.0; docker run --name swc-dev --rm -p 8888:8080 -v \"/$(pwd)/target/portal-develop-SNAPSHOT/:/usr/local/tomcat/webapps/ROOT/\" -v \"/$HOME/.m2/settings.xml\":/root/.m2/settings.xml -e CATALINA_OPTS=\"-Dorg.sagebionetworks.web.client.dev.mode=true\" tomcat:9.0", | ||
"dev:vite": "vite dev", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a script that runs the Vite dev server (live reloading of assets bundled by Vite)
"dev:codeserver": "mvn clean gwt:run-codeserver", | ||
"dev:watcher": "wait-on tcp:127.0.0.1:9876 && mvn fizzed-watcher:run", | ||
"dev:tomcat": "wait-on tcp:127.0.0.1:9876 && docker pull tomcat:9.0; docker run --name swc-dev --rm -p 8888:8080 -v \"/$(pwd)/target/portal-develop-SNAPSHOT/:/usr/local/tomcat/webapps/ROOT/\" -v \"/$HOME/.m2/settings.xml\":/root/.m2/settings.xml tomcat:9.0", | ||
"dev:tomcat": "wait-on tcp:127.0.0.1:9876 && docker pull tomcat:9.0; docker run --name swc-dev --rm -p 8888:8080 -v \"/$(pwd)/target/portal-develop-SNAPSHOT/:/usr/local/tomcat/webapps/ROOT/\" -v \"/$HOME/.m2/settings.xml\":/root/.m2/settings.xml -e CATALINA_OPTS=\"-Dorg.sagebionetworks.web.client.dev.mode=true\" tomcat:9.0", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add environment variable org.sagebionetworks.web.client.dev.mode=true
, which tells the servlet that we are running in dev mode and to use the Vite dev server.
// ViteManifestProviderImpl requires ServletContext, which cannot be injected, so we create the singleton here. | ||
private ViteManifestProvider viteManifestProviderSingleton; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a better way to do this?
filter("/*").through(SSLFilter.class); | ||
bind(SSLFilter.class).in(Singleton.class); | ||
|
||
filter("*").through(HtmlInjectionFilter.class); | ||
bind(HtmlInjectionFilter.class).in(Singleton.class); | ||
|
||
filter("/*").through(GWTCacheControlFilter.class); | ||
bind(GWTCacheControlFilter.class).in(Singleton.class); | ||
|
||
filter("/js/*").through(GWTAllCacheFilter.class); | ||
filter("/images/*").through(GWTAllCacheFilter.class); | ||
filter("/research/*").through(GWTAllCacheFilter.class); | ||
bind(GWTAllCacheFilter.class).in(Singleton.class); | ||
|
||
filter("/*").through(JavaScriptContentTypeFilter.class); | ||
bind(JavaScriptContentTypeFilter.class).in(Singleton.class); | ||
|
||
filter("/*").through(HSTSFilter.class); | ||
bind(HSTSFilter.class).in(Singleton.class); | ||
|
||
filter("/*").through(CORSFilter.class); | ||
bind(CORSFilter.class).in(Singleton.class); | ||
|
||
filter("/*").through(XFrameOptionsFilter.class); | ||
bind(XFrameOptionsFilter.class).in(Singleton.class); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed filters from web.xml and added them here, preserving the filter order. This allows us to inject dependencies into the filter objects.
src/main/java/org/sagebionetworks/web/server/StackEndpoints.java
Outdated
Show resolved
Hide resolved
private void addCdnEndpoint( | ||
Map<String, String> dataModel, | ||
HttpServletRequest request | ||
) { | ||
String origin = request.getHeader("origin"); | ||
if (origin != null && CDN_ORIGINS_REGEX.matcher(origin).matches()) { | ||
dataModel.put(CDN_ENDPOINT_KEY, "//cdn-" + request.getHeader("origin")); | ||
} else { | ||
dataModel.put(CDN_ENDPOINT_KEY, ""); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved logic to determine the CDN endpoint to this filter, instead of JavaScript in the HTML file itself. Logic should be the same.
/** | ||
* Adds Vite imports to the data model based on the request origin. | ||
* This must be called AFTER the CDN_ENDPOINT_KEY is added to the data model | ||
* @param dataModel | ||
*/ | ||
private void addViteImports(Map<String, String> dataModel) { | ||
boolean isDev = "true".equals(System.getProperty(IS_DEV_MODE)); | ||
if (isDev) { | ||
dataModel.put( | ||
VITE_IMPORTS_INJECTION_KEY, | ||
ViteHTMLProvider.getViteDevelopmentHTML(VITE_IMPORTED_FILES) | ||
); | ||
} else { | ||
dataModel.put( | ||
VITE_IMPORTS_INJECTION_KEY, | ||
ViteHTMLProvider.getViteProductionHTML( | ||
VITE_IMPORTED_FILES, | ||
viteManifestProvider.getManifest(), | ||
dataModel.get(CDN_ENDPOINT_KEY) + "/generated/vite/" | ||
) | ||
); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Injects scripts for the assets bundled by Vite
src/main/webapp/Portal.html
Outdated
@@ -10,7 +10,7 @@ | |||
|
|||
<meta | |||
http-equiv="Content-Security-Policy" | |||
content="default-src 'self' data: blob: 'unsafe-inline' 'unsafe-eval' *.synapse.org *.sagebase.org *.googleapis.com *.gstatic.com *.googletagmanager.com cdn.statuspage.io s3.amazonaws.com www.google-analytics.com kh896k90gyvg.statuspage.io *.youtube.com *.rstudio.com *.google.com *.shinyapps.io *.smartsheet.com sagebionetworks.jira.com 127.0.0.1:9876 esm.sh; frame-ancestors 'self' https://*.synapse.org localhost; img-src * data: blob:; connect-src https://* http://127.0.0.1:8888" | |||
content="default-src 'self' data: blob: 'unsafe-inline' 'unsafe-eval' *.synapse.org *.sagebase.org *.googleapis.com *.gstatic.com *.googletagmanager.com cdn.statuspage.io s3.amazonaws.com www.google-analytics.com kh896k90gyvg.statuspage.io *.youtube.com *.rstudio.com *.google.com *.shinyapps.io *.smartsheet.com sagebionetworks.jira.com 127.0.0.1:9876 esm.sh localhost:5173; frame-ancestors 'self' https://*.synapse.org localhost; img-src * data: blob:; connect-src https://* http://127.0.0.1:8888 http://localhost:5173 ws://localhost:5173" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Vite dev server runs on localhost:5173
, need to add to CSP to allow downloading scripts, connecting over HTTP and WebSocket protocols
var cdnEndpoint = '//cdn-' + location.hostname + '/' | ||
var processEnvironment = 'production' | ||
var synapseOrgRegex = /(www|staging|tst)\.synapse\.org$/ | ||
|
||
if (!synapseOrgRegex.test(location.hostname)) { | ||
cdnEndpoint = '/' | ||
processEnvironment = 'development' | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Logic for CDN moved to the HtmlInjectionFilter. Vite should handle the processEnvironment
logic in the bundling phase.
let reactPath, reactDomPath | ||
|
||
if (processEnvironment === 'production') { | ||
reactPath = cdnEndpoint + 'generated/react.production.min.js' | ||
reactDomPath = cdnEndpoint + 'generated/react-dom.production.min.js' | ||
} else { | ||
reactPath = cdnEndpoint + 'generated/react.development.js' | ||
reactDomPath = cdnEndpoint + 'generated/react-dom.development.js' | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
React/ReactDOM scripts removed, now handled by Vite
loadJs(cdnEndpoint + 'generated/plotly.min.js') | ||
loadJs(cdnEndpoint + 'generated/create-plotly-component.min.js') | ||
loadJs(cdnEndpoint + 'generated/universalCookie.min.js') | ||
loadJs(cdnEndpoint + 'generated/synapse-react-client.production.min.js') // We don't load SRC's scss because we include it in our own compiled scss |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
synapse-react-client import removed, now handled by Vite
loadJs(reactPath) | ||
loadJs(reactDomPath) | ||
loadJs(cdnEndpoint + 'generated/material-ui.production.min.js') | ||
loadJs(cdnEndpoint + 'generated/react-transition-group.min.js') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
react-transition-group bundle removed because it is unused
loadJs(cdnEndpoint + 'generated/material-ui.production.min.js') | ||
loadJs(cdnEndpoint + 'generated/react-transition-group.min.js') | ||
loadJs(cdnEndpoint + 'generated/prop-types.min.js') | ||
loadJs(cdnEndpoint + 'generated/react-measure.js') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
react-measure bundle removed because it is unused
loadJs(cdnEndpoint + 'generated/pica.min.js') | ||
loadJs(reactPath) | ||
loadJs(reactDomPath) | ||
loadJs(cdnEndpoint + 'generated/material-ui.production.min.js') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed, now handled by Vite
@@ -6,94 +6,10 @@ | |||
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" | |||
version="2.5" | |||
> | |||
<filter> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Filter instantiation moved to PortalServletModule so dependencies can be injected into these.
- Add Vite integration to bundle and emit assets - Update HtmlInjectionFilter to inject a CDN endpoint and Vite asset tags - Update Portal.html to use injected CDN endpoint and injected Vite asset tags - Add script that bundles React, ReactDOM, ReactQuery, SRC, MUI components and adds them to the window object (replacing UMD scripts in Portal.html) - Migrate from yarn to pnpm - Update dependencies to match those that are actually used (required by pnpm) and remove some that are unused.
@@ -5,7 +5,7 @@ env: | |||
BUILD_ARTIFACT_NAME: swc-war | |||
BUILD_DIR: target | |||
BUILD_NAME: portal-develop-SNAPSHOT.war | |||
NODE_VERSION: 18.16.0 | |||
NODE_VERSION: 22 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update Node to 22 (latest LTS) since it includes the latest version of corepack, which we will use to install pnpm.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great to me! It'd be great to run e2e tests locally if possible to confirm that core functionality is unaffected.
- Fix e2e tests - Fix ReactDOM/ReactDOMClient distinction -- ReactDOMClient only contains `createRoot` - Prefer `window` over `self` - Move Vite compilation to `compile` phase -- it does not get copied over if we wait until the `package` phase, even though we don't need it until then.
Depends on a synapse-react-client release containing Sage-Bionetworks/synapse-web-monorepo#1565