Skip to content

Incorrect paths for fonts #915

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

Closed
giero opened this issue Feb 4, 2021 · 13 comments
Closed

Incorrect paths for fonts #915

giero opened this issue Feb 4, 2021 · 13 comments
Labels

Comments

@giero
Copy link

giero commented Feb 4, 2021

Hi :)

I have comeback of known issue #88 in new version of Encore :)
So far I used the same solution as #88 (comment)

webpackConfig.module.rules[2].options.publicPath = './';
webpackConfig.module.rules[3].options.publicPath = './';

but this option is not valid anymore.
I tried to modify config using

.configureLoaderRule('fonts', (loaderRule) => {
    
})

but there's not much to do here

{
  test: /\.(woff|woff2|ttf|eot|otf)$/,
  type: 'asset/resource',
  generator: { filename: 'fonts/[name].[hash:8][ext]' },
  parser: {}
}

Do you have any idea how to do this correctly?

@giero
Copy link
Author

giero commented Feb 4, 2021

Temporary working (but with warning from Encore about public path) solution:

Encore
    .setOutputPath('web/build/')
    .setPublicPath('.')
    .setManifestKeyPrefix('.')
    .configureManifestPlugin((options) => {
        options.publicPath = './build/';
    })
// ...

Doesn't work with .enableVersioning()

@weaverryan
Copy link
Member

Hey @giero!

Is the problem only that the paths are wrong in manifest.json? Or is there some other problem? It could be related to #907 if it's just about manifest.json.

Cheers!

@giero
Copy link
Author

giero commented Feb 5, 2021

Reffering to #88 (comment) we have the same case - multiple Symfony instances under sub-directories e.g:

http://example.org/site-1/web/app.php
http://example.org/site-2/web/app.php

Our current Encore config looks like this:

Encore
    .setOutputPath('web/assets/')
    .setPublicPath('/assets')

and maybe it's important

.splitEntryChunks()
.configureSplitChunks((splitChunks) => {
        splitChunks.chunks = 'all';
        splitChunks.cacheGroups = {
            css: {
                test: /\.(css|sass|scss|less)$/,
                name: 'styles',
                chunks: 'all',
            },
        };
    })

to aggregate all style files into single css file.

Production entrypoints (with versioning) looks like this

{
  "entrypoints": {
    "attribute/index": {
      "js": [
        "/assets/runtime.5b7a9943.js",
        "/assets/styles.b54955b2.js",
        "/assets/0.cf60d32b.js",
        "/assets/attribute/index.1561a3ba.js"
      ],
      "css": [
        "/assets/styles.55053e81.css"
      ]
    },

and some examples from manifest.json

{
  ...
  "assets/attribute/index.js": "/assets/attribute/index.1561a3ba.js",
  "assets/styles.js": "/assets/styles.b54955b2.js",
  "assets/styles.css": "/assets/styles.f6a7beab.css",
  ...
  "assets/fonts/fontawesome-webfont.woff2?v=4.7.0": "/assets/fonts/fontawesome-webfont.20fd1704.woff2",
  ...
}

Everithing is ok so far, but in styles.css we need relative fonts/images/icons path ... because it looks like this:

url(/assets/fonts/glyphicons-halflings-regular.be810be3.woff2) format("woff2")

So

const config = Encore.getWebpackConfig();

config.module.rules[2].options.publicPath = './';
config.module.rules[3].options.publicPath = './';

module.exports = config;

was a "hack" to fix that css paths - after that we have

url(fonts/glyphicons-halflings-regular.be810be3.woff2) format("woff2")

And now, with Asset Modules I have to find working solution to fix those paths.

@weaverryan weaverryan added the Bug Bug Fix label Feb 6, 2021
@giero
Copy link
Author

giero commented Feb 9, 2021

I am not sure if this is a bug. This works fine, as long as the application is not running in a subdirectory.

In this case, since the styles.css and fonts are in the web/assets/ directory, that's why the path to fonts should be relative. The question is whether at the moment it is possible to force the path relativity in the css file (maybe it's not a matter of Encore itself but the less/scss configuration).

@weaverryan
Copy link
Member

Yea, I understand. It's a matter of having relative paths in the final CSS files. I don't know if that's possible - it's not something I've looked into recently. Sorry I can't be more helpful! This would require some deep research.

@weaverryan weaverryan added Feature New Feature and removed Bug Bug Fix labels Feb 12, 2021
@giero
Copy link
Author

giero commented Apr 27, 2021

After hours of trial and error I have found working (but not very best I suppose) solution. But maybe someone could come up with their own solution based on that.

My goals:

  1. generate single styles.css (from all in-project css/less/scss files) file in Encore's outputPath
  2. gather all font files in outputPath/fonts
  3. gather all image files in outputPath/image
  4. (the most important) have all URLs for fonts/images as RELATIVE inside styles.css file - this is because we have single build and project may be in different sub-directories on clients server.

Point 1. can be simply done by

.splitEntryChunks()
.configureSplitChunks((splitChunks) => {
    splitChunks.cacheGroups = {
        css: {
            test: /\.(css|sass|scss|less)$/,
            name: 'styles',
            chunks: 'all',
        },
    };
})

But for the others the solution is ... "do not use Asset Modules" ...

My configuration is based on:
https://webpack.js.org/guides/asset-modules/
https://webpack.js.org/loaders/file-loader/
and ... .configureFontRule / .configureImageRule comments ...

.configureFontRule(
    { type: 'javascript/auto' },
    (rule) => {
        rule.loader = 'file-loader';
        rule.options = { outputPath: 'fonts', name: '[name].[ext]', publicPath: './fonts/' };
    }
)
.configureImageRule(
    { type: 'javascript/auto' },
    (rule) => {
        rule.loader = 'file-loader';
        rule.options = { outputPath: 'images', name: '[name].[ext]', publicPath: './images/' };
    }
)

After all of this every font/image is in its directory in public path and my URLs for fonts in styles.css look like this

@font-face {
  font-family: "Glyphicons Halflings";
  src: url(./fonts/glyphicons-halflings-regular.eot);
  src: url(./fonts/glyphicons-halflings-regular.eot?#iefix) format("embedded-opentype"), url(./fonts/glyphicons-halflings-regular.woff2) format("woff2"), url(./fonts/glyphicons-halflings-regular.woff) format("woff"), url(./fonts/glyphicons-halflings-regular.ttf) format("truetype"), url(./images/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format("svg");
}

Works like a charm ;) If I don't find a better solution using Assets Modules, I think I'll leave it as it is.
Cheers :)

@kevinpapst
Copy link

kevinpapst commented Apr 29, 2021

After upgrading to latest web pack (was still on 0.28) I ran into #88 again.

Thanks @giero for posting your solution, saved me a couple of hours.

As this is an issue for every (open source) app, where the devs don't know anything about the host system, I'd propose adding some documentation for it.

Edit: btw. the default config sets filenames to [name].[hash:8].[ext] instead of your example [name].[ext]

@andyexeter
Copy link
Contributor

The solution from @giero appears to have stopped working. I believe this release is the cause: https://github.com/webpack-contrib/mini-css-extract-plugin/releases/tag/v2.0.0

I have managed to get relative URLs working again by using the following in my webpack.config.js:

.configureMiniCssExtractPlugin((loaderConfig) => {
    loaderConfig.publicPath = './';
})

@xmontero
Copy link

@andyexeter you made my day!

I'll describe my situation so anyone looking in google for this will know your solution works:

  • Symfony 6.2
  • scss working perfect
  • required "@fortawesome/fontawesome-free": "^6.3.0" with yarn
  • imported in the scss
    • @import '~@fortawesome/fontawesome-free/scss/fontawesome';
    • @import '~@fortawesome/fontawesome-free/scss/regular';
    • @import '~@fortawesome/fontawesome-free/scss/solid';
    • @import '~@fortawesome/fontawesome-free/scss/brands';
  • Developing inside a docker at port 23180 inside a subdirectory
  • In webpack.config.js I had:
Encore
    .setOutputPath('public/build/')
    .setPublicPath('build') // removed / for subdirectory deploy

Problem:

With @andyexeter's solution, ie: this:

Encore
    .setOutputPath('public/build/')
    .setPublicPath('build') // removed / for subdirectory deploy
    .configureMiniCssExtractPlugin((loaderConfig) => {
        loaderConfig.publicPath = './';
    })

now the final path is: http://localhost:23180/repos/hello-trip/admin-panel/public/build/fonts/fa-solid-900.bdb9e232.woff2 (ie: no double /build/build but a single one) and the icons properly load.

@carsonbot
Copy link
Collaborator

Thank you for this suggestion.
There has not been a lot of activity here for a while. Would you still like to see this feature?
Every feature is developed by the community.
Perhaps someone would like to try?
You can read how to contribute to get started.

1 similar comment
@carsonbot
Copy link
Collaborator

Thank you for this suggestion.
There has not been a lot of activity here for a while. Would you still like to see this feature?
Every feature is developed by the community.
Perhaps someone would like to try?
You can read how to contribute to get started.

@carsonbot
Copy link
Collaborator

Friendly reminder that this issue exists. If I don't hear anything I'll close this.

@carsonbot
Copy link
Collaborator

Hey,

I didn't hear anything so I'm going to close it. Feel free to comment if this is still relevant, I can always reopen!

@carsonbot carsonbot closed this as not planned Won't fix, can't repro, duplicate, stale May 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants