parcel-bundler / parcel

The zero configuration build tool for the web. 📦🚀
https://parceljs.org
MIT License
43.38k stars 2.26k forks source link

Running dev server on multiple entries only serves the first one since 2.9.0 #9061

Closed truesteps closed 1 year ago

truesteps commented 1 year ago

🐛 bug report

🎛 Configuration (.babelrc, package.json, cli command)

parcel configuration

{
  entries: ['./300x300/index.html', './300x600/index.html'],
  defaultConfig: path.resolve('./.parcelrc'),
  serveOptions: {
      publicUrl: '/',
      port: 3000
  },
  logLevel: 'error',
  shouldDisableCache: true,
  shouldAutoInstall: false,
  shouldContentHash: false,
  shouldBuildLazily: false,
  shouldProfile: false,
  defaultTargetOptions: {
      publicUrl: '/',
      sourceMaps: true,
      shouldOptimize: true,
      shouldScopeHoist: false,
      distDir: './dist/',
  }
}

.parcelrc

{
  "extends": "@parcel/config-default",
  "optimizers": {
    "*.{html,xhtml}": [
        "...",
        // custom optimizer we use in-house, it just appends extra scripts into the finished bundle
        "parcel-optimizer-imagelance"
      ],
  },
  "transformers": {
    "*.svg": ["@parcel/transformer-raw"],
    "*.{mp3,wav,mp4,mov,wmv,flv,avi,webm}": ["@parcel/transformer-raw"]
  }
}

🤔 Expected Behavior

When i server a live server, i expect to find each entry on a separate URL.

localhost:3000/300x600 returns the ./300x600/index.html entry and localhost:3000/300x300 returns the ./300x300/index.html entry.

😯 Current Behavior

When i serve the live server, I expect to find the entries under different URLs, instead, on all URLs, only the first entry is served.

localhost:3000/300x600 returns the same as localhost:3000/300x300.

🔦 Context

Cannot update to 2.9.0 because of this bug, since it breaks the cloud bundler functionality

🌍 Your Environment

I am running this through parcel API, i do nothing else, just the configuration i provided higher, and I send it an array of entry points expecting to find them on separate URLs. I am using moleculerjs framework to build a microservice, that serves parcels as a cloud bundler. I see no errors thrown

Software Version(s)
Parcel 2.9.1
Node 16.19.0
Yarn 1.22.19
Operating System mac os
truesteps commented 1 year ago

Maybe in a related issue, when I replaced my URLs with localhost:3000/300x600/ as suggested by the pullrequest, this now works but it broke bundling some scripts, that were included without a slash in the src attribute, so if I include an env.js file like this <script src="env.js"></script> it didnt work, but when I did <script src="/env.js"></script> it works. I think the pull request will fix this issue as well :)

mischnic commented 1 year ago

<script src="env.js"></script> it didnt work

But Parcel would never generate HTML like that, so I don't quite understand how you got script loading to break.

truesteps commented 1 year ago

<script src="env.js"></script> it didnt work

But Parcel would never generate HTML like that, so I don't quite understand how you got script loading to break.

In HTML when I add this script (in the html file i'm bundling) it also falls back to the first preview instead of the properly resolving the path, which worked before 2.9.0, im assuming your fix will make this work again as well.

Also thank you @mischnic for the quick fix, you're a gem!

mischnic commented 1 year ago

Can you share a complete example for that? Parcel will (at least for me) always generate absolute urls like

300
<script src="/300x300/index.a9f2f4b3.js" defer=""></script>
truesteps commented 1 year ago

@mischnic im not sure it's a parcel bug, more like it's my maybe not perfect understanding :D I have a custom optimizer I wrote which includes some helper scripts + polyfills and an env.js file, that gets loaded.

        const envScript = `<script src="/env.js?cb=${ new Date().getTime() }"></script>`;

        if (contents.indexOf('<!--ENV-->') === -1) {
            contents = contents.replace('</head>', `\n<!--ENV-->\n${ envScript }\n<!--/ENV-->\n</head>`);
        }

Before 2.9.0 it looked like

 const envScript = `<script src="env.js?cb=${ new Date().getTime() }"></script>`;

I just had tu add the slash to the beginning to make it work, otherwise the env.js file resolved as the first entry bundled. Whereas it might not have been correct even before 2.9.0, after the update it broke this. The env.js file just gets copied to the dist directory manually

mischnic commented 1 year ago

I see, the version with src="env.js" would have been broken already though if you had deeper subdirectories like localhost/300x600/something

If you manually insert some script tags in an optimizer like this, then all bets are off anyway 😄 .

truesteps commented 1 year ago

Yeah :D I mean i got it to work so that's not a problem anymore :) thanks a bunch for the quick fix of the original issue! Amazing work as always