-
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
Consider serving and transforming all HTML files, rather than just limiting it to index files #110
Conversation
Removing staticFilePath check, as vite.middlewares are now mounted before the injectViteIndexMiddleware function. This adjustment is made because the staticFilePath check doesn't provide any additional benefits, aside from blocking requests like /index.html on the development server.
Allowing requests for html files to be transformable. This is achieved by skipping files with .htm or .html in the Static Middleware, allowing them to be handled by the IndexMiddlewares.
Previously, my implementation involved checking if a file ended with the html extension and then verifying its existence. If the file didn't exist, it would trigger next(), eventually resulting in a 404 error. However, I now realize that this approach does not align with the current methodology. The updated approach is to return the closest index file if the requested file does not exist.
These tests will ensure serving and transformation of .html and .htm files when request explicitly includes filenames.
During my testing with .htm files, I discovered that Vite lacks support for this file format. I encountered the following issues:
Hence, we should also avoid transforming .htm files. In that case, the objectives of this pull request would be:
|
Hi @rmhaiderali, thanks for your work. Sorry to say that but I don't really like the idea of serving HTML files using their name. What I do agree though is that it might be misleading to have something.html files served but not transformed. That's why I do believe that html files should not be served as static files in production mode, like they are not currently served in development. Let me know what do you think. |
Hello @szymmis, I completely agree with your perspective on how things should ideally work—for instance, using Moreover, regarding subpaths, developers can leverage frontend routing libraries to handle explicit file name requests. For example, if a developer is handling subpaths, they likely have a routing library in place to manage navigation within their application. By implementing a redirection strategy within the routing library, developers can ensure that all unmatched requests, including On the other hand, if the serving of HTML files is disabled, a request to By serving and transforming all HTML files, we provide developers with enhanced control to effectively manage specific cases and allowing developers to maintain control over the application's routing behavior. Let me know if you have any further thoughts or considerations on this approach. |
Here is the reference where we can see vite is doing it in similar way. |
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.
I'm always a fan of aligning vite-express with how Vite works and I understand your approach. If there is some edge case it might fix, I think it is indeed better to do it that way instead of just not serving html files as static files at all.
Also big thank you for cleaning up some unnecessary stuff. You are doing a really great job here at vite-express, thanks a lot!
src/main.ts
Outdated
const indexPath = findFilePath(req.path, config.root); | ||
if (indexPath === undefined) return next(); | ||
|
||
const template = fs.readFileSync(indexPath, "utf8"); |
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.
I feel like we need to find more meaningful name instead of findFilePath
for that function. I'm not sure how those HTML files should be called, templates maybe?
So it would be called findTemplateFilePath
or even readTemplate
and it would replace those couple of lines (obviously after adding this functionality to the function itself 😅)
const indexPath = findFilePath(req.path, config.root); | |
if (indexPath === undefined) return next(); | |
const template = fs.readFileSync(indexPath, "utf8"); | |
const template = readTemplate(req.path, config.root); | |
if (!template) return next(); |
What do you think about that?
src/main.ts
Outdated
const indexPath = findFilePath(req.path, config.root); | ||
if (indexPath === undefined) return next(); | ||
|
||
const template = fs.readFileSync(indexPath, "utf8"); | ||
let html = await server.transformIndexHtml(req.originalUrl, template); | ||
|
||
try { | ||
html = await getTransformedHTML(html, req); |
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.
What if we include the precise file path of the html file as an input for the getTransformedHTML
function? This could assist users in distinguishing between various files, particularly when working with multipage apps. Additionally, I'm uncertain about the optimal parameter ordering for the getTransformedHTML
function.
const indexPath = findFilePath(req.path, config.root); | |
if (indexPath === undefined) return next(); | |
const template = fs.readFileSync(indexPath, "utf8"); | |
let html = await server.transformIndexHtml(req.originalUrl, template); | |
try { | |
html = await getTransformedHTML(html, req); | |
const templateFilePath = findTemplateFilePath(req.path, config.root); | |
if (templateFilePath === undefined) return next(); | |
const template = fs.readFileSync(templateFilePath, "utf8"); | |
let html = await server.transformIndexHtml(req.originalUrl, template); | |
try { | |
html = await getTransformedHTML( | |
html, | |
req, | |
templateFilePath.slice(config.root.length), | |
); |
@szymmis what are your thoughts on this? |
Sorry for me being so slow to respond @rmhaiderali. Answering your question: How would you want to change I guess we could merge You don't need to do that much of a refactor, you can just change the function name or even leave it as is, because I'm planning to revisit the code in the near future with a little refactoring. |
async function getTransformedHTML(
html: string,
req: express.Request,
htmlFilePath: string,
) {
return Config.transformer ? Config.transformer(html, req, htmlFilePath) : html;
} The primary objective was to supply a precise HTML file path to a transformer function, enabling users to differentiate between various HTML files when dealing with multi-page applications. Subsequently, users can utilize this file path to apply distinct transformations to each HTML file or choose to apply transformations to specific files while excluding others. For example if user have this structure:
And they want to transform only ViteExpress.config({
transformer: (html, req) => {
if(req.path.startsWith("/nested1/nested2/nested3/nested4/")){
// transform
}
else if(req.path.startsWith("/nested1/nested2/nested3/")){
// unnessary check but required
}
else if(req.path.startsWith("/nested1/nested2/")){
// transform
}
else if(req.path.startsWith("/nested1/")){
// unnessary check but required
}
else if(req.path.startsWith("/")){
// transform
}
}
}); But with this change they can do it like this: ViteExpress.config({
transformer: (html, req, htmlFilePath) => {
if(htmlFilePath === "/nested1/nested2/nested3/nested4/index.html"){
// transform
}
else if(htmlFilePath === "/nested1/nested2/index.html"){
// transform
}
else if(htmlFilePath === "/index.html"){
// transform
}
}
}); |
@szymmis, I've made changes to the variable/function names. I believe we can postpone adding filePath to the transformer function for now, and proceed with merging this pull request. Thank you very much for your time and cooperation ❤️ |
Okay I see now, but I think if you use regex instead of I don't want to bloat the transformers in any way if there is an information already available in the request object. Also, your change would somehow tie request handling to how vite-express internally works with the HTML files etc. which is also something I don't like. Nevertheless, after your changes to the naming everything looks great, so we can merge it! 🎉 |
This pull request addresses two main issues.
Firstly, it resolves the problem of not serving HTML files in dev mode when the request explicitly includes filenames like /index.html or /main.html.
Secondly, in production mode, when specifically requesting /index.html, the HTML transformer function was being skipped, potentially causing issues as described in issue #109.
Additionally, this pull request will enable users to use the .htm extension in addition to .html. After applying this pull request, transformer functions can now be used with any file ending with .html or .htm.
This is achieved by skipping files with .htm or .html extensions in the Static Middleware Function to ensure proper serving and transformation of these files.