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

fix: css url public path #17170

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

ahabhgk
Copy link
Contributor

@ahabhgk ahabhgk commented May 10, 2023

Summary

fixes #16969

🤖 Generated by Copilot at 33215ce

This pull request adds a new feature to the CSS modules plugin that allows using a placeholder for the public path in the CSS source and dependencies. This enables the public path to be resolved at runtime instead of being hardcoded in the generated CSS assets. It also adds a test case to verify the functionality and refactors some code for clarity and consistency.

Details

🤖 Generated by Copilot at 33215ce

  • Import ReplaceSource class and getUndoPath function to enable replacing public path placeholder in CSS module source (link, link)
  • Obtain filename and info properties of CSS asset by calling compilation.getPathWithInfo and compute publicPath property using getUndoPath or compilation.getAssetPath (link)
  • Replace filenameTemplate and pathOptions properties of CSS asset with filename, info, publicPath, and modules properties (link)
  • Add publicPath parameter to renderContentAsset method of CssModulesPlugin class and wrap moduleSource in ReplaceSource instance to replace public path placeholder (link, link, link)
  • Define PUBLIC_PATH_PLACEHOLDER constant as a special string to mark public path in CSS url dependencies and use it in runtimeTemplate.assetUrl calls in CssUrlDependencyTemplate class (link, link, link, link)
  • Add test case to test/configCases/css/urls-css-filename/index.js to check styles in div.css (link)
  • Add nested.css file to test/configCases/css/urls-css-filename/ to test nested import and url handling (link)
  • Add webpack.config.js file to test/configCases/css/urls-css-filename/ to set up output options, CSS experiments, and split chunks optimization for test case (link)

@webpack-bot
Copy link
Contributor

For maintainers only:

  • This needs to be documented (issue in webpack/webpack.js.org will be filed when merged)
  • This needs to be backported to webpack 4 (issue will be created when merged)

@@ -501,6 +519,21 @@ class CssModulesPlugin {
codeGenResult.sources.get("css") ||
codeGenResult.sources.get("css-import");

const moduleSourceCode = moduleSource.source().toString();
const publicPathRegex = new RegExp(
CssUrlDependency.PUBLIC_PATH_PLACEHOLDER,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It breaks source maps, we should not do it, we should rewrite assets modules and generate the valid URL there

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we use the same logic in mini-css-extract-plugin, but it was wrong and yeah our source maps are broken in some cases, there are issues about it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any link about the source maps issues, would like to learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just make an URL with a newline and put somethings CSS on the same line.

Also if you look your bundled JS file, it will contain asset module, this is wrong, so the solution is refactor assets module and make it compatibility with CSS

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good to know, thanks

Copy link
Member

@alexander-akait alexander-akait left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, wrong solution

@alexander-akait
Copy link
Member

@ahabhgk I tried different solution and I think I found. We have two problems here:

  1. When we have an asset only in CSS module we include runtime for loading assets modules in JS bundle, but there is no asset module for loading in JS, we should fix it, I will do it in a separate PR
  2. Your solution is not bad, we need to improve path using getUndoPath (so we need to do it late), I will finish your PR soon too

Time to finish CSS feature

(match.index += match[0].length - 1),
publicPath
);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally we need to use ReplaceSource here for caching, just an idea

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you mean CachedSource?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I see, add cache for css renderModule result just like _moduleFactoryCache added in js renderModule

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, feel free to try it, should work without perf and source maps problems

Copy link
Member

@alexander-akait alexander-akait left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And we need more test:

  1. When asset above CSS file
  2. When asset on the same level
  3. When asset in nested directory

Each test should be for public path auto public path with string value

Also we have https://webpack.js.org/configuration/module/#rulegeneratoroutputpath, so we need to add a test case too

@alexander-akait
Copy link
Member

A lot of tests... If you have time you can add them to your solution to ensure the idea is working

@alexander-akait
Copy link
Member

And feel free to rebase

@webpack-bot
Copy link
Contributor

@ahabhgk Thanks for your update.

I labeled the Pull Request so reviewers will review it again.

@alexander-akait Please review the new changes.

) {
source = cacheEntry.source;
} else {
const moduleSourceCode = moduleSourceContent.source().toString();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to use .toString()? It is very bad for perf

hash: compilation.hash
}
);
assetPathForCss = path + filename;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can generate this only when asset module in CSS dependecy to avoid extra work, because we still need to improve it, have
runtimeRequirements.add(RuntimeGlobals.publicPath);, and so we generate extra JS code if you have an asset in your CSS (but not in JS), and in future we will need to fix it too (I described it above)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, both need the asset module to aware whether it is only referenced by a css module or a js module, since it's not very related to this PR, I can give a try in the future PR

Copy link
Member

@alexander-akait alexander-akait left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you look good, I want to make some investigation about perf and more test cases (I will do it), so I will finish and merge it for the next release ❤️

@alexander-akait
Copy link
Member

I want to make a release on this week with this fix, so don't worry, it is not abadoned, will review in the next few days

@alexander-akait
Copy link
Member

/cc @vankop Can you look at this too?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Ready for Merge
Development

Successfully merging this pull request may close these issues.

experiments.css generate wrong url path
3 participants