mini-css-extract-plugin icon indicating copy to clipboard operation
mini-css-extract-plugin copied to clipboard

fix: improve esMododule exports

Open jantimon opened this issue 1 year ago • 5 comments

This PR contains a:

  • [ ] bugfix
  • [x] new feature
  • [ ] code refactor
  • [ ] test update
  • [ ] typo fix
  • [ ] metadata update

Motivation / Use-Case

With esModule: false the mini-css-extract-plugin generates JS modules like this:

module.exports = {
  foo: "src-styles-foo",
  bar: "src-styles-bar",
};

This allows the following import:

import * as styles from "./styles.css";
import styles from "./styles.css";
import { foo } from "./styles.css";

With esModule: true the mini-css-extract-plugin generates JS modules like this:

export {
  "foo": "src-styles-foo",
  "bar": "src-styles-bar"
};

As there is no default export, the following import will not work:

import styles from "./styles.css"; // Fails

Interestingly the test case es-named-export tests for it:

https://github.com/webpack-contrib/mini-css-extract-plugin/blob/master/test/cases/es-named-export/index.js

import css, { aClass, bClass, cClass } from "./style.css";

However when tested manually, the test case fails:

export 'default' (imported as 'css') was not found in './style.css'

This PR adds the defaultExport option to the mini-css-extract-plugin which will allow the user to write the import exactly as in the es-named-exports test case

Breaking Changes

This feature is introduces behind an option. Therefore this is a non-breaking change. However changing the named export would probably also be not a breaking change)

jantimon avatar Feb 28 '24 16:02 jantimon

CLA Signed

The committers listed above are authorized under a signed CLA.

  • :white_check_mark: login: jantimon / name: Jan Nicklas (1787dab814042c324e0f07e72bfeb55567bc7831, 023d85cd1c065783f08b3c6f0c003c7fcb5656a5, 9e1c005409e7fcfce7af678cd9f58ca641b8611f)
  • :white_check_mark: login: alexander-akait / name: Alexander Akait (657af90ab28419eacc1b4873541011f353da01ed, fe1faa330a210c3e9fb7657d8958830b4a68ff92, ddb84c682b821ed949b5710d1fea1ed2722151cd)

@alexander-akait - I added it to the namedExport case - is it okay like this?

jantimon avatar Feb 29 '24 08:02 jantimon

@jantimon Just want to clarify, do you want to use and default and named export together?

alexander-akait avatar Mar 04 '24 17:03 alexander-akait

yes for backwards compatibility - right now nextjs allows both

nextjs uses mini-css-extract-plugin but is explicitly setting esModule: false

unfortunately esModule: false has the drawback that it prevents webpacks esmodule optimizations

so my idea was to switch to esModule but also allow named and default exports just like esModule: false

mini-extract-plugin has also a (currently broken) test on master which mixes default and named imports with esModules:

https://github.com/webpack-contrib/mini-css-extract-plugin/blob/master/test/cases/es-named-export/index.js

jantimon avatar Mar 05 '24 02:03 jantimon

@jantimon I see, we need to verify webpack (experimental.css) work the same (or provide an option to do it) and align with this plugin, I will investigate it tomorrow

alexander-akait avatar Mar 07 '24 14:03 alexander-akait

Sorry for delay, I done the same for built-in CSS support - https://github.com/webpack/webpack/pull/18271/ but want some dicussion with trspack team to align behaviour, then it will be merged I will do the same here

alexander-akait avatar Apr 02 '24 14:04 alexander-akait

@jantimon I put it under the option, because we still recommend to use only a named export to be better compatibility with future https://web.dev/articles/css-module-scripts

alexander-akait avatar Apr 02 '24 18:04 alexander-akait

@alexander-akait thanks for merging 🎉

Initially I added the default export also behind a feature flag so it's totally fine for me that you brought that back..

However I have one question - should the following css module code cause a warning for better future compatibility?

example.module.css

.default {
  color: red
} 

jantimon avatar Apr 03 '24 07:04 jantimon

@jantimon make sense, but I think better to make it in css-loader

alexander-akait avatar Apr 03 '24 10:04 alexander-akait