Skip to content

Commit 3415266

Browse files
feat: esModule option (#441)
1 parent 907aed8 commit 3415266

8 files changed

+1201
-78
lines changed

README.md

+29
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ module.exports = {
6767
| **`attributes`** | `{Object}` | `{}` | Adds custom attributes to tag |
6868
| **`insert`** | `{String\|Function}` | `head` | Inserts tag at the given position into the DOM |
6969
| **`base`** | `{Number}` | `true` | Sets module ID base (DLLPlugin) |
70+
| **`esModule`** | `{Boolean}` | `false` | Use ES modules syntax |
7071

7172
### `injectType`
7273

@@ -548,6 +549,34 @@ module.exports = {
548549
};
549550
```
550551

552+
### `esModule`
553+
554+
Type: `Boolean`
555+
Default: `false`
556+
557+
By default, `style-loader` generates JS modules that use the CommonJS modules syntax.
558+
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/).
559+
560+
You can enable a ES module syntax using:
561+
562+
**webpack.config.js**
563+
564+
```js
565+
module.exports = {
566+
module: {
567+
rules: [
568+
{
569+
test: /\.css$/i,
570+
loader: 'css-loader',
571+
options: {
572+
esModule: true,
573+
},
574+
},
575+
],
576+
},
577+
};
578+
```
579+
551580
## Examples
552581

553582
### Source maps

src/index.js

+123-60
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,11 @@ loaderApi.pitch = function loader(request) {
2121
: typeof options.insert === 'string'
2222
? JSON.stringify(options.insert)
2323
: options.insert.toString();
24-
2524
const injectType = options.injectType || 'styleTag';
25+
const esModule =
26+
typeof options.esModule !== 'undefined' ? options.esModule : false;
27+
28+
delete options.esModule;
2629

2730
switch (injectType) {
2831
case 'linkTag': {
@@ -32,13 +35,18 @@ if (module.hot) {
3235
module.hot.accept(
3336
${loaderUtils.stringifyRequest(this, `!!${request}`)},
3437
function() {
35-
var newContent = require(${loaderUtils.stringifyRequest(
36-
this,
37-
`!!${request}`
38-
)});
39-
newContent = newContent.__esModule ? newContent.default : newContent;
40-
41-
update(newContent);
38+
${
39+
esModule
40+
? `update(content);`
41+
: `var newContent = require(${loaderUtils.stringifyRequest(
42+
this,
43+
`!!${request}`
44+
)});
45+
46+
newContent = newContent.__esModule ? newContent.default : newContent;
47+
48+
update(newContent);`
49+
}
4250
}
4351
);
4452
@@ -48,18 +56,34 @@ if (module.hot) {
4856
}`
4957
: '';
5058

51-
return `var options = ${JSON.stringify(options)};
59+
return `${
60+
esModule
61+
? `import api from ${loaderUtils.stringifyRequest(
62+
this,
63+
`!${path.join(__dirname, 'runtime/injectStylesIntoLinkTag.js')}`
64+
)};
65+
import content from ${loaderUtils.stringifyRequest(
66+
this,
67+
`!!${request}`
68+
)};`
69+
: `var api = require(${loaderUtils.stringifyRequest(
70+
this,
71+
`!${path.join(__dirname, 'runtime/injectStylesIntoLinkTag.js')}`
72+
)});
73+
var content = require(${loaderUtils.stringifyRequest(
74+
this,
75+
`!!${request}`
76+
)});
77+
78+
content = content.__esModule ? content.default : content;`
79+
}
5280
53-
options.insert = ${insert};
81+
var options = ${JSON.stringify(options)};
5482
55-
var content = require(${loaderUtils.stringifyRequest(this, `!!${request}`)});
56-
content = content.__esModule ? content.default : content;
83+
options.insert = ${insert};
5784
58-
var api = require(${loaderUtils.stringifyRequest(
59-
this,
60-
`!${path.join(__dirname, 'runtime/injectStylesIntoLinkTag.js')}`
61-
)});
6285
var update = api(content, options);
86+
6387
${hmrCode}`;
6488
}
6589

@@ -71,9 +95,9 @@ ${hmrCode}`;
7195
? `
7296
if (module.hot) {
7397
var lastRefs = module.hot.data && module.hot.data.refs || 0;
74-
98+
7599
if (lastRefs) {
76-
exports.use();
100+
exported.use();
77101
78102
if (!content.locals) {
79103
refs = lastRefs;
@@ -94,42 +118,62 @@ if (module.hot) {
94118
}`
95119
: '';
96120

97-
return `var refs = 0;
98-
var dispose;
99-
var content = require(${loaderUtils.stringifyRequest(this, `!!${request}`)});
100-
content = content.__esModule ? content.default : content;
121+
return `${
122+
esModule
123+
? `import api from ${loaderUtils.stringifyRequest(
124+
this,
125+
`!${path.join(__dirname, 'runtime/injectStylesIntoStyleTag.js')}`
126+
)};
127+
import content from ${loaderUtils.stringifyRequest(
128+
this,
129+
`!!${request}`
130+
)};`
131+
: `var api = require(${loaderUtils.stringifyRequest(
132+
this,
133+
`!${path.join(__dirname, 'runtime/injectStylesIntoStyleTag.js')}`
134+
)});
135+
var content = require(${loaderUtils.stringifyRequest(
136+
this,
137+
`!!${request}`
138+
)});
139+
140+
content = content.__esModule ? content.default : content;
141+
142+
if (typeof content === 'string') {
143+
content = [[module.id, content, '']];
144+
}`
145+
}
101146
147+
var refs = 0;
148+
var dispose;
102149
var options = ${JSON.stringify(options)};
103150
104151
options.insert = ${insert};
105152
options.singleton = ${isSingleton};
106153
107-
if (typeof content === 'string') {
108-
content = [[module.id, content, '']];
109-
}
154+
var exported = {};
110155
111156
if (content.locals) {
112-
exports.locals = content.locals;
157+
exported.locals = content.locals;
113158
}
114159
115-
exports.use = function() {
160+
exported.use = function() {
116161
if (!(refs++)) {
117-
var api = require(${loaderUtils.stringifyRequest(
118-
this,
119-
`!${path.join(__dirname, 'runtime/injectStylesIntoStyleTag.js')}`
120-
)});
121162
dispose = api(content, options);
122163
}
123164
124-
return exports;
165+
return exported;
125166
};
126167
127-
exports.unuse = function() {
168+
exported.unuse = function() {
128169
if (refs > 0 && !--refs) {
129170
dispose();
130171
dispose = null;
131172
}
132173
};
174+
175+
${esModule ? 'export default' : 'module.exports ='} exported;
176+
133177
${hmrCode}
134178
`;
135179
}
@@ -146,17 +190,22 @@ if (module.hot) {
146190
module.hot.accept(
147191
${loaderUtils.stringifyRequest(this, `!!${request}`)},
148192
function () {
149-
var newContent = require(${loaderUtils.stringifyRequest(
150-
this,
151-
`!!${request}`
152-
)});
153-
newContent = newContent.__esModule ? newContent.default : newContent;
154-
155-
if (typeof newContent === 'string') {
156-
newContent = [[module.id, newContent, '']];
193+
${
194+
esModule
195+
? `update(content);`
196+
: `var newContent = require(${loaderUtils.stringifyRequest(
197+
this,
198+
`!!${request}`
199+
)});
200+
201+
newContent = newContent.__esModule ? newContent.default : newContent;
202+
203+
if (typeof newContent === 'string') {
204+
newContent = [[module.id, newContent, '']];
205+
}
206+
207+
update(newContent);`
157208
}
158-
159-
update(newContent);
160209
}
161210
)
162211
}
@@ -167,30 +216,44 @@ if (module.hot) {
167216
}`
168217
: '';
169218

170-
return `var content = require(${loaderUtils.stringifyRequest(
171-
this,
172-
`!!${request}`
173-
)});
174-
content = content.__esModule ? content.default : content;
175-
176-
if (typeof content === 'string') {
177-
content = [[module.id, content, '']];
178-
}
219+
return `${
220+
esModule
221+
? `import api from ${loaderUtils.stringifyRequest(
222+
this,
223+
`!${path.join(__dirname, 'runtime/injectStylesIntoStyleTag.js')}`
224+
)};
225+
import content from ${loaderUtils.stringifyRequest(
226+
this,
227+
`!!${request}`
228+
)};
229+
var clonedContent = content;`
230+
: `var api = require(${loaderUtils.stringifyRequest(
231+
this,
232+
`!${path.join(__dirname, 'runtime/injectStylesIntoStyleTag.js')}`
233+
)});
234+
var content = require(${loaderUtils.stringifyRequest(
235+
this,
236+
`!!${request}`
237+
)});
238+
239+
content = content.__esModule ? content.default : content;
240+
241+
if (typeof content === 'string') {
242+
content = [[module.id, content, '']];
243+
}`
244+
}
179245
180-
var options = ${JSON.stringify(options)}
246+
var options = ${JSON.stringify(options)};
181247
182248
options.insert = ${insert};
183249
options.singleton = ${isSingleton};
184250
185-
var api = require(${loaderUtils.stringifyRequest(
186-
this,
187-
`!${path.join(__dirname, 'runtime/injectStylesIntoStyleTag.js')}`
188-
)});
189251
var update = api(content, options);
190252
191-
if (content.locals) {
192-
module.exports = content.locals;
193-
}
253+
var exported = content.locals ? content.locals : {};
254+
255+
${esModule ? 'export default' : 'module.exports ='} exported;
256+
194257
${hmrCode}`;
195258
}
196259
}

src/options.json

+4
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@
2929
"base": {
3030
"description": "Sets module ID base for DLLPlugin (https://github.com/webpack-contrib/style-loader#base).",
3131
"type": "number"
32+
},
33+
"esModule": {
34+
"description": "Use the ES modules syntax (https://github.com/webpack-contrib/css-loader#esmodule).",
35+
"type": "boolean"
3236
}
3337
},
3438
"additionalProperties": false

0 commit comments

Comments
 (0)