Skip to content

Add support for ES2015 module syntax #433

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

Closed
wants to merge 4 commits into from
Closed
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
51 changes: 42 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,9 @@ module.exports = {
plugins: [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// all options are optional
// both options are optional
filename: '[name].css',
chunkFilename: '[id].css',
ignoreOrder: false, // Enable to remove warnings about conflicting order
}),
],
module: {
Expand Down Expand Up @@ -203,6 +202,46 @@ module.exports = {
};
```

#### `esModules`

Type: `boolean`
Default: `false`

By default, extract-mini-css-plugin generates JS modules that use the CommonJS syntax. However, there are some
cases in which using ES2015 modules is more 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/).

**webpack.config.js**

```js
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
plugins: [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: '[name].css',
chunkFilename: '[id].css',
}),
],
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
esModules: true,
},
},
'css-loader',
],
},
],
},
};
```

### Minimizing For Production

To minify the output, use a plugin like [optimize-css-assets-webpack-plugin](https://github.com/NMFR/optimize-css-assets-webpack-plugin). Setting `optimization.minimizer` overrides the defaults provided by webpack, so make sure to also specify a JS minimizer:
Expand Down Expand Up @@ -359,13 +398,7 @@ For long term caching use `filename: "[contenthash].css"`. Optionally add `[name

### Remove Order Warnings

For projects where css ordering has been mitigated through consistent use of scoping or naming conventions, the css order warnings can be disabled by setting the ignoreOrder flag to true for the plugin.

```javascript
new MiniCssExtractPlugin({
ignoreOrder: true,
}),
```
If the terminal is getting bloated with chunk order warnings. You can filter by configuring [warningsFilter](https://webpack.js.org/configuration/stats/) withing the webpack stats option

### Media Query Plugin

Expand Down
7 changes: 6 additions & 1 deletion src/loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,9 +181,14 @@ export function pitch(request) {
return callback(e);
}

const esModules =
typeof options.esModules === 'boolean' && options.esModules === true;

let resultSource = `// extracted by ${pluginName}`;
const result = locals
? `\nmodule.exports = ${JSON.stringify(locals)};`
? `\n${
esModules ? 'export default ' : 'module.exports = '
}${JSON.stringify(locals)};`
: '';

resultSource += options.hmr
Expand Down
6 changes: 6 additions & 0 deletions test/__snapshots__/esModules-options.test.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`EsModules should generate ES6 modules 1`] = `
"// extracted by mini-css-extract-plugin
export default {\\"test\\":\\"MHBvAShXnAxWEC-jxsBd\\"};"
`;
8 changes: 8 additions & 0 deletions test/cases/esModules/expected/main.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
body {
background: red;
}

.MHBvAShXnAxWEC-jxsBd {
color: black;
}

2 changes: 2 additions & 0 deletions test/cases/esModules/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/* eslint-disable */
import styles from './style.css';
7 changes: 7 additions & 0 deletions test/cases/esModules/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
body {
background: red;
}

.test {
color: black;
}
31 changes: 31 additions & 0 deletions test/cases/esModules/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import Self from '../../../src';

module.exports = {
entry: './index.js',
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: Self.loader,
options: {
esModules: true,
},
},
{
loader: 'css-loader',
options: {
modules: true,
},
},
],
},
],
},
plugins: [
new Self({
filename: '[name].css',
}),
],
};
34 changes: 34 additions & 0 deletions test/esModules-options.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import path from 'path';

import webpack from 'webpack';

describe('EsModules', () => {
it('should generate ES6 modules', (done) => {
const casesDirectory = path.resolve(__dirname, 'cases');
const directoryForCase = path.resolve(casesDirectory, 'esModules');
// eslint-disable-next-line import/no-dynamic-require, global-require
const webpackConfig = require(path.resolve(
directoryForCase,
'webpack.config.js'
));
const compiler = webpack({
...webpackConfig,
mode: 'development',
context: directoryForCase,
cache: false,
});

compiler.run((err1, stats) => {
const { modules } = stats.toJson();
let foundModule = false;
modules.forEach((module) => {
if (module.name === './style.css') {
foundModule = true;
expect(module.source).toMatchSnapshot();
}
});
expect(foundModule).toBe(true);
done();
});
});
});