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

Add ability to export as es6 modules instead of commonjs #618

Closed
remcohaszing opened this issue Oct 5, 2017 · 3 comments
Closed

Add ability to export as es6 modules instead of commonjs #618

remcohaszing opened this issue Oct 5, 2017 · 3 comments

Comments

@remcohaszing
Copy link

Do you want to request a feature or report a bug? feature

What is the current behavior?

css-loader always outputs commonjs modules when modules is set to true.

What is the expected behavior?

To have the ability to output es6 modules instead.

If this is a feature request, what is motivation or use case for changing the behavior?

Let's say there is a file main.js:

import { myClassName } from './style-es6';


document.body.classList.add(myClassName);

And there is a file style.css:

.my-class-name {
  color: green;
}

This would be converted to the following JavaScript module:

module.exports = {
  myClassName: 'hash',
  'my-class-name': 'hash',
};

When this is then bundled by webpack, the generated output (with the webpack bootstrap removed) looks like the code below. This means that for each css file an object is defined to map the CSS classes; this object exported; the object is imported; and the property is read from the imported module.

/******/ ([
/* 0 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__style_commonjs__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__style_commonjs___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0__style_commonjs__);



document.body.classList.add(__WEBPACK_IMPORTED_MODULE_0__style_commonjs__["myClassName"]);


/***/ }),
/* 1 */
/***/ (function(module, exports) {

module.exports = {
  myClassName: 'hash',
  'my-class-name': 'hash',
};


/***/ })
/******/ ]);

I suggest to add an option to generate es6 modules instead. This es6 module would import all class mappings as a serie of exported constants. Because JavaScript constants may not have hyphens in their names, this always converts names to camel case.

This means that the example above would get converted to:

export const myClassName = 'hash';

When this is combined with the ModuleConcatenationPlugin, the generated code looks like this:

/******/ ([
/* 0 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });

// CONCATENATED MODULE: ./app/style-es6.js
const myClassName = 'hash';

// CONCATENATED MODULE: ./app/main.js



document.body.classList.add(myClassName);


/***/ })
/******/ ]);

This has several benefits:

  • There are fewer JavaScript function scopes.
  • The bundle is already smaller.
  • A minifier will be able to minify variable names, or even inline class names if they're only used once.
@remcohaszing
Copy link
Author

This would solve #612

@michael-ciniawsky
Copy link
Member

michael-ciniawsky commented Oct 5, 2017

This is highly required and 'in progress' already, but won't likely happen anytime soon. See https://medium.com/webpack/the-new-css-workflow-step-1-79583bd107d7 for more info on this topic :)

@michael-ciniawsky
Copy link
Member

All whole ecosystem e.g url/file-loader, style-loader, extract-text-webpack-plugin would break and there are other downsides to the current approach taken by css-loader anyways

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants