When bundling and serve multiple entry files, / index.html
can not be accessed with localhost:1234/
However, you can access it with localhost: 1234 / index.html
//- src/index.pug
h1 hello world!
//- src/sub.pug
h1 sub page!
$ parcel 'src/**/*.pug'
When accessing localhost:1234/
, "hello world!" is displayed
Accessing localhost:1234/
will display empty HTML
<html>
<head></head>
<body></body>
</html>
However, accessing localhost: 1234 / index.html
will display the page correctly
I do not know, but when accessed with /
we have to make sure to check the existence of / index.html
| Software | Version(s) |
| ---------------- | ---------- |
| Parcel |v1.8.1|
| Node |v8.11.1|
| npm/Yarn |v6.0.0/v1.5.1|
| Operating System |MacBook Pro (High Sierra)|
This is because it currently checks for an entrypoint and multiple entrypoints works with a html entrypoint thats being created in the background as a main asset to link all assets to.
This is an empty file and therefore it shows you that file as mainasset
Sent with GitHawk
Thank you!
This was a specification
Will this be fixed?
It would be helpful to have index.html served from / and any other entry points served without .html.
So, page1.html would be resolved by visiting /page1.
Is there a way to create URL rewrites for the server locally in a project?
@lucaseverett This is unrelated to the issue, but I'm fairly sure there is already an issue concerning this. It's currently not possible, feel free to open a PR to implement this, it should be fairly easy to do this
I've got a working solution for this (as explained in #1778) and can PR if this is agreeable.
Essentially, it enhances the respond
method by looking for indexes (with a method replacing sendIndex
called findIndex
), looking for the main bundle as it does now, failing that looking for an HTML file called index.html
.
function respond() {
let {pathname} = url.parse(req.url);
if (bundler.error) {
return send500(bundler.error);
} else if (
!pathname.startsWith(bundler.options.publicURL) ||
path.extname(pathname) === ''
) {
const index = findIndex(pathname)
if (index) {
req.url = `/${path.basename(index)}`;
serve(req, res, send404);
}
else {
send404();
}
} else {
// Otherwise, serve the file from the dist folder
req.url = pathname.slice(bundler.options.publicURL.length);
return serve(req, res, send404);
}
}
function findIndex(pathname) {
// If the bundle is HTML, send that
if (bundler.mainBundle.type === 'html') {
return bundler.mainBundle.name;
}
else if (pathname === bundler.options.publicURL) {
// if the pathname is empty, look for files named index.html in the bundle and send back the first one. If there's nothing, return null;
const indexes = Array.from(bundler.mainBundle.childBundles).filter((asset) => path.basename(asset.name) === 'index.html');
return indexes[0].name;
}
return null;
}
Has there been any progress on this issue? It is a very useful feature.
Started working on a pull request for this issue
I'm experiencing some test errors, which I asked about on Spectrum. Once those are resolved I can add the pull request. It is using @MathieuLoutre's fix (here) and not setting index to true as suggested here if that would be the better option I can change that in the PR, the tests for it stay the same.
FWIW: This issue also occurs when you just have a single .tsx entry point (parcel src/index.tsx
) as well
Same happened here when parcel *.html
.
That actually confused my colleague and thought the computer was under the weather lol
It would be nice to solve this issue. It would avoid any confusion in the future.
Is there any news on this issue?
Looks like lots of people requesting this feature, any word on whether there's even a workaround to solve this?
Same here. Any updates?
Same here, just ran into this, with the whole team confused as to what happened, when the second entry point was first added.
In the meantime, I have this workaround set up:
// run-parcel.js
const Bundler = require('parcel-bundler');
const express = require('express');
const bundler = new Bundler(['src/index.html', 'src/login.html', 'src/logout.html']);
const app = express();
app.get('/', (req, res, next) => {
req.url = '/index.html';
app._router.handle(req, res, next);
});
app.use(bundler.middleware());
const port = Number(process.env.PORT || 1234);
app.listen(port);
console.log(`listening at http://localhost:${port}`);
then run node run-parcel.js
instead of parcel src/*.html
.
Looking forward to this feature!
I ended up writing a local plugin as a bandaid, until we get a legit fix. It uses the same modules included in Parcel v1. Only gotcha is you have to use the watch
command to trigger it. Here's an example of what it looks like - ymmv:
parcel watch [entries] --serve
parcel watch [entries] --serve --open
const serveStatic = require("serve-static"); // included in parcel v1
const { createServer } = require("http");
module.exports = (bundler) => {
let server = null; // prevent from restarting on rebundle
const openBrowser = process.argv.includes("--open");
const useServer = process.argv.includes("--serve");
bundler.on("bundled", () => {
if (useServer && !server && bundler.options.watch) {
server = startServer(bundler.options.outDir, 8080, openBrowser);
}
});
}
function startServer(outDir, port, openBrowser) {
const serve = serveStatic(outDir, { extensions: ["html"] });
// 404 handler
const redirect = (res) => {
res.writeHead(302, { Location: "/404" });
res.end();
};
// request handler
const handler = (req, res) => {
serve(req, res, () => redirect(res));
};
// start server
return createServer(handler).listen(port, () => {
// optional if you want to open the browser (included in parcel v1)
if (openBrowser) require("opn")(`http://localhost:${port}`);
});
}
Most helpful comment
In the meantime, I have this workaround set up:
then run
node run-parcel.js
instead ofparcel src/*.html
.