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

Wrong path for assets inside css files, when use subfolder for css files #1005

Open
WebCimes opened this issue Dec 26, 2022 · 5 comments
Open

Comments

@WebCimes
Copy link

Bug report

Actual Behavior

For begin I set a publicPath for my assets (ex fonts) :

test: /\.(eot|ttf|otf|woff|woff2)$/i,
    type: 'asset/resource',
    generator: {
        publicPath: '/dist/fonts/',
        outputPath: './fonts/',
    },

When I set no subfolder for my css files it's work fine :
new MiniCssExtractPlugin({filename: "[name].css"}),

And I got the right path in my css files :

@font-face
{
    font-family: 'Poppins';
    src: url(/dist/fonts/3bd71aafa4de4b4a8875.eot);
    src: url(/dist/fonts/3bd71aafa4de4b4a8875.eot?#iefix) format('embedded-opentype'),
        url(/dist/fonts/e9b88d1590baa248f3e2.woff2) format('woff2'),
        url(/dist/fonts/081fa188b65fb4393803.woff) format('woff'),
        url(/dist/fonts/5c210093630fe230c462.ttf) format('truetype');
    font-weight: 300;
    font-style: normal;
}

But now if I want to put my css files into a subfolder like css/myfiles.css :
new MiniCssExtractPlugin({filename: "css/[name].css"}),

I get wrong path in my css files :

@font-face
{
    font-family: 'Poppins';
    src: url(..//dist/fonts/3bd71aafa4de4b4a8875.eot);
    src: url(..//dist/fonts/3bd71aafa4de4b4a8875.eot?#iefix) format('embedded-opentype'),
        url(..//dist/fonts/e9b88d1590baa248f3e2.woff2) format('woff2'),
        url(..//dist/fonts/081fa188b65fb4393803.woff) format('woff'),
        url(..//dist/fonts/5c210093630fe230c462.ttf) format('truetype');
    font-weight: 300;
    font-style: normal;
}

Expected Behavior

When I use subfolder for my css files the path of my fonts inside my css files must be only /dist/fonts/, but actually ../ are added in addition.

Please paste the results of npx webpack-cli info here, and mention other relevant information

System:
OS: Linux 4.4 Debian GNU/Linux 10 (buster) 10 (buster)
CPU: (8) x64 Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz
Memory: 8.02 GB / 15.89 GB
Binaries:
Node: 18.12.1 - ~/.nvm/versions/node/v18.12.1/bin/node
npm: 9.2.0 - ~/.nvm/versions/node/v18.12.1/bin/npm
Packages:
@webpack-cli/generators: ^3.0.1 => 3.0.1
babel-loader: ^9.1.0 => 9.1.0
copy-webpack-plugin: ^11.0.0 => 11.0.0
css-loader: ^6.7.3 => 6.7.3
html-webpack-plugin: ^5.5.0 => 5.5.0
style-loader: ^3.3.1 => 3.3.1
terser-webpack-plugin: ^5.3.6 => 5.3.6
webpack: ^5.75.0 => 5.75.0
webpack-cli: ^5.0.1 => 5.0.1
webpack-dev-server: ^4.11.1 => 4.11.1
webpack-manifest-plugin: ^5.0.0 => 5.0.0
workbox-webpack-plugin: ^6.5.4 => 6.5.4
Global Packages:
webpack-cli: 5.0.1
webpack: 5.75.0

Thanks

@alexander-akait
Copy link
Member

Please creare repdocuible test repo, I think you have a problem with public path

@vetruvet
Copy link

I happen to have run into the same issue and put together a reproduction repo: https://github.com/vetruvet/mini-css-extract-public-path-bug

In digging into the issue, I've found some seemingly useful information (not enough for me to propose a fix though):

  • When this plugin's loader runs importModule, it passes ABSOLUTE_PUBLIC_PATH (webpack:///mini-css-extract-plugin/) as the publicPath
  • When the webpack asset module rule has a publicPath (that overrides the full output.publicPath), webpack's AssetGenerator will put that in the generated code instead of a publicPath + filename expression. This causes the ABSOLUTE_PUBLIC_PATH to not be used, and instead BASE_URI (webpack://)
  • When this plugin then does replacement of the webpack:// URIs, it ends up trying to make a relative path from the CSS file to the asset using getUndoPath, but (at least in the reproduction repo) it ends up being ../ and then the asset rule's publicPath and file name get appended to that. In the case of the reproduction repo, it would need to be ../../.
  • This only happens when the CSS file is output into a subfolder. Otherwise getUndoPath returns an empty string, and the asset rule's publicPath is not prepended with ../

I'm not sure where a proper fix would be, but hopefully that info at least helps.

@WebCimes as a workaround what I've done is make output.assetModuleFilename a function and not use the outputPath or publicPath options on the asset rule e.g.

assetModuleFilename: ({ filename }) => `${/\.(eot|ttf|otf|woff|woff2)$/i.test(filename) ? 'fonts/' : ''}[name][ext]`,

@WebCimes
Copy link
Author

@vetruvet thanks for your reproduction repo and your great explanation of the problem, I hope someone could correct the bug. Also thanks for your workaround who works well, but finnaly I have also find another easy workaround (similary to yours), like you said I don't use outputPath or publicPath, and I add the subfolder for my asset directly inside the generator.filename :
{ test: /\.(eot|ttf|otf|woff|woff2)$/i, type: 'asset/resource', generator: { // publicPath: '/dist/fonts/', // outputPath: './fonts/', filename: 'fonts/[name][ext][query]', }, },

@MLoughry
Copy link

I encountered this issue after enabling esModule and module.namedExport in css-loader. While the above workarounds were not really applicable to my config, I found the setting experimentalUseImportModule: false bypasses the bad code in question and resolved my issue.

@alexander-akait
Copy link
Member

@MLoughry You should not use experimentalUseImportModule

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

4 participants