Skip to content

Commit

Permalink
feat: support named exports with any characters
Browse files Browse the repository at this point in the history
  • Loading branch information
alexander-akait committed Feb 1, 2024
1 parent aeb97fc commit b656c5c
Show file tree
Hide file tree
Showing 19 changed files with 401 additions and 54 deletions.
24 changes: 12 additions & 12 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -68,7 +68,7 @@
"bootstrap": "^4.6.2",
"cross-env": "^7.0.3",
"cspell": "^6.31.1",
"css-loader": "^6.9.0",
"css-loader": "^6.10.0",
"del": "^6.0.0",
"del-cli": "^4.0.0",
"es-check": "^7.1.0",
Expand Down
46 changes: 34 additions & 12 deletions src/loader.js
Expand Up @@ -245,22 +245,44 @@ function pitch(request) {
return;
}

const result = locals
? namedExport
? Object.keys(locals)
const result = (function makeResult() {
if (locals) {
if (namedExport) {
const identifiers = Array.from(
(function* generateIdentifiers() {
let identifierId = 0;

for (const key of Object.keys(locals)) {
identifierId += 1;

yield [`_${identifierId.toString(16)}`, key];
}
})()
);

const localsString = identifiers
.map(
(key) =>
`\nexport var ${key} = ${stringifyLocal(
([id, key]) =>
`\nvar ${id} = ${stringifyLocal(
/** @type {Locals} */ (locals)[key]
)};`
)
.join("")
: `\n${
esModule ? "export default" : "module.exports ="
} ${JSON.stringify(locals)};`
: esModule
? `\nexport {};`
: "";
.join("");
const exportsString = `export { ${identifiers
.map(([id, key]) => `${id} as ${JSON.stringify(key)}`)
.join(", ")} }`;

return `${localsString}\n${exportsString}\n`;
}

return `\n${
esModule ? "export default" : "module.exports = "
} ${JSON.stringify(locals)};`;
} else if (esModule) {
return "\nexport {};";
}
return "";
})();

let resultSource = `// extracted by ${MiniCssExtractPlugin.pluginName}`;

Expand Down
Expand Up @@ -7,12 +7,14 @@

__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ cnA: () => (/* binding */ cnA),
/* harmony export */ cnB: () => (/* binding */ cnB)
/* harmony export */ cnA: () => (/* binding */ _1),
/* harmony export */ cnB: () => (/* binding */ _2)
/* harmony export */ });
// extracted by mini-css-extract-plugin
var cnA = () => "class-name-a";
var cnB = () => "class-name-b";
var _1 = () => "class-name-a";
var _2 = () => "class-name-b";



/***/ })
/******/ ]);
Expand Down
20 changes: 13 additions & 7 deletions test/cases/es-module-concatenation-modules/expected/main.js
Expand Up @@ -41,21 +41,21 @@ __webpack_require__.r(__webpack_exports__);
__webpack_require__.d(__webpack_exports__, {
a: () => (/* reexport */ a_namespaceObject),
b: () => (/* reexport */ b_namespaceObject),
c: () => (/* reexport */ c)
c: () => (/* reexport */ c_1)
});

// NAMESPACE OBJECT: ./a.css
var a_namespaceObject = {};
__webpack_require__.r(a_namespaceObject);
__webpack_require__.d(a_namespaceObject, {
a: () => (a)
a: () => (_1)
});

// NAMESPACE OBJECT: ./b.css
var b_namespaceObject = {};
__webpack_require__.r(b_namespaceObject);
__webpack_require__.d(b_namespaceObject, {
b: () => (b)
b: () => (b_1)
});

// NAMESPACE OBJECT: ./index.js
Expand All @@ -64,18 +64,24 @@ __webpack_require__.r(index_namespaceObject);
__webpack_require__.d(index_namespaceObject, {
a: () => (a_namespaceObject),
b: () => (b_namespaceObject),
c: () => (c)
c: () => (c_1)
});

;// CONCATENATED MODULE: ./a.css
// extracted by mini-css-extract-plugin
var a = "foo__a";
var _1 = "foo__a";


;// CONCATENATED MODULE: ./b.css
// extracted by mini-css-extract-plugin
var b = "foo__b";
var b_1 = "foo__b";


;// CONCATENATED MODULE: ./c.css
// extracted by mini-css-extract-plugin
var c = "foo__c";
var c_1 = "foo__c";


;// CONCATENATED MODULE: ./index.js
/* eslint-disable import/no-namespace */

Expand Down
12 changes: 12 additions & 0 deletions test/cases/es-named-export-as-is-output-module/expected/main.css
@@ -0,0 +1,12 @@
.Xh041yLR4iCP4RGjge50 {
background: red;
}

.NMuRsxoDwvW8BhSXhFAY {
color: green;
}

.ayWIv09rPsAqE2JznIsI {
color: blue;
}

87 changes: 87 additions & 0 deletions test/cases/es-named-export-as-is-output-module/expected/main.mjs
@@ -0,0 +1,87 @@
/******/ 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 */ "a-class": () => (/* binding */ _1),
/* harmony export */ b__class: () => (/* binding */ _2),
/* harmony export */ cClass: () => (/* binding */ _3)
/* harmony export */ });
// extracted by mini-css-extract-plugin
var _1 = "Xh041yLR4iCP4RGjge50";
var _2 = "NMuRsxoDwvW8BhSXhFAY";
var _3 = "ayWIv09rPsAqE2JznIsI";



/***/ })
/******/ ]);
/************************************************************************/
/******/ // 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 _style_css__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);


// eslint-disable-next-line no-console
console.log({ css: _style_css__WEBPACK_IMPORTED_MODULE_0__["default"], aClass: _style_css__WEBPACK_IMPORTED_MODULE_0__["a-class"], bClass: _style_css__WEBPACK_IMPORTED_MODULE_0__.b__class, cClass: _style_css__WEBPACK_IMPORTED_MODULE_0__.cClass });

})();

8 changes: 8 additions & 0 deletions test/cases/es-named-export-as-is-output-module/index.js
@@ -0,0 +1,8 @@
import css, {
"a-class" as aClass,
"b__class" as bClass,
cClass,
} from "./style.css";

// eslint-disable-next-line no-console
console.log({ css, aClass, bClass, cClass });
11 changes: 11 additions & 0 deletions test/cases/es-named-export-as-is-output-module/style.css
@@ -0,0 +1,11 @@
.a-class {
background: red;
}

.b__class {
color: green;
}

.cClass {
color: blue;
}
38 changes: 38 additions & 0 deletions test/cases/es-named-export-as-is-output-module/webpack.config.js
@@ -0,0 +1,38 @@
import Self from "../../../src";

module.exports = {
entry: "./index.js",
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: Self.loader,
},
{
loader: "css-loader",
options: {
esModule: true,
modules: {
namedExport: true,
exportLocalsConvention: "asIs",
},
},
},
],
},
],
},
output: {
module: true,
},
experiments: {
outputModule: true,
},
plugins: [
new Self({
filename: "[name].css",
}),
],
};
12 changes: 12 additions & 0 deletions test/cases/es-named-export-as-is/expected/main.css
@@ -0,0 +1,12 @@
.Xh041yLR4iCP4RGjge50 {
background: red;
}

.NMuRsxoDwvW8BhSXhFAY {
color: green;
}

.ayWIv09rPsAqE2JznIsI {
color: blue;
}

0 comments on commit b656c5c

Please sign in to comment.