Skip to content

Commit d358cdb

Browse files
feat: esModule option (#1026)
1 parent 23bc1e9 commit d358cdb

17 files changed

+704
-43
lines changed

README.md

+29
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ module.exports = {
118118
| **[`importLoaders`](#importloaders)** | `{Number}` | `0` | Enables/Disables or setups number of loaders applied before CSS loader |
119119
| **[`localsConvention`](#localsconvention)** | `{String}` | `'asIs'` | Style of exported classnames |
120120
| **[`onlyLocals`](#onlylocals)** | `{Boolean}` | `false` | Export only locals |
121+
| **[`esModule`](#esmodule)** | `{Boolean}` | `false` | Use ES modules syntax |
121122

122123
### `url`
123124

@@ -857,6 +858,34 @@ module.exports = {
857858
};
858859
```
859860

861+
### `esModule`
862+
863+
Type: `Boolean`
864+
Default: `false`
865+
866+
By default, `css-loader` generates JS modules that use the CommonJS modules syntax.
867+
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/).
868+
869+
You can enable a ES module syntax using:
870+
871+
**webpack.config.js**
872+
873+
```js
874+
module.exports = {
875+
module: {
876+
rules: [
877+
{
878+
test: /\.css$/i,
879+
loader: 'css-loader',
880+
options: {
881+
esModule: true,
882+
},
883+
},
884+
],
885+
},
886+
};
887+
```
888+
860889
## Examples
861890

862891
### Assets

package-lock.json

+6-6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/index.js

+7-2
Original file line numberDiff line numberDiff line change
@@ -107,12 +107,16 @@ export default function loader(content, map, meta) {
107107
}
108108

109109
const { importLoaders, localsConvention } = options;
110+
const esModule =
111+
typeof options.esModule !== 'undefined' ? options.esModule : false;
112+
110113
const importCode = getImportCode(
111114
this,
112115
imports,
113116
exportType,
114117
sourceMap,
115-
importLoaders
118+
importLoaders,
119+
esModule
116120
);
117121
const moduleCode = getModuleCode(
118122
this,
@@ -126,7 +130,8 @@ export default function loader(content, map, meta) {
126130
exports,
127131
exportType,
128132
replacers,
129-
localsConvention
133+
localsConvention,
134+
esModule
130135
);
131136

132137
return callback(null, [importCode, moduleCode, exportCode].join(''));

src/options.json

+4
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,10 @@
9494
"onlyLocals": {
9595
"description": "Export only locals (https://github.com/webpack-contrib/css-loader#onlylocals).",
9696
"type": "boolean"
97+
},
98+
"esModule": {
99+
"description": "Use the ES modules syntax (https://github.com/webpack-contrib/css-loader#esmodule).",
100+
"type": "boolean"
97101
}
98102
},
99103
"type": "object"

src/utils.js

+62-25
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,8 @@ function getImportCode(
205205
imports,
206206
exportType,
207207
sourceMap,
208-
importLoaders
208+
importLoaders,
209+
esModule
209210
) {
210211
const importItems = [];
211212
const codeItems = [];
@@ -216,12 +217,21 @@ function getImportCode(
216217

217218
if (exportType === 'full') {
218219
importItems.push(
219-
`var ___CSS_LOADER_API_IMPORT___ = require(${stringifyRequest(
220-
loaderContext,
221-
require.resolve('./runtime/api')
222-
)});`
220+
esModule
221+
? `import ___CSS_LOADER_API_IMPORT___ from ${stringifyRequest(
222+
loaderContext,
223+
require.resolve('./runtime/api')
224+
)};`
225+
: `var ___CSS_LOADER_API_IMPORT___ = require(${stringifyRequest(
226+
loaderContext,
227+
require.resolve('./runtime/api')
228+
)});`
229+
);
230+
codeItems.push(
231+
esModule
232+
? `var exports = ___CSS_LOADER_API_IMPORT___(${sourceMap});`
233+
: `exports = ___CSS_LOADER_API_IMPORT___(${sourceMap});`
223234
);
224-
codeItems.push(`exports = ___CSS_LOADER_API_IMPORT___(${sourceMap});`);
225235
}
226236

227237
imports.forEach((item) => {
@@ -251,10 +261,15 @@ function getImportCode(
251261

252262
importName = `___CSS_LOADER_AT_RULE_IMPORT_${atRuleImportNames.size}___`;
253263
importItems.push(
254-
`var ${importName} = require(${stringifyRequest(
255-
loaderContext,
256-
importPrefix + url
257-
)});`
264+
esModule
265+
? `import ${importName} from ${stringifyRequest(
266+
loaderContext,
267+
importPrefix + url
268+
)};`
269+
: `var ${importName} = require(${stringifyRequest(
270+
loaderContext,
271+
importPrefix + url
272+
)});`
258273
);
259274

260275
atRuleImportNames.set(url, importName);
@@ -267,10 +282,15 @@ function getImportCode(
267282
{
268283
if (urlImportNames.size === 0) {
269284
importItems.push(
270-
`var ___CSS_LOADER_GET_URL_IMPORT___ = require(${stringifyRequest(
271-
loaderContext,
272-
require.resolve('./runtime/getUrl.js')
273-
)});`
285+
esModule
286+
? `import ___CSS_LOADER_GET_URL_IMPORT___ from ${stringifyRequest(
287+
loaderContext,
288+
require.resolve('./runtime/getUrl.js')
289+
)};`
290+
: `var ___CSS_LOADER_GET_URL_IMPORT___ = require(${stringifyRequest(
291+
loaderContext,
292+
require.resolve('./runtime/getUrl.js')
293+
)});`
274294
);
275295
}
276296

@@ -281,10 +301,15 @@ function getImportCode(
281301
if (!importName) {
282302
importName = `___CSS_LOADER_URL_IMPORT_${urlImportNames.size}___`;
283303
importItems.push(
284-
`var ${importName} = require(${stringifyRequest(
285-
loaderContext,
286-
url
287-
)});`
304+
esModule
305+
? `import ${importName} from ${stringifyRequest(
306+
loaderContext,
307+
url
308+
)};`
309+
: `var ${importName} = require(${stringifyRequest(
310+
loaderContext,
311+
url
312+
)});`
288313
);
289314

290315
urlImportNames.set(url, importName);
@@ -311,10 +336,15 @@ function getImportCode(
311336
}
312337

313338
importItems.push(
314-
`var ${importName} = require(${stringifyRequest(
315-
loaderContext,
316-
importPrefix + url
317-
)});`
339+
esModule
340+
? `import ${importName} from ${stringifyRequest(
341+
loaderContext,
342+
importPrefix + url
343+
)};`
344+
: `var ${importName} = require(${stringifyRequest(
345+
loaderContext,
346+
importPrefix + url
347+
)});`
318348
);
319349

320350
if (exportType === 'full') {
@@ -380,7 +410,8 @@ function getExportCode(
380410
exports,
381411
exportType,
382412
replacers,
383-
localsConvention
413+
localsConvention,
414+
esModule
384415
) {
385416
const exportItems = [];
386417
let exportLocalsCode;
@@ -448,13 +479,19 @@ function getExportCode(
448479
}
449480

450481
if (exportType === 'locals') {
451-
exportItems.push(`module.exports = {\n${exportLocalsCode}\n};`);
482+
exportItems.push(
483+
`${
484+
esModule ? 'export default' : 'module.exports ='
485+
} {\n${exportLocalsCode}\n};`
486+
);
452487
} else {
453488
if (exportLocalsCode) {
454489
exportItems.push(`exports.locals = {\n${exportLocalsCode}\n};`);
455490
}
456491

457-
exportItems.push('module.exports = exports;');
492+
exportItems.push(
493+
`${esModule ? 'export default' : 'module.exports ='} exports;`
494+
);
458495
}
459496

460497
return `// Exports\n${exportItems.join('\n')}\n`;

0 commit comments

Comments
 (0)