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

[Bug]: wrong url path when using generator.publicPath and asset module #1118

Closed
SoonIter opened this issue Dec 24, 2024 · 10 comments
Closed

Comments

@SoonIter
Copy link

SoonIter commented Dec 24, 2024

Bug report

configure webpack with generator.asset.publicPath = '' and assetModule as below

module.exports = {
  module: {
    generator: {
      asset: {
        publicPath: '',
      },
    },
    rules: [
      {
        test: /\.svg$/i,
        oneOf: [
          /* config.module.rule('svg').oneOf('svg-asset') */
          {
            type: 'asset',
            parser: {
              dataUrlCondition: {
                maxSize: 1000,
              },
            },
            generator: {
              filename: 'static/svg/[name].svg',
            },
          },
        ],
      },
}

Actual Behavior

webpack-dist/static/css/index.392c62df.css

.a {
  background: url(../..//static/svg/react.svg);
}

Expected Behavior

.a {
  background: url(../../static/svg/react.svg);
}

How Do We Reproduce?

https://github.com/SoonIter/rspack-css-extract-wrong-path

pnpm i
npm run build # both rspack and webpack
# or npm run build:webpack

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

@SoonIter SoonIter changed the title [Bug]: [Bug]: wrong path when using generator.publicPath = '' and asset module Dec 24, 2024
@SoonIter
Copy link
Author

It didn't appear in experiments.css in
webpack/webpack#17170

it may related to base_uri replacement logic and importModule result
#915

@SoonIter SoonIter changed the title [Bug]: wrong path when using generator.publicPath = '' and asset module [Bug]: wrong url path when using generator.publicPath = '' and asset module Dec 24, 2024
@SoonIter
Copy link
Author

SoonIter commented Jan 7, 2025

@alexander-akait @vankop
Would you mind checking this, please? :)

@alexander-akait
Copy link
Member

alexander-akait commented Feb 6, 2025

@SoonIter Sorry for delay, why you need publicPath: ''? I strongly recommend avoid it and use auto by default

@SoonIter
Copy link
Author

SoonIter commented Feb 7, 2025

@SoonIter Sorry for delay, why you need publicPath: ''? I strongly recommend avoid it and use auto by default

“auto" is not implemented, any value of generator.publicPath would cause this bug

@SoonIter
Copy link
Author

SoonIter commented Feb 7, 2025

after set

module: {
    generator: {
      asset: {
        publicPath: 'auto',
      },
    },
}

webpack-dist/static/css/index.392c62df.css

.a {
  background: url(../..//autostatic/svg/react.svg);
}

@SoonIter SoonIter changed the title [Bug]: wrong url path when using generator.publicPath = '' and asset module [Bug]: wrong url path when using generator.publicPath and asset module Feb 7, 2025
@alexander-akait
Copy link
Member

@SoonIter Remove publicPath everywhere, here is fixed version:

const config = {
  mode: 'production',
  devtool: false,
  entry: {
    index: [join(__dirname, './src/index.mjs')],
    // 'assets/react': [join(__dirname, './src/assets/react.svg')],
  },
  plugins: [new HtmlWebpackPlugin()],
  optimization: {
    minimize: false,
  },
  output: {
    clean: true,
    path: isRunningWebpack
      ? path.resolve(__dirname, 'webpack-dist')
      : path.resolve(__dirname, 'rspack-dist'),
    filename: '[name].js',
    // publicPath: 'auto',
    // assetModuleFilename: 'static/asset/[name].[ext]',
    // module: true,
    // chunkFormat: 'module',
    // chunkLoading: 'import',
    // workerChunkLoading: 'import',
    // wasmLoading: 'fetch',
  },
  stats: {
    children: true,
  },
  module: {
    rules: [
      {
        resourceQuery: /raw/,
        type: 'asset/source',
      },
      {
        test: /\.svg$/i,
        oneOf: [
          /* config.module.rule('svg').oneOf('svg-asset-url') */
          {
            type: 'asset/resource',
            resourceQuery: /(__inline=false|url)/,
            generator: {
              filename: 'static/svg/[name].svg',
            },
          },
          /* config.module.rule('svg').oneOf('svg-asset-inline') */
          {
            type: 'asset/inline',
            resourceQuery: /inline/,
          },
          /* config.module.rule('svg').oneOf('svg-asset') */
          {
            type: 'asset',
            parser: {
              dataUrlCondition: {
                maxSize: 1000,
              },
            },
            generator: {
              filename: 'static/svg/[name].svg',
            },
          },
        ],
      },
      ...(isRunningRspack
        ? [
            {
              test: /\.css$/,
              type: 'javascript/auto',
              dependency: {
                not: 'url',
              },
              sideEffects: true,
              use: [
                {
                  loader: rspack.CssExtractRspackPlugin.loader,
                  options: {
                    // publicPath: 'auto',
                  },
                },
                {
                  loader: 'css-loader',
                  options: {
                    importLoaders: 1,
                    modules: {
                      auto: true,
                      namedExport: false,
                      exportGlobals: false,
                      exportLocalsConvention: 'camelCase',
                      localIdentName: '[local]-[hash:base64:6]',
                    },
                    sourceMap: true,
                  },
                },
              ],
            },
          ]
        : [
            {
              test: /\.css$/,
              type: 'javascript/auto',
              dependency: {
                not: 'url',
              },
              sideEffects: true,
              use: [
                {
                  loader: MiniCssExtractPlugin.loader,
                },
                {
                  loader: 'css-loader',
                  options: {
                    importLoaders: 1,
                    modules: {
                      auto: true,
                      namedExport: false,
                      exportGlobals: false,
                      exportLocalsConvention: 'camelCase',
                      localIdentName: '[local]-[hash:base64:6]',
                    },
                    sourceMap: true,
                  },
                },
              ],
            },
          ]),
    ],
  },
  experiments: {
    css: true,
    outputModule: true,
  },
  plugins: [
    isRunningRspack
      ? new rspack.CssExtractRspackPlugin({
          filename: 'static/css/[name].[contenthash:8].css',
          chunkFilename: 'static/css/async/[name].[contenthash:8].css',
          ignoreOrder: true,
        })
      : new MiniCssExtractPlugin({
          filename: 'static/css/[name].[contenthash:8].css',
          chunkFilename: 'static/css/async/[name].[contenthash:8].css',
          ignoreOrder: true,
        }),
  ],
};

Don't mix publicPath: '' and publicPath: 'auto', because it is different things and can lead to such things, when you have publicPath: '' webpack thinks you have empty public path and starts url with / (i.e. /autostatic/svg/react.svg), but when globally you have auto, so when chunk is generating it add ../../ to work from room and be relative, so you got url(../..//autostatic/svg/react.svg);

@alexander-akait
Copy link
Member

There is the same issue - #1005

@SoonIter
Copy link
Author

SoonIter commented Feb 7, 2025

Don't mix publicPath: '' and publicPath: 'auto', because it is different things and can lead to such things, when you have publicPath: '' webpack thinks you have empty public path and starts url with / (i.e. /autostatic/svg/react.svg)

🤔 Yes, but when setting output.publicPath: '/' and generator['asset'].publicPath: '/', shouldn't they produce consistent results?

only output.publicPath: '/'

yeah, this is a commonly used case

.a {
  background: url(/static/svg/react.svg);
}

output.publicPath: '/' and generator['asset'].publicPath: '/'

config can be seen at https://github.com/SoonIter/rspack-css-extract-wrong-path/blob/575267927cbda52385694afd76071fb0a39d1b31/rspack.config.mjs

.a {
  background: url(../..//static/svg/react.svg);
}

according to investigation of #1005 (comment), i think it is a bug of base_uri replacement bug when using associated with asset-module

@alexander-akait
Copy link
Member

Yes, it is a bug/limitation as was described here - #1005 (comment)

I recommend don't set multiple publicPath, because extracting and rewriting URLs can be hard in such cases, I want to close this issue, because it is a duplicate of #1005, anyway feel free to feedback there and feel free to send a PR

It is on my radar, by has low priority because in mostly cases it can be simplified and fixed by removing extra publicPath and it happens very rare

@alexander-akait
Copy link
Member

I can continue discussion there - #1005

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

2 participants