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

Enable multi page app #88

Merged
merged 14 commits into from
Nov 2, 2023
Merged

Enable multi page app #88

merged 14 commits into from
Nov 2, 2023

Conversation

elturpin
Copy link
Contributor

Hello I recently discovered this project along with Vite and I wanted to use it for a personal application.

Unfortunately, it cannot manage multiple entry points like Vite, as mention here #87.

I have made some investigation and find a way to serve multiple entry points: let's assume this file organization (this is the one picked from Vite documentation: https://vitejs.dev/guide/build.html#multi-page-app):

├── package.json
├── vite.config.js
├── index.html
├── main.js
└── nested
    ├── index.html
    └── nested.js
  • http://server:port/ -> will serve /index.html
  • http://server:port/plop -> will also serve /index.html
  • http://server:port/nested/ -> will serve /nested/index.html
  • http://server:port/nested/plop -> will serve /nested/index.html
  • http://server:port/nested/plop/ -> will try to serve /nested/plop/index.html but will fail

Additionally, I added a way to respond a 404 status if no index is found. For the moment it crashes the dev server.

I completed the tests with all the new cases.

Tell me if you think it can be improved or anything.

@elturpin elturpin changed the title Enable multip page Enable multi page app Oct 27, 2023
@szymmis
Copy link
Owner

szymmis commented Oct 28, 2023

Hi @elturpin, thanks a lot for your contribution. I'll take a look at your code as soon as I find a minute of free time to do so. Also, great to hear that you've implemented tests for that feature.

Copy link
Owner

@szymmis szymmis left a comment

Choose a reason for hiding this comment

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

Hi again @elturpin,
First of all, thanks a lot for spending your time to take on this pretty big feature. You've did a lot of research that was needed for that, like how does Vite make it work etc., thank you.

I've reviewed the code and I see a problem with it breaking the current behaviour, so we need to change that. The PR comments should be descriptive enough for you to start, but if you have any questions feel free to ask. Also, if you don't plan to continue work on it, let me know, but if you do, I will be happy to help you.

I also wanted to say thank you for writing tests cases, great job.

src/main.ts Outdated
Comment on lines 210 to 213
const template = fs.readFileSync(
path.join(config.root, basePath, "index.html"),
"utf8"
);
Copy link
Owner

Choose a reason for hiding this comment

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

Right now if the file doesn't exist, an error is thrown and that breaks client-side routing.
When you go to /some/path/nested, and file that it looks for (for example /some/path/index.html) doesn't exist, it should fallback to /some/index.html and if that also doesn't exist, the root index.html.

That way you can have:

  • /admin/my/secret/route -> /admin/index.html is displayed and client-side routing is used to render correct components for /my/secret/route
  • /whatever/other/route -> index.html is served

I suggest creating a function that will try to sequentially find a nested index html file for a route.
For the /admin/my/secret/route path the process would look like this:

  • admin/my/secret/index.html
  • admin/my/index.html
  • admin/index.html
  • index.html

So these files would be selected from top to bottom, if one doesn't exist, try to select another one. This behaviour seems to mimic what Vite does and also keeps client-side routing intact.

src/main.ts Outdated
const html = await server.transformIndexHtml(req.originalUrl, template);
res.send(getTransformedHTML(html, req));
} catch (e) {
res.sendStatus(404);
Copy link
Owner

Choose a reason for hiding this comment

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

When looking for index.html file to serve will fail, you can just let it throw an 500 error, so don't try-catch this block at all.

Alternatively, you can invoke next() and pass an e error object as a parameter, that way you give an opportunity for other handlers to do it's job. For example, someone could have a middleware that serves beautiful 404 page when that error comes, but in your case you would make that impossible by closing the request too early.

See this for more information.

@szymmis szymmis linked an issue Oct 31, 2023 that may be closed by this pull request
@elturpin
Copy link
Contributor Author

Thanks a lot for the reviews !

I am very pleased to help you so i am glad to resolve the issues you pointed out.

I will work on it very soon.

@elturpin
Copy link
Contributor Author

elturpin commented Nov 1, 2023

Hi @szymmis

I take some time to work on the feature today.

I managed to implement the behavior of falling back to the closest index toward the root directory.
For the case where no root index exists, I just use the next function to let followings handlers do their job.

As previously I updated/added test cases.

Again, tell me if you think of other improvements.

Copy link
Owner

@szymmis szymmis left a comment

Choose a reason for hiding this comment

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

Looks great! 🚀 Thanks a lot for your contribution.

The only change I've made was to inline getBasePath function into findClosestIndexToRoot as it is not really usable outside of it, so we declutter code a little bit.

One last thing to do is to document this feature and release a new version 0.11.0. I will try to do this as soon as possible.

Thanks a lot again, great job!

@szymmis szymmis merged commit 0c4b032 into szymmis:master Nov 2, 2023
@elturpin
Copy link
Contributor Author

elturpin commented Nov 2, 2023

Perfect !!

It was a pleasure to give some help and I want to say that your code base is very nice to develop with.

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

Successfully merging this pull request may close these issues.

Multiple entry points for multi page app
2 participants