Skip to content

Commit 1787dab

Browse files
committed
feat: add defaultExport option
1 parent c7ff30d commit 1787dab

File tree

11 files changed

+221
-10
lines changed

11 files changed

+221
-10
lines changed

README.md

+42
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,7 @@ module.exports = {
407407
- **[`publicPath`](#publicPath)**
408408
- **[`emit`](#emit)**
409409
- **[`esModule`](#esModule)**
410+
- **[`defaultExport`](#defaultExport)**
410411

411412
#### `publicPath`
412413

@@ -549,6 +550,47 @@ module.exports = {
549550
};
550551
```
551552

553+
#### `defaultExport`
554+
555+
Type:
556+
557+
```ts
558+
type defaultExport = boolean;
559+
```
560+
561+
Default: `false`
562+
563+
By default, `mini-css-extract-plugin` generates JS modules with a default export.
564+
However for name exports, each local is exported as a named export.
565+
566+
In case you need both default and named exports, you can enable this option:
567+
568+
**webpack.config.js**
569+
570+
```js
571+
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
572+
573+
module.exports = {
574+
plugins: [new MiniCssExtractPlugin()],
575+
module: {
576+
rules: [
577+
{
578+
test: /\.css$/i,
579+
use: [
580+
{
581+
loader: MiniCssExtractPlugin.loader,
582+
options: {
583+
defaultExport: true,
584+
},
585+
},
586+
"css-loader",
587+
],
588+
},
589+
],
590+
},
591+
};
592+
```
593+
552594
## Examples
553595

554596
### Recommended

src/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ const {
3636
* @property {string | ((resourcePath: string, rootContext: string) => string)} [publicPath]
3737
* @property {boolean} [emit]
3838
* @property {boolean} [esModule]
39+
* @property {boolean} [defaultExport]
3940
* @property {string} [layer]
4041
*/
4142

src/loader-options.json

+5
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@
2525
"description": "Generates JS modules that use the ES modules syntax.",
2626
"link": "https://github.com/webpack-contrib/mini-css-extract-plugin#esmodule"
2727
},
28+
"defaultExport": {
29+
"type": "boolean",
30+
"description": "Generates JS modules with the default export syntax even for named exports.",
31+
"link": "https://github.com/webpack-contrib/mini-css-extract-plugin#defaultexports"
32+
},
2833
"layer": {
2934
"type": "string"
3035
}

src/loader.js

+9-2
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,11 @@ function pitch(request) {
124124
const esModule =
125125
typeof options.esModule !== "undefined" ? options.esModule : true;
126126

127+
const defaultExport =
128+
typeof options.defaultExport !== "undefined"
129+
? options.defaultExport
130+
: false;
131+
127132
/**
128133
* @param {Dependency[] | [null, object][]} dependencies
129134
*/
@@ -271,8 +276,10 @@ function pitch(request) {
271276
const exportsString = `export { ${identifiers
272277
.map(([id, key]) => `${id} as ${JSON.stringify(key)}`)
273278
.join(", ")} }`;
274-
275-
return `${localsString}\n${exportsString}\n`;
279+
const exportDefaultString = defaultExport
280+
? `export default ${JSON.stringify(locals)}\n`
281+
: "";
282+
return `${localsString}\n${exportsString}\n${exportDefaultString}`;
276283
}
277284

278285
return `\n${

test/__snapshots__/validate-loader-options.test.js.snap

+8-8
Original file line numberDiff line numberDiff line change
@@ -21,47 +21,47 @@ exports[`validate options should throw an error on the "publicPath" option with
2121
exports[`validate options should throw an error on the "unknown" option with "/test/" value 1`] = `
2222
"Invalid options object. Mini CSS Extract Plugin Loader has been initialized using an options object that does not match the API schema.
2323
- options has an unknown property 'unknown'. These properties are valid:
24-
object { publicPath?, emit?, esModule?, layer? }"
24+
object { publicPath?, emit?, esModule?, defaultExport?, layer? }"
2525
`;
2626
2727
exports[`validate options should throw an error on the "unknown" option with "[]" value 1`] = `
2828
"Invalid options object. Mini CSS Extract Plugin Loader has been initialized using an options object that does not match the API schema.
2929
- options has an unknown property 'unknown'. These properties are valid:
30-
object { publicPath?, emit?, esModule?, layer? }"
30+
object { publicPath?, emit?, esModule?, defaultExport?, layer? }"
3131
`;
3232
3333
exports[`validate options should throw an error on the "unknown" option with "{"foo":"bar"}" value 1`] = `
3434
"Invalid options object. Mini CSS Extract Plugin Loader has been initialized using an options object that does not match the API schema.
3535
- options has an unknown property 'unknown'. These properties are valid:
36-
object { publicPath?, emit?, esModule?, layer? }"
36+
object { publicPath?, emit?, esModule?, defaultExport?, layer? }"
3737
`;
3838
3939
exports[`validate options should throw an error on the "unknown" option with "{}" value 1`] = `
4040
"Invalid options object. Mini CSS Extract Plugin Loader has been initialized using an options object that does not match the API schema.
4141
- options has an unknown property 'unknown'. These properties are valid:
42-
object { publicPath?, emit?, esModule?, layer? }"
42+
object { publicPath?, emit?, esModule?, defaultExport?, layer? }"
4343
`;
4444
4545
exports[`validate options should throw an error on the "unknown" option with "1" value 1`] = `
4646
"Invalid options object. Mini CSS Extract Plugin Loader has been initialized using an options object that does not match the API schema.
4747
- options has an unknown property 'unknown'. These properties are valid:
48-
object { publicPath?, emit?, esModule?, layer? }"
48+
object { publicPath?, emit?, esModule?, defaultExport?, layer? }"
4949
`;
5050
5151
exports[`validate options should throw an error on the "unknown" option with "false" value 1`] = `
5252
"Invalid options object. Mini CSS Extract Plugin Loader has been initialized using an options object that does not match the API schema.
5353
- options has an unknown property 'unknown'. These properties are valid:
54-
object { publicPath?, emit?, esModule?, layer? }"
54+
object { publicPath?, emit?, esModule?, defaultExport?, layer? }"
5555
`;
5656
5757
exports[`validate options should throw an error on the "unknown" option with "test" value 1`] = `
5858
"Invalid options object. Mini CSS Extract Plugin Loader has been initialized using an options object that does not match the API schema.
5959
- options has an unknown property 'unknown'. These properties are valid:
60-
object { publicPath?, emit?, esModule?, layer? }"
60+
object { publicPath?, emit?, esModule?, defaultExport?, layer? }"
6161
`;
6262
6363
exports[`validate options should throw an error on the "unknown" option with "true" value 1`] = `
6464
"Invalid options object. Mini CSS Extract Plugin Loader has been initialized using an options object that does not match the API schema.
6565
- options has an unknown property 'unknown'. These properties are valid:
66-
object { publicPath?, emit?, esModule?, layer? }"
66+
object { publicPath?, emit?, esModule?, defaultExport?, layer? }"
6767
`;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
.foo__style__aClass {
2+
background: red;
3+
}
4+
5+
.foo__style__bClass {
6+
color: green;
7+
}
8+
9+
.foo__style__cClass {
10+
color: blue;
11+
}
12+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/******/ (() => { // webpackBootstrap
2+
/******/ "use strict";
3+
/******/ var __webpack_modules__ = ([
4+
/* 0 */,
5+
/* 1 */
6+
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
7+
8+
__webpack_require__.r(__webpack_exports__);
9+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
10+
/* harmony export */ aClass: () => (/* binding */ _1),
11+
/* harmony export */ bClass: () => (/* binding */ _2),
12+
/* harmony export */ cClass: () => (/* binding */ _3)
13+
/* harmony export */ });
14+
// extracted by mini-css-extract-plugin
15+
var _1 = "foo__style__aClass";
16+
var _2 = "foo__style__bClass";
17+
var _3 = "foo__style__cClass";
18+
19+
20+
21+
/***/ })
22+
/******/ ]);
23+
/************************************************************************/
24+
/******/ // The module cache
25+
/******/ var __webpack_module_cache__ = {};
26+
/******/
27+
/******/ // The require function
28+
/******/ function __webpack_require__(moduleId) {
29+
/******/ // Check if module is in cache
30+
/******/ var cachedModule = __webpack_module_cache__[moduleId];
31+
/******/ if (cachedModule !== undefined) {
32+
/******/ return cachedModule.exports;
33+
/******/ }
34+
/******/ // Create a new module (and put it into the cache)
35+
/******/ var module = __webpack_module_cache__[moduleId] = {
36+
/******/ // no module.id needed
37+
/******/ // no module.loaded needed
38+
/******/ exports: {}
39+
/******/ };
40+
/******/
41+
/******/ // Execute the module function
42+
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
43+
/******/
44+
/******/ // Return the exports of the module
45+
/******/ return module.exports;
46+
/******/ }
47+
/******/
48+
/************************************************************************/
49+
/******/ /* webpack/runtime/define property getters */
50+
/******/ (() => {
51+
/******/ // define getter functions for harmony exports
52+
/******/ __webpack_require__.d = (exports, definition) => {
53+
/******/ for(var key in definition) {
54+
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
55+
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
56+
/******/ }
57+
/******/ }
58+
/******/ };
59+
/******/ })();
60+
/******/
61+
/******/ /* webpack/runtime/hasOwnProperty shorthand */
62+
/******/ (() => {
63+
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
64+
/******/ })();
65+
/******/
66+
/******/ /* webpack/runtime/make namespace object */
67+
/******/ (() => {
68+
/******/ // define __esModule on exports
69+
/******/ __webpack_require__.r = (exports) => {
70+
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
71+
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
72+
/******/ }
73+
/******/ Object.defineProperty(exports, '__esModule', { value: true });
74+
/******/ };
75+
/******/ })();
76+
/******/
77+
/************************************************************************/
78+
var __webpack_exports__ = {};
79+
// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
80+
(() => {
81+
__webpack_require__.r(__webpack_exports__);
82+
/* harmony import */ var _style_css__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
83+
84+
85+
// eslint-disable-next-line no-console
86+
console.log({ css: _style_css__WEBPACK_IMPORTED_MODULE_0__["default"], aClass: _style_css__WEBPACK_IMPORTED_MODULE_0__.aClass, bClass: _style_css__WEBPACK_IMPORTED_MODULE_0__.bClass, cClass: _style_css__WEBPACK_IMPORTED_MODULE_0__.cClass });
87+
88+
})();
89+
90+
/******/ })()
91+
;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import css, { aClass, bClass, cClass } from "./style.css";
2+
3+
// eslint-disable-next-line no-console
4+
console.log({ css, aClass, bClass, cClass });
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
.aClass {
2+
background: red;
3+
}
4+
5+
.bClass {
6+
color: green;
7+
}
8+
9+
.cClass {
10+
color: blue;
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
const Self = require("../../../");
2+
3+
module.exports = {
4+
entry: "./index.js",
5+
module: {
6+
rules: [
7+
{
8+
test: /\.css$/,
9+
use: [
10+
{
11+
loader: Self.loader,
12+
options: {
13+
defaultExport: false,
14+
},
15+
},
16+
{
17+
loader: "css-loader",
18+
options: {
19+
esModule: true,
20+
modules: {
21+
namedExport: true,
22+
exportLocalsConvention: "asIs",
23+
localIdentName: "foo__[name]__[local]",
24+
},
25+
},
26+
},
27+
],
28+
},
29+
],
30+
},
31+
plugins: [
32+
new Self({
33+
filename: "[name].css",
34+
}),
35+
],
36+
};

types/index.d.ts

+2
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ type PluginOptions = {
147147
* @property {string | ((resourcePath: string, rootContext: string) => string)} [publicPath]
148148
* @property {boolean} [emit]
149149
* @property {boolean} [esModule]
150+
* @property {boolean} [defaultExport]
150151
* @property {string} [layer]
151152
*/
152153
/**
@@ -199,6 +200,7 @@ type LoaderOptions = {
199200
| undefined;
200201
emit?: boolean | undefined;
201202
esModule?: boolean | undefined;
203+
defaultExport?: boolean | undefined;
202204
layer?: string | undefined;
203205
};
204206
type NormalizedPluginOptions = {

0 commit comments

Comments
 (0)