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

feat: esModule option #441

Merged
merged 1 commit into from
Dec 19, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Loading