parcel-bundler / parcel

The zero configuration build tool for the web. šŸ“¦šŸš€
https://parceljs.org
MIT License
43.39k stars 2.27k forks source link

Paths to css and js in the build dist package are not correct #7149

Closed Ren22 closed 2 years ago

Ren22 commented 2 years ago

šŸ› bug report

The bug is observed once parcel build index.html is executed. Generated index.html file has an incorrect paths to css and js file which is defined from html as a module.

šŸŽ› Configuration (.babelrc, package.json, cli command)

package.json

{
  "scripts": {
    "build": "parcel build index.html --no-optimize",
  },
  "devDependencies": {
    "@parcel/transformer-less": "^2.0.0",
    "@typescript-eslint/eslint-plugin": "^4.32.0",
    "eslint": "^7.32.0",
    "eslint-config-airbnb-base": "^14.2.1",
    "eslint-plugin-import": "^2.24.2",
    "parcel": "^2.0.0",
    "typescript": "^4.4.3"
  },
  "dependencies": {
    "express": "^4.17.1",
    "handlebars": "^4.7.7",
    "less": "^4.1.1"
  },
  "engines": {
    "node": ">=12.0.0"
  },
  "targets": {
    "global": {
      "context": "browser",
      "outputFormat": "global"
    }
  }
}

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <title>Bla</title>
  <meta charset="utf-8">
</head>
<body>
  <script type="module" src="./src/index.ts"></script>
</body>
</html> 

šŸ¤” Expected Behavior

Generated html page by parcel has correct paths to css and js sources.

<!DOCTYPE html>
<html lang="en">
<head><link rel="stylesheet" href="./index.4c040f44.css">
  <title>My aweseome chat</title>
  <meta charset="utf-8">
</head>
<body>
  <script type="module" src="./index.3c9a2e4f.js"></script>
</body>
</html> 

šŸ˜Æ Current Behavior

The path has a missing dot in front of slash of the source files (src and href)

<!DOCTYPE html>
<html lang="en">
<head><link rel="stylesheet" href="/index.4c040f44.css">
  <title>My aweseome chat</title>
  <meta charset="utf-8">
</head>
<body>
  <script type="module" src="/index.3c9a2e4f.js"></script>
</body>
</html> 

Browser complains that:

Refused to apply style from 'http://127.0.0.1:5500/index.4c040f44.css' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.
Refused to apply style from 'http://127.0.0.1:5500/index.4c040f44.css' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.

šŸ’ Possible Solution

Manually changing (putting a dot in front of slsh) the paths in generated index.html to href="./index.4c040f44.css" and src="./index.3c9a2e4f.js" solved the problem.

šŸ”¦ Context

šŸ’» Code Sample

šŸŒ Your Environment

Software Version(s)
Parcel 2.0.0
Node v15.9.0
npm/Yarn 7.5.3
Operating System macOS Big Sur
devongovett commented 2 years ago

Did you try setting --public-url ./ (or the publicUrl option in target config)? The default public URL is /

Ren22 commented 2 years ago

Did you try setting --public-url ./ (or the publicUrl option in target config)? The default public URL is /

Seems to solve it, thanks! Although fonts are not found this time, but will have one more look.

scm04 commented 2 years ago

Just to comment on this issue, the fact that Parcel puts all the generated files from the build command into the same directory (it has done so in all my testing so far) but does not use bare specifiers for the dependencies in the generated index.html file is very confusing.

I've had a poke around in the source code, and it seems that it is intentional that all dependency URLs created by Parcel start at the project root (/, the default value of publicUrl), but why was the decision made to default publicUrl to /? It seems counter-intuitive to me to do things this way since all of the Parcel-generated files are put in the same directory.

I found this especially confusing as a new user because the Parcel-generated files are not placed at the project root even if the original source files are at the project root (the generated files are placed in the dist directory by default), so it makes no sense to me that the dependency URLs are constructed as if the dependencies are located at the project root when they will never be that way by default.

Honestly, from what I have observed about how Parcel works (and making a few inferences about what Parcel's creators intend for users to do with the generated files), I would suggest that it never makes sense to start a dependency URL at the project root and that the dependency URLs should instead be bare specifiers because bare specifiers would most likely resolve correctly no matter where the user attempts to view their website as long as the user keeps all the generated files together, which is likely (users probably aren't going to try to organize minified files beyond what Parcel already did automatically).

If I'm totally wrong about how Parcel works and what the creators intended when they made the decision to default publicUrl to /, I'd love to get some feedback that explains why it works the way it works and potential difficulties to using bare specifiers instead, so please feel free to reply! Also, I've loved using Parcel aside from this issue, so keep up the great work! šŸ˜„

devongovett commented 2 years ago

It's because of client side routing. The URL of a page may have nothing to do with where the HTML file is hosted.