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

Is there a way to build html with relative assets url? #206

Open
xcatliu opened this issue Dec 11, 2017 · 40 comments
Open

Is there a way to build html with relative assets url? #206

xcatliu opened this issue Dec 11, 2017 · 40 comments

Comments

@xcatliu
Copy link
Contributor

xcatliu commented Dec 11, 2017

Choose one: is this a 🐛 bug report or 🙋 feature request?

🙋 feature request

🤔 Expected Behavior

When exec parcel build docs/index.html, the generated html should have relative assets url, such as:

<script src="./89ee6b6452b6649c72b85a19637b8362.js"></script>

😯 Current Behavior

The url is an absolute path:

<script src="/dist/89ee6b6452b6649c72b85a19637b8362.js"></script>

💁 Possible Solution

Is there a way to build html with relative assets url? Maybe some configuration?

🔦 Context

A common practice is to only host the dist (or public) dir using a static server. But with absolute path, it cannot find the assets resource.

@albinotonnina
Copy link
Contributor

Yes, use --public-url when building:
check this PR: parcel-bundler/website#30

@xcatliu xcatliu closed this as completed Dec 11, 2017
@johanberonius
Copy link

Built files written in ./dist are fine but nothing except the index page gets served by the dev-server.

Example:

test.html:

<h1>test.html</h1>
<script src="test.js"></script>

test.js:

console.log('test.js');

Command, using version 1.10.2:

parcel --public-url '.' test.html

Now http://localhost:1234/ returns the index page as stored in ./dist/test.html. Notice there is no slash in front of the file name, that is the desired outcome of setting --public-url.

<h1>test.html</h1>
<script src="test.e98b79dd.js"></script>

The file ./dist/test.e98b79dd.js looks fine but http://localhost:1234/test.e98b79dd.js does not serve the file.

@Akiyamka
Copy link

--public-url ./ still not work.
I just want <script src="./test.e98b79dd.js"></script> instead <script src="test.e98b79dd.js"></script> but a can't do that with --public-url ./ settings - output still without './' =(

nmelehan added a commit to nmelehan/code-widget that referenced this issue Jun 28, 2019
Use --public-url option to ensure assets are linked like
"app.7c88748f.js" instead of "/app.7c88748f.js"

The previous link behavior was causing 404 errors for the assets
when hosted on GitHub Pages

See
parcel-bundler/parcel#206
parcel-bundler/website#30
Rayraegah added a commit to Rayraegah/bias-viz that referenced this issue Jul 3, 2019
@ErikSom
Copy link

ErikSom commented Dec 13, 2019

For anyone that just really wants to see a './' before the url, what I did was to change the build command (on Mac) to:
parcel build src/index.html --public-url replacethislinewithadot && sed -i '' 's/replacethislinewithadot/./g' dist/index.html

I found no other way to force the '.' in the url.

@jdoleary
Copy link

jdoleary commented Dec 22, 2019

Relative urls are necessary if one is using parcel to build for a subdomain. This is a necessary feature. @albinotonnina

@puresick
Copy link

Wouldn't it also be saver in general to have ./-relative paths per default in the index.html?
I mean, it does not care if sub-directory or not, it will just take the file relative from its location.

I can imagine other scenarios were relative paths are not necessary or need to be altered are way less common than this one.

@Cristy94
Copy link

Cristy94 commented Mar 5, 2020

Note that if you are using something like react-router, the relative paths won't work. Because the href is something like site.com/myApp/router-path and it will try to load site.com/myApp/router-path/styles.css instead of site.com/myApp/styles.css.

Is there any way to have the asset paths be relative to index.html, si it will work wherever you place the index file?

@mischnic
Copy link
Member

mischnic commented Mar 5, 2020

maybe --public-url .

@Cristy94
Copy link

Cristy94 commented Mar 5, 2020

I did it! I managed to make a production build that has react-router and works in any subfolder.
Steps I took:

  • Build parcel with relative paths --public-path ./
  • Use .htaccess to make sure index.html and all assets are loaded correctly when refreshing a virtual path generated by react-router. This was done by simply loading all 404 files from the folder root instead of current path.
  • Make all the links in react-router correct by automatically detecting the app path (basename) on page load based on current location.pathname.

I wrote a more detailed blog post here.

Note, this feels like a very hacky solution, but I did not find any other way to make a fully build application be completely path independent and use only relative paths.

@EmmaGoodliffe
Copy link

I would recommend deleting your .cache and dist folders whenever you change your --public-url for the changes to actually take effect

@pawelkedra
Copy link

Why it's closed? I still don't see a way to produce <script src="./test.e98b79dd.js"></script> output instead <script src="test.e98b79dd.js">

@mischnic
Copy link
Member

@pawelkedra --public-url ./doesn't work for you?

@pawelkedra
Copy link

pawelkedra commented Apr 22, 2020

@mischnic it doesn't, it produces <script src="my-app.0ad7f820.js"> </script>. Looks like ./ part is always skipped

@mischnic
Copy link
Member

Well,
<script src="./test.e98b79dd.js"></script> and
<script src="test.e98b79dd.js"></script>
do the same thing. The ./ is actually redudant, every path that doesn't start with a protocol or / is relative anyway.

@pawelkedra
Copy link

@mischnic it matters if your site is not deployed at the root of the domain, e.g. example.com/site/index.html - without dot browser will try to download all resources from example.com/test.e98b79dd.js, not from example.com/site/test.e98b79dd.js. I can't use --public-url site, I have to consider site part "dynamic", it may be changed for reasons beyond my control.

@artemisSystem
Copy link

I agree with @pawelkedra. Having an option to output files that use ./ for paths would be quite useful 😊

@yonatanmn
Copy link

Any update on this? Why is it closed?

@klausbreyer
Copy link

--public-url ./ works for me.

@exsesx
Copy link

exsesx commented Jul 8, 2020

Any updates?

@EmmaGoodliffe
Copy link

@exsesx Have you tried this? It was the only way I could get it to work.

@exsesx
Copy link

exsesx commented Jul 8, 2020

@EmmaGoodliffe I'm trying, but my index.html points to {public-url}/src...js, but the actual file is not there :c

@EmmaGoodliffe
Copy link

@exsesx Sorry, I'm not quite sure what you are trying to do 🤔.

What is the path in your source index.html and what do you want to change it to?

@panbehkar
Copy link

For anyone that just really wants to see a './' before the url, what I did was to change the build command (on Mac) to:
parcel build src/index.html --public-url replacethislinewithadot && sed -i '' 's/replacethislinewithadot/./g' dist/index.html

I found no other way to force the '.' in the url.

Thanks to @ErikSom
This is my package.json, which is working fine for me.
Inside the build script:
First, I removed the old dist folder
Then, I moved my project's assets to the files folder.
And at the end, I updated the @font-face URL from files/ to ./ path

{
  "name": "test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "keywords": [],
  "author": "Panbehkar",
  "license": "ISC",
  "scripts": {
    "build": " npm run clean & npm run buildIntoFiles && npm run updatePath",
    "clean": "rmdir /Q /S dist",
    "buildIntoFiles": "parcel build src/index.html --no-source-maps --public-url ./files",
    "updatePath": "sed -i -- 's/files/.\\//g' dist/files/*.css"
  },
  "dependencies": {},
  "devDependencies": {
    "autoprefixer": "^9.8.6",
    "parcel-bundler": "^1.12.4",
    "parcel-plugin-custom-dist-structure": "^1.1.16",
    "postcss-modules": "^3.2.2",
    "prettier": "^2.1.2",
    "sass": "^1.26.11"
  },
  "customDistStructure": {
    "config": {
      "files": [
        ".css",
        ".js",
        ".woff",
        ".png",
        ".jpg"
      ]
    }
  }
}

@TimDaub
Copy link

TimDaub commented Nov 30, 2020

would recommend deleting your .cache and dist folders whenever you change your --public-url for the changes to actually take effect

I did

$ rm -rf .parcel-cache
$ rm -rf dist
$ parcel build --public-url ./ --dist-dir dist src/html/index.html

And now my file paths are relative (the / is gone).

@hrahimi270
Copy link

I think using --public-url / solves it if you serve the files after building with something like server dist -p 3000. But it's not useful for uploading the files into a folder on a host like example.com/site.

@iuriikomarov
Copy link

Are any updates on it?

foo.js and ./foo.js are different things. Please, keep things simple and straightforward, do not remove ./ only because your opinion is that it is redundant. Many folks will burn a lot of time debugging why ./ is getting stripped.

@awreese
Copy link

awreese commented Jun 18, 2021

@klausbreyer

--public-url ./ works for me.

Thanks, using --public-url ./ stripped off the leading "/" and the .css and .js files worked correctly for me as well.

@codingedgar
Copy link

codingedgar commented Aug 25, 2021

It does not work for me neither I'm using parcel build --public-url ./ -d docs demo/index.html and its still producing <script src="main.4a6d51be.js" type="text/javascript"> instead of <script src="./main.4a6d51be.js" type="text/javascript">

Things I tried

  • delete cache
  • delete build folder
  • use --public-url ./
  • use --public-url .

the repo at: https://github.com/codingedgar/macos-multi-select

workaround

I manually changed the src because its just one file and i have like 40min debugging this.

#### Edit
idk if this is relevant, the environment is: macOS Big Sur

@ErikSom
Copy link

ErikSom commented Aug 26, 2021

It does not work for me neither I'm using parcel build --public-url ./ -d docs demo/index.html and its still producing <script src="main.4a6d51be.js" type="text/javascript"> instead of <script src="./main.4a6d51be.js" type="text/javascript">

Things I tried

  • delete cache
  • delete build folder
  • use --public-url ./
  • use --public-url .

the repo at: https://github.com/codingedgar/macos-multi-select

workaround

I manually changed the src because its just one file and i have like 40min debugging this.

#### Edit
idk if this is relevant, the environment is: macOS Big Sur

Would recommend to do something like this:
#206 (comment)

@johanroug
Copy link

parcel --public-url '.' test.html

thankss
but I believe it should be

parcel --public-url . test.html
not
parcel --public-url '.' test.html

@ettmetal
Copy link

I feel like there's a smarter way to do this. Parcel is all about being minimal-config right? The reason I'm here was trying to build a basic html page (I know, not main use-case, but still, hear me out).

When I link the script in my HTML, I already 'chose' if I want that href to be relative to the file, the domain root etc. Why not have parcel analyse & repsect that?

@MuhammadM1998
Copy link

MuhammadM1998 commented Feb 16, 2022

Can anyone help me out I

For anyone that just really wants to see a './' before the url, what I did was to change the build command (on Mac) to: parcel build src/index.html --public-url replacethislinewithadot && sed -i '' 's/replacethislinewithadot/./g' dist/index.html

I found no other way to force the '.' in the url.

What's the equivalent windows command for
sed -i '' 's/replacethislinewithadot/./g' dist/index.html
I'm stuck at this.

@rocstack
Copy link

Is there an official solution to this? Been stuck on it for days. --public-url ./ removes the dot after building and I need the asset paths to be relative to the subdirectory.

Denperidge added a commit to osoc22/project-idlab that referenced this issue Jul 11, 2022
@KhafraDev
Copy link

If you know the subdomain the resources are on, you can use that as the public-url option. Not the prettiest, but the only thing that worked without using tools like sed.

- "build:prod": "npx parcel build --public-url ./ index.html"
+ "build:prod": "npx parcel build --public-url /My-Subdomain/ index.html"

'test.hash.js' will now resolve to '/My-Subdomain/test.hash.js' as is expected.

@StevedeP-Philips
Copy link

If you know the subdomain the resources are on, you can use that as the public-url option. Not the prettiest, but the only thing that worked without using tools like sed.

- "build:prod": "npx parcel build --public-url ./ index.html"
+ "build:prod": "npx parcel build --public-url /My-Subdomain/ index.html"

'test.hash.js' will now resolve to '/My-Subdomain/test.hash.js' as is expected.

Thanks! This helped me out.

@rienheuver
Copy link

Why is this still not fixed? I have a repo using Parcel and I also have a /docs where I have some html-pages. I use parcel build docs/src/index.html --dist-dir docs to build it to /docs in my repo. I then set Github Pages to use /docs as the directory for publishing my docs. However, the CSS and JS don't work, because they are referenced incorrectly. Haven't found a workaround yet. I could set --public-url <repo-name> but that will fault when changing the name of the repo...

@ErikSom
Copy link

ErikSom commented Mar 3, 2023

For the linux people:
parcel build src/index.html --public-url replacethislinewithadot && sed -i.bak 's/replacethislinewithadot/./g' dist/index.html

@rschoenbichler
Copy link

Since ./ does not result in relative imports, it's not possible to move the dist output into a sub directory when including a service worker. This can't be fixed with the sed workaround as service worker imports are handled via the import.meta.url

Any official statement on this?

@rschoenbichler
Copy link

Could we please reopen this issue, as the sed workaround is not applicable for using with service workers

@sdedovic
Copy link

sdedovic commented Sep 2, 2024

Having relative paths is a requirement for IPFS 1 2 3 4 and the above workarounds are hacks, at best. Being able to generate relative asset URLs and/or prepend a path is a requirement.

For another workaround, one that may be converted into a Parcel plugin (or ideally build flag), I found this: https://github.com/tmcw/make-relative

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

No branches or pull requests