Closed emmanuelbernard closed 2 years ago
Yes, please provide more details, I don't understand why putting static files in one folder would lead to problems with two top level projects.
Being not an expert of front end frameworks and not using maven for quite a long time I'm facing difficulties to find and easy and clean way to integrate in a single build a React JS project with a Protean one in order to deploy it on OpenShift. Maybe having a tutorial with an example on how to integrate a JavaScript framework with Protean could be beneficial.
I'm no expect either but I support React "default" structure would come with npm, babel to change your JS, ESLint and other tool chain. Do you want all of that in META-INF/resources
?
Have anyone investigated this, https://github.com/eirslett/frontend-maven-plugin? Maybe we can provide a separate Protean project that leverages this.
That's the way Spring recommends apparently, https://spring.io/guides/tutorials/react-and-spring-data-rest/.
With the Frontend Maven plugin you could at least integrate the React code into the Maven directory structure and get it to build. You'd have to adjust the configuration to ensure the "build" result goes into the target META-INF/resources
of course.
The downside I see to this, something that happens a lot within RH, is that it's very Java/Maven centric (both in the build process and the directory structure it imposes), which is just not how a lot of developers out there will be working (nor will they want to). So to them it would probably be more useful if we could come up with something that sees frontend and backend as separate projects handled be different people/teams.
How to link the two I'm not sure. Perhaps have a single project with a Java/Maven backend folder and a React/JS frontend folder and have a toplevel Maven pom that builds both and creates the final result?
I personally like the toplevel Maven project with 2 sub projects one for the backend (Protean) and the other for the frontend (React JS) and it is how I structured my toy project.
I don't recall doing an all in one (front and back), but I have used Frontend Maven plugin to create a website that can be run from a Thorntail uber jar: https://github.com/kenfinnigan/ejm-samples/tree/master/chapter2/ui
It only requires some tweaks to tell webpack to output the generated HTML into /target/{app-name} and then it just becomes static resources
@quintesse so I do see your point and for a Java centric person, merging the two projects under one maven module structure is fine and we can work on a way where the React Hot Deploy approach integrates with Protean rendering these files.
In the case of two separate projects like Andrea did, it's assuming it's two teams really or at least that the output of the front end is copied by the CLI "on a regular basis" in the backend serving. That works but it means no fast development cycle. Maybe that's ok.
@emmanuelbernard I think it can work if you combine what @kenfinnigan mentioned with a way to include the frontend project into the backend somehow. You could either just expect it to be in the same parent folder, but perhaps using something like git modules to include the frontend directly into the backend project might be a better option. That way you could have a standard React project that works normal in every way but if you run the backend build it will run the frontend build while oeverriding the output path. (Or you just copy the files yourself)
If I understand correctly, the issue is figuring out how to best bundle and serve static files created by an external tool (angular-cli, etc.) from Quarkus? Maybe I'm missing something here but why use Quarkus in this scenario? If it's because the backend is also developed using Quarkus, wouldn't it make more sense to develop the projects separately (and even deploy them in different pods) anyway? Presumably, there are better solutions to serve static files for a JS/TS frontend, are there?
What you describe is a valid and clean architecture. But for the not quite full on microservices person, an all in one app with quarkus:dev experience is really cool.
Editing a UI screen + a Hibernate entity, REST endpoint hit save and look is what I'm looking for.
Very good examples of what you describe can be generated with the help of JHipster. It would be great for the Quarkus project to be integrated with the JHipster generator.
So either you put the front-end inside the quarkus project and let the maven front-end plugin generate the site, or you have a separate project and let npm tooling (or front-end plugin) put the output in the quarkus project. But for both of these solutions you would need the quarkus:dev
command to also watch the target folder for changes, right? Does that sum it up?
Actively reviewing a similar challenge where using a quarkus application that is in need of a UI, that based on any large/enterprise organization may mandate react+their styling / angular+their styling / some-other-nodejs-based-solution-specific-to-environment-working-in.
Having a 'developer joy' example that interacts with a nodejs-built-static-asset UI (reactjs my preference), such as with the maven-front-end plugin and how to use quarkus:dev to watch/update on changes would be great, particularly for scenarios where the ideal would be an intuitive start-small-move-fast with a single project before getting buy-in to make it larger scale and break it out into separate projects with their own lifecycles (by project, I really mean repository, if its two maven reactor projects under a single parent that has a one-command-line devbuild, great).
So most modern frontend web frameworks provide their own development server. We need to take advantage of this, as we also want to allow for hot reload in the web framework. This means there are two apprpaches we can use:
1) Map JAX-RS under a specific path (/api), then configure the frontend server to proxy /api to quarkus. 2) Add the ability to change the 'DefaultServlet' to a proxy servlet, that proxies requests to the frontend development server rather than serving static resources directly.
I think 1) is the way to go, as we can do this at the moment, so it is mostly just a case of documenting the workflow, and possibly adding some additional user friendliness (e.g. auto starting the dev server, auto redirecting to the correct port).
How does quarkus treats the src/main/resources/node_modules
-folder (which can have a vaste amount of data in different formats(js, css, html, txt, ..)? Will it be scanned and included all over the time while (hot) compiling the project? Should such a folder be better placed on the root-path of the project instead of src/main/resources
-folder? Where should all the client config files be placed (e.g., .bacelrc, gulpfile.js, webpack.js, package.json, tsconfig.js, ..)? Would it be better to have a special "marker folder" where all the client related stuff should be placed (something like src/main/resources/webapp/WEB_INF
) seperated by stuff only needed during development (e.g., node_modules, webpack.js, package.json) and stuff needed to be packaged in the compiled project?
@nimo23 that is why I put organised the frontend project into 2 modules one for the frontend and one for the backend. That way only a pom.xml
is needed extra in the frontend project (that also builds with the maven frontend plugin and copies the project into src/main/resources/
) and using a proxy you can still to npm start
and have hot replace
@edewit So we need to watchers: one for quarkus:dev (server code) and the other for the frontend-code (for example, by webpack hot redeploy).
Is it possible to bind tasks by pom.xml to quarkus:dev to watch/rebuild the frontend-module also on any change? If I got it right, I must rebuild the frontend-project on every change by myself to get it copied to quarkus-project/src/main/resources/
.
While developing, the frontend-code (react) is bound to the backend-code (quarkus) by a proxy. So every change on the frontend-code is rebuild by its frontend-watcher while every change on the backend-code is rebuild by quarkus:dev. So there is no need to put the frontend-code in src/main/resources/
on every change.
right it's not needed on every change to put the frontend-code in src/main/resources
only when you do a maven production build will that be done.
@dreab8 was pointing to me that he worked on a project with Protean. It had classical Java backend and a React front end. He wanted Protean to serve the front end content but having to put the react or angular directory structure under
META-INF/resources
is not convenient and would serve the whole project. In his situation he had two top level projects. But we could envision a subproject of protean with the react structure possibly.@dreab8 can you add more info on the pains you felt and how you think it could work. @stuartwdouglas could you put down your ideas in this issue as well. You had some from last year on how to serve the front end as easily as possible.
In the npm/node world you don't want to watch files inside of the node_modules directory.
A popular thing I've seen in the React community is NextJS aka server-side rendering (different routing ability). You may be able to glean from their patterns and structure to get an idea. Maybe there should be an extension for each web framework (angular, reactjs(clientside rendering), nextjs/reactjs(serverside rendering) etc.)
I also heard the folk at GraalVM has a version of NodeJS having the GraalVM inside able to run Java code and Node/Npm(javascript) code.
But yea, I'm looking forward to this idea/ability. Decoupling is good, but this option just allows you to develop faster for small/medium projects.
btw we have a related blog article: https://quarkus.io/blog/quarkus-and-web-ui-development-mode/
For code.quarkus.io, we have a react frontend: https://github.com/quarkusio/code.quarkus.io
src/main/frontend
as a standalone react appI think the dev mode could be improved by integrating it in the frontend maven plugin because it's the part responsible of dealing with yarn or npm.
Maybe we could have some kind of extension to make it easier and bind everything together?
Is it possible that we solve the problem by writing a small maven plugin that replaces the Makefile and spins up the servers for you at dev time?
Just for completeness, this weekend I finally managed to find the time to write yet another blog post about SPA frontend and Quarkus backend integrations. This is an approach I've been using for years with other frameworks, but I haven't seen it documented anywhere.
The main issue with building the frontend into the META-INF/resource
directory approach is that front-end routers won't work as expected. This means that if you access http://localhost:8080/front-end/nested/path
your index.html
file won't be found and your front-end application won't load.
btw we have a related blog article: https://quarkus.io/blog/quarkus-and-web-ui-development-mode/
In Kabir's blog post, the issue is tackled using a Servlet or a Filter, which works great.
In my case, I'm just using a standard JAX-RS endpoint definition.It's a similar solution to that of the servlet/filter, but IMHO it allows more flexibility and control regarding the frontend build and assembly.
With respect to the frontend build, I'm using the standard Maven resources and exec plugin.
Regarding hot-reloading / Development mode, I find it quite easier running each application with its own dev server and configuring CORS in Quarkus. You can read more about this in the article too.
@edewit Why is https://github.com/edewit/quarkus-quickstarts/tree/react-example/react-rest not more available in https://github.com/quarkusio/quarkus-quickstarts?
@nimo23 it's an open PR https://github.com/quarkusio/quarkus-quickstarts/pull/286 leave a +1 on it ;)
Quinoa 1.0.0 has been released. We now have a elegant integrated way to deal with web frameworks: https://github.com/quarkiverse/quarkus-quinoa
I think most of the concerns evoked in this issue are solved using Quinoa:
quarkus.quinoa.ui-dir
is on the disk during dev and CI). Default is src/main/webui
META-INF/resources
but served by Quinoa using another Vertx Route, which is the same in term of performance but gives the ability to have SPA routing: https://quarkiverse.github.io/quarkiverse-docs/quarkus-quinoa/dev/index.html#quarkus-quinoa_quarkus.quinoa.enable-spa-routingLink to the doc: https://quarkiverse.github.io/quarkiverse-docs/quarkus-quinoa/dev/index.html
@dreab8 was pointing to me that he worked on a project with Protean. It had classical Java backend and a React front end. He wanted Protean to serve the front end content but having to put the react or angular directory structure under
META-INF/resources
is not convenient and would serve the whole project. In his situation he had two top level projects. But we could envision a subproject of protean with the react structure possibly.@dreab8 can you add more info on the pains you felt and how you think it could work. @stuartwdouglas could you put down your ideas in this issue as well. You had some from last year on how to serve the front end as easily as possible.