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): resolve style field skipping package exports #11510

Closed

Conversation

edoardocavazza
Copy link

Description

This PR is alternative to #7817 but it aims to solve the same problem. At the moment, vite fails to import css modules from package.json style field if the module has also a package exports map.
Please note that, differently from #7817, this PR does not introduce new features but it "just" fix the wrong resolution.

I have also updated the playground in order to test the case with and without skipExports option.

Additional context

skipExports may not be the best option name for the case, I am open to suggestions.


What is the purpose of this pull request?

  • Bug fix
  • New Feature
  • Documentation update
  • Other

Before submitting the PR, please make sure you do the following

  • Read the Contributing Guidelines.
  • Read the Pull Request Guidelines and follow the PR Title Convention.
  • Check that there isn't already a PR that solves the problem the same way to avoid creating a duplicate.
  • Provide a description in this PR that addresses what the PR is solving, or reference the issue that it solves (e.g. fixes #123).
  • Ideally, include relevant tests that fail without this PR but pass with it.

@edoardocavazza edoardocavazza changed the title Resolve style field skipping package exports feat(css): resolve style field skipping package exports Dec 28, 2022
@edoardocavazza edoardocavazza changed the title feat(css): resolve style field skipping package exports fix(css): resolve style field skipping package exports Dec 28, 2022
@@ -732,6 +732,7 @@ function createCSSResolvers(config: ResolvedConfig): CSSAtImportResolvers {
mainFields: ['style'],
tryIndex: false,
preferRelative: true,
skipExports: true,
Copy link
Member

Choose a reason for hiding this comment

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

I don't think we can skip exports here. Exports should work when resolving in CSS as it's a convention, and it has higher precedence over mainFields. I'd argue this PR creates a wrong resolution instead.

Copy link
Author

Choose a reason for hiding this comment

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

If I understand correctly, Vite does not follow any convention on styles and exports at the moment. The resolution of style entrypoints from the export map is blocked by #7817, which is under discussion. This PR fixes the mainFields styles resolution behavior, since it is currently broken in these cases. I would be happy to see #7817 merged, but if it is out of purpose for Vite, I think that the mainFields resolution should work at least.

Copy link
Member

Choose a reason for hiding this comment

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

Vite does follow partial convention for styles, mainly the sass, less, style mainFields config. I still don't quite see what's wrong here, based on the exports spec, if exports field is present, mainFields is ignored completely. So if the package you're using has an exports field, it will resolve from exports only. We would be breaking the spec if we go with this PR.

https://nodejs.org/api/esm.html#resolver-algorithm-specification

  1. If pjson is not null and pjson.exports is not null or undefined, then
    1. Return the result of PACKAGE_EXPORTS_RESOLVE(packageURL, packageSubpath, pjson.exports, defaultConditions).
  2. Otherwise, if packageSubpath is equal to ".", then
    If pjson.main is a string, then
    1. Return the URL resolution of main in packageURL.

Copy link
Contributor

@kherock kherock Jan 15, 2023

Choose a reason for hiding this comment

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

In my projects, prior to export maps, we were able to use the same package entrypoint for both CSS and JS with a top-level main and style fields. The constraint of Node's resolver algorithm that Vite is obeying here makes the pattern of having one entrypoint for both JS and style impossible when ESM exports are defined since Vite's current CSS resolver will always prefer the JavaScript import or require conditions from the exports map and ignore top level style fields. So to be consistent with Node's resolver spec, we need #7817.

However I would also argue that this PR isn't breaking any spec - the resources in question here are not ES Modules, they are stylesheets importing other stylesheets. When I write @use in Sass, I expect that my SCSS will resolve in accordance with Sass's own module resolution rules. The closest thing that Sass has decided there is some general consensus to use Node's own import algorithm sass/sass#2739 (comment). In the absence of any real convention, I think this PR or #7187 are the only community-established ways forward.

Copy link
Author

Choose a reason for hiding this comment

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

Following what @bluwy said, we are trying to diversify imports in our projects. For the JS entrypoint we are still using the module name, while for the stylesheet we have added the /style suffix to all the @import in our CSS files. Also, we've added "./style": "./dist/my-component.css" to export maps.

It's a lot of work, because it means updating hundreds of imports that until now worked with the top-level style field, but I have to admit that it makes sense.

@bluwy
Copy link
Member

bluwy commented Feb 26, 2023

as we're moving forward with #7817, I'll close this in favour of it.

@bluwy bluwy closed this Feb 26, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants