From 8f77e19a89eca97b05f1855d2c851592e98ff774 Mon Sep 17 00:00:00 2001 From: HHX <57352881+houhongxu@users.noreply.github.com> Date: Mon, 19 Aug 2024 06:42:37 -0700 Subject: [PATCH] fix: add `export default {}` when CSS modules enabled and a file is empty for the `defaultExport` option --- src/loader.js | 14 +-- .../es-named-and-default-export-1/empty.css | 0 .../expected/main.css | 1 + .../expected/main.js | 85 +++++++++++++++++++ .../es-named-and-default-export-1/index.js | 4 + .../webpack.config.js | 34 ++++++++ 6 files changed, 132 insertions(+), 6 deletions(-) create mode 100644 test/cases/es-named-and-default-export-1/empty.css create mode 100644 test/cases/es-named-and-default-export-1/expected/main.css create mode 100644 test/cases/es-named-and-default-export-1/expected/main.js create mode 100644 test/cases/es-named-and-default-export-1/index.js create mode 100644 test/cases/es-named-and-default-export-1/webpack.config.js diff --git a/src/loader.js b/src/loader.js index 5c0b04b1..e4217f5c 100644 --- a/src/loader.js +++ b/src/loader.js @@ -255,6 +255,11 @@ function pitch(request) { } const result = (function makeResult() { + const defaultExport = + typeof options.defaultExport !== "undefined" + ? options.defaultExport + : false; + if (locals) { if (namedExport) { const identifiers = Array.from( @@ -281,11 +286,6 @@ function pitch(request) { .map(([id, key]) => `${id} as ${JSON.stringify(key)}`) .join(", ")} }`; - const defaultExport = - typeof options.defaultExport !== "undefined" - ? options.defaultExport - : false; - return defaultExport ? `${localsString}\n${exportsString}\nexport default { ${identifiers .map(([id, key]) => `${JSON.stringify(key)}: ${id}`) @@ -297,7 +297,9 @@ function pitch(request) { esModule ? "export default" : "module.exports = " } ${JSON.stringify(locals)};`; } else if (esModule) { - return "\nexport {};"; + return defaultExport + ? "\nexport {};export default {};" + : "\nexport {};"; } return ""; })(); diff --git a/test/cases/es-named-and-default-export-1/empty.css b/test/cases/es-named-and-default-export-1/empty.css new file mode 100644 index 00000000..e69de29b diff --git a/test/cases/es-named-and-default-export-1/expected/main.css b/test/cases/es-named-and-default-export-1/expected/main.css new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/test/cases/es-named-and-default-export-1/expected/main.css @@ -0,0 +1 @@ + diff --git a/test/cases/es-named-and-default-export-1/expected/main.js b/test/cases/es-named-and-default-export-1/expected/main.js new file mode 100644 index 00000000..1d321d3a --- /dev/null +++ b/test/cases/es-named-and-default-export-1/expected/main.js @@ -0,0 +1,85 @@ +/******/ (() => { // webpackBootstrap +/******/ "use strict"; +/******/ var __webpack_modules__ = ([ +/* 0 */, +/* 1 */ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +// extracted by mini-css-extract-plugin +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({}); + +/***/ }) +/******/ ]); +/************************************************************************/ +/******/ // The module cache +/******/ var __webpack_module_cache__ = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ // Check if module is in cache +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = __webpack_module_cache__[moduleId] = { +/******/ // no module.id needed +/******/ // no module.loaded needed +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/************************************************************************/ +/******/ /* webpack/runtime/define property getters */ +/******/ (() => { +/******/ // define getter functions for harmony exports +/******/ __webpack_require__.d = (exports, definition) => { +/******/ for(var key in definition) { +/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { +/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); +/******/ } +/******/ } +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/hasOwnProperty shorthand */ +/******/ (() => { +/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) +/******/ })(); +/******/ +/******/ /* webpack/runtime/make namespace object */ +/******/ (() => { +/******/ // define __esModule on exports +/******/ __webpack_require__.r = (exports) => { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ })(); +/******/ +/************************************************************************/ +var __webpack_exports__ = {}; +// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. +(() => { +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _empty_css__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1); + + +// eslint-disable-next-line no-console +console.log({ css: _empty_css__WEBPACK_IMPORTED_MODULE_0__["default"] }); + +})(); + +/******/ })() +; \ No newline at end of file diff --git a/test/cases/es-named-and-default-export-1/index.js b/test/cases/es-named-and-default-export-1/index.js new file mode 100644 index 00000000..e42dfb9a --- /dev/null +++ b/test/cases/es-named-and-default-export-1/index.js @@ -0,0 +1,4 @@ +import css from "./empty.css"; + +// eslint-disable-next-line no-console +console.log({ css }); diff --git a/test/cases/es-named-and-default-export-1/webpack.config.js b/test/cases/es-named-and-default-export-1/webpack.config.js new file mode 100644 index 00000000..b58d12f5 --- /dev/null +++ b/test/cases/es-named-and-default-export-1/webpack.config.js @@ -0,0 +1,34 @@ +import Self from "../../../src"; + +module.exports = { + entry: "./index.js", + module: { + rules: [ + { + test: /\.css$/, + use: [ + { + loader: Self.loader, + options: { + defaultExport: true, + }, + }, + { + loader: "css-loader", + options: { + esModule: true, + modules: { + namedExport: true, + }, + }, + }, + ], + }, + ], + }, + plugins: [ + new Self({ + filename: "[name].css", + }), + ], +};