Skip to content

Commit

Permalink
feat: esModule option (#441)
Browse files Browse the repository at this point in the history
  • Loading branch information
evilebottnawi committed Dec 19, 2019
1 parent 907aed8 commit 3415266
Show file tree
Hide file tree
Showing 8 changed files with 1,201 additions and 78 deletions.
29 changes: 29 additions & 0 deletions README.md
Expand Up @@ -67,6 +67,7 @@ module.exports = {
| **`attributes`** | `{Object}` | `{}` | Adds custom attributes to tag |
| **`insert`** | `{String\|Function}` | `head` | Inserts tag at the given position into the DOM |
| **`base`** | `{Number}` | `true` | Sets module ID base (DLLPlugin) |
| **`esModule`** | `{Boolean}` | `false` | Use ES modules syntax |

### `injectType`

Expand Down Expand Up @@ -548,6 +549,34 @@ module.exports = {
};
```

### `esModule`

Type: `Boolean`
Default: `false`

By default, `style-loader` generates JS modules that use the CommonJS modules syntax.
There are some cases in which using ES modules is beneficial, like in the case of [module concatenation](https://webpack.js.org/plugins/module-concatenation-plugin/) and [tree shaking](https://webpack.js.org/guides/tree-shaking/).

You can enable a ES module syntax using:

**webpack.config.js**

```js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: 'css-loader',
options: {
esModule: true,
},
},
],
},
};
```

## Examples

### Source maps
Expand Down
183 changes: 123 additions & 60 deletions src/index.js
Expand Up @@ -21,8 +21,11 @@ loaderApi.pitch = function loader(request) {
: typeof options.insert === 'string'
? JSON.stringify(options.insert)
: options.insert.toString();

const injectType = options.injectType || 'styleTag';
const esModule =
typeof options.esModule !== 'undefined' ? options.esModule : false;

delete options.esModule;

switch (injectType) {
case 'linkTag': {
Expand All @@ -32,13 +35,18 @@ if (module.hot) {
module.hot.accept(
${loaderUtils.stringifyRequest(this, `!!${request}`)},
function() {
var newContent = require(${loaderUtils.stringifyRequest(
this,
`!!${request}`
)});
newContent = newContent.__esModule ? newContent.default : newContent;
update(newContent);
${
esModule
? `update(content);`
: `var newContent = require(${loaderUtils.stringifyRequest(
this,
`!!${request}`
)});
newContent = newContent.__esModule ? newContent.default : newContent;
update(newContent);`
}
}
);
Expand All @@ -48,18 +56,34 @@ if (module.hot) {
}`
: '';

return `var options = ${JSON.stringify(options)};
return `${
esModule
? `import api from ${loaderUtils.stringifyRequest(
this,
`!${path.join(__dirname, 'runtime/injectStylesIntoLinkTag.js')}`
)};
import content from ${loaderUtils.stringifyRequest(
this,
`!!${request}`
)};`
: `var api = require(${loaderUtils.stringifyRequest(
this,
`!${path.join(__dirname, 'runtime/injectStylesIntoLinkTag.js')}`
)});
var content = require(${loaderUtils.stringifyRequest(
this,
`!!${request}`
)});
content = content.__esModule ? content.default : content;`
}
options.insert = ${insert};
var options = ${JSON.stringify(options)};
var content = require(${loaderUtils.stringifyRequest(this, `!!${request}`)});
content = content.__esModule ? content.default : content;
options.insert = ${insert};
var api = require(${loaderUtils.stringifyRequest(
this,
`!${path.join(__dirname, 'runtime/injectStylesIntoLinkTag.js')}`
)});
var update = api(content, options);
${hmrCode}`;
}

Expand All @@ -71,9 +95,9 @@ ${hmrCode}`;
? `
if (module.hot) {
var lastRefs = module.hot.data && module.hot.data.refs || 0;
if (lastRefs) {
exports.use();
exported.use();
if (!content.locals) {
refs = lastRefs;
Expand All @@ -94,42 +118,62 @@ if (module.hot) {
}`
: '';

return `var refs = 0;
var dispose;
var content = require(${loaderUtils.stringifyRequest(this, `!!${request}`)});
content = content.__esModule ? content.default : content;
return `${
esModule
? `import api from ${loaderUtils.stringifyRequest(
this,
`!${path.join(__dirname, 'runtime/injectStylesIntoStyleTag.js')}`
)};
import content from ${loaderUtils.stringifyRequest(
this,
`!!${request}`
)};`
: `var api = require(${loaderUtils.stringifyRequest(
this,
`!${path.join(__dirname, 'runtime/injectStylesIntoStyleTag.js')}`
)});
var content = require(${loaderUtils.stringifyRequest(
this,
`!!${request}`
)});
content = content.__esModule ? content.default : content;
if (typeof content === 'string') {
content = [[module.id, content, '']];
}`
}
var refs = 0;
var dispose;
var options = ${JSON.stringify(options)};
options.insert = ${insert};
options.singleton = ${isSingleton};
if (typeof content === 'string') {
content = [[module.id, content, '']];
}
var exported = {};
if (content.locals) {
exports.locals = content.locals;
exported.locals = content.locals;
}
exports.use = function() {
exported.use = function() {
if (!(refs++)) {
var api = require(${loaderUtils.stringifyRequest(
this,
`!${path.join(__dirname, 'runtime/injectStylesIntoStyleTag.js')}`
)});
dispose = api(content, options);
}
return exports;
return exported;
};
exports.unuse = function() {
exported.unuse = function() {
if (refs > 0 && !--refs) {
dispose();
dispose = null;
}
};
${esModule ? 'export default' : 'module.exports ='} exported;
${hmrCode}
`;
}
Expand All @@ -146,17 +190,22 @@ if (module.hot) {
module.hot.accept(
${loaderUtils.stringifyRequest(this, `!!${request}`)},
function () {
var newContent = require(${loaderUtils.stringifyRequest(
this,
`!!${request}`
)});
newContent = newContent.__esModule ? newContent.default : newContent;
if (typeof newContent === 'string') {
newContent = [[module.id, newContent, '']];
${
esModule
? `update(content);`
: `var newContent = require(${loaderUtils.stringifyRequest(
this,
`!!${request}`
)});
newContent = newContent.__esModule ? newContent.default : newContent;
if (typeof newContent === 'string') {
newContent = [[module.id, newContent, '']];
}
update(newContent);`
}
update(newContent);
}
)
}
Expand All @@ -167,30 +216,44 @@ if (module.hot) {
}`
: '';

return `var content = require(${loaderUtils.stringifyRequest(
this,
`!!${request}`
)});
content = content.__esModule ? content.default : content;
if (typeof content === 'string') {
content = [[module.id, content, '']];
}
return `${
esModule
? `import api from ${loaderUtils.stringifyRequest(
this,
`!${path.join(__dirname, 'runtime/injectStylesIntoStyleTag.js')}`
)};
import content from ${loaderUtils.stringifyRequest(
this,
`!!${request}`
)};
var clonedContent = content;`
: `var api = require(${loaderUtils.stringifyRequest(
this,
`!${path.join(__dirname, 'runtime/injectStylesIntoStyleTag.js')}`
)});
var content = require(${loaderUtils.stringifyRequest(
this,
`!!${request}`
)});
content = content.__esModule ? content.default : content;
if (typeof content === 'string') {
content = [[module.id, content, '']];
}`
}
var options = ${JSON.stringify(options)}
var options = ${JSON.stringify(options)};
options.insert = ${insert};
options.singleton = ${isSingleton};
var api = require(${loaderUtils.stringifyRequest(
this,
`!${path.join(__dirname, 'runtime/injectStylesIntoStyleTag.js')}`
)});
var update = api(content, options);
if (content.locals) {
module.exports = content.locals;
}
var exported = content.locals ? content.locals : {};
${esModule ? 'export default' : 'module.exports ='} exported;
${hmrCode}`;
}
}
Expand Down
4 changes: 4 additions & 0 deletions src/options.json
Expand Up @@ -29,6 +29,10 @@
"base": {
"description": "Sets module ID base for DLLPlugin (https://github.com/webpack-contrib/style-loader#base).",
"type": "number"
},
"esModule": {
"description": "Use the ES modules syntax (https://github.com/webpack-contrib/css-loader#esmodule).",
"type": "boolean"
}
},
"additionalProperties": false
Expand Down

0 comments on commit 3415266

Please sign in to comment.