Skip to content

Commit

Permalink
feat: add experimental support for importModule, improve perfomance (
Browse files Browse the repository at this point in the history
  • Loading branch information
sokra committed Apr 16, 2021
1 parent a33f22f commit 8471ac2
Show file tree
Hide file tree
Showing 68 changed files with 4,328 additions and 199 deletions.
70 changes: 70 additions & 0 deletions .github/workflows/nodejs.yml
Expand Up @@ -80,6 +80,18 @@ jobs:
if: matrix.os == 'windows-latest'
run: npm i -g npm

- name: Get npm cache directory
id: npm-cache
run: |
echo "::set-output name=dir::$(npm config get cache)"
- uses: actions/cache@v1
with:
path: ${{ steps.npm-cache.outputs.dir }}
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- name: Install dependencies
run: npm i

Expand All @@ -93,3 +105,61 @@ jobs:
uses: codecov/codecov-action@v1
with:
token: ${{ secrets.CODECOV_TOKEN }}

test2:
name: Test - ${{ matrix.os }} - Node v${{ matrix.node-version }}, Webpack latest, experimentalUseImportModule

strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node-version: [10.x, 12.x, 14.x]

runs-on: ${{ matrix.os }}

steps:
- name: Setup Git
if: matrix.os == 'windows-latest'
run: git config --global core.autocrlf input

- uses: actions/checkout@v2

- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}

- name: Use latest NPM on ubuntu/macos
if: matrix.os == 'ubuntu-latest' || matrix.os == 'macos-latest'
run: sudo npm i -g npm

- name: Use latest NPM on windows
if: matrix.os == 'windows-latest'
run: npm i -g npm

- name: Get npm cache directory
id: npm-cache
run: |
echo "::set-output name=dir::$(npm config get cache)"
- uses: actions/cache@v1
with:
path: ${{ steps.npm-cache.outputs.dir }}
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- name: Install dependencies
run: npm i

- name: Install webpack latest
run: npm i webpack@latest

- name: Run tests for webpack version latest with experimentalUseImportModule
run: npm run test:coverage -- --ci
env:
EXPERIMENTAL_USE_IMPORT_MODULE: 'true'

- name: Submit coverage data to codecov
uses: codecov/codecov-action@v1
with:
token: ${{ secrets.CODECOV_TOKEN }}
27 changes: 19 additions & 8 deletions README.md
Expand Up @@ -75,14 +75,15 @@ module.exports = {

### Plugin Options

| Name | Type | Default | Description |
| :-----------------------------------: | :------------------: | :-----------------------------------: | :--------------------------------------------------------- |
| **[`filename`](#filename)** | `{String\|Function}` | `[name].css` | This option determines the name of each output CSS file |
| **[`chunkFilename`](#chunkFilename)** | `{String\|Function}` | `based on filename` | This option determines the name of non-entry chunk files |
| **[`ignoreOrder`](#ignoreOrder)** | `{Boolean}` | `false` | Remove Order Warnings |
| **[`insert`](#insert)** | `{String\|Function}` | `document.head.appendChild(linkTag);` | Inserts `<link>` at the given position |
| **[`attributes`](#attributes)** | `{Object}` | `{}` | Adds custom attributes to tag |
| **[`linkType`](#linkType)** | `{String\|Boolean}` | `text/css` | Allows loading asynchronous chunks with a custom link type |
| Name | Type | Default | Description |
| :---------------------------------------------------------------: | :------------------: | :-----------------------------------: | :---------------------------------------------------------------------------- |
| **[`filename`](#filename)** | `{String\|Function}` | `[name].css` | This option determines the name of each output CSS file |
| **[`chunkFilename`](#chunkFilename)** | `{String\|Function}` | `based on filename` | This option determines the name of non-entry chunk files |
| **[`ignoreOrder`](#ignoreOrder)** | `{Boolean}` | `false` | Remove Order Warnings |
| **[`insert`](#insert)** | `{String\|Function}` | `document.head.appendChild(linkTag);` | Inserts `<link>` at the given position |
| **[`attributes`](#attributes)** | `{Object}` | `{}` | Adds custom attributes to tag |
| **[`linkType`](#linkType)** | `{String\|Boolean}` | `text/css` | Allows loading asynchronous chunks with a custom link type |
| **[`experimentalUseImportModule`](#experimentalUseImportModule)** | `{Boolean}` | `false` | Use an experimental webpack API to execute modules instead of child compilers |

#### `filename`

Expand Down Expand Up @@ -256,6 +257,16 @@ module.exports = {
};
```

#### `experimentalUseImportModule`

Use an experimental webpack API to execute modules instead of child compilers.

This improves performance and memory usage a lot, but isn't as stable as the normal approach.

When combined with `experiments.layers`, this adds a `layer` option to the loader options to specify the layer of the css execution.

You need to have at least webpack 5.33.2.

### Loader Options

| Name | Type | Default | Description |
Expand Down
56 changes: 21 additions & 35 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -73,7 +73,7 @@
"npm-run-all": "^4.1.5",
"prettier": "^2.2.1",
"standard-version": "^9.1.0",
"webpack": "^5.27.1",
"webpack": "^5.33.2",
"webpack-cli": "^4.5.0",
"webpack-dev-server": "^3.7.2"
},
Expand Down
22 changes: 20 additions & 2 deletions src/index.js
Expand Up @@ -309,7 +309,11 @@ class MiniCssExtractPlugin {
this._sortedModulesCache = new WeakMap();

this.options = Object.assign(
{ filename: DEFAULT_FILENAME, ignoreOrder: false },
{
filename: DEFAULT_FILENAME,
ignoreOrder: false,
experimentalUseImportModule: false,
},
options
);

Expand Down Expand Up @@ -355,6 +359,18 @@ class MiniCssExtractPlugin {
: // eslint-disable-next-line global-require
require('webpack');

if (this.options.experimentalUseImportModule) {
if (!compiler.options.experiments) {
throw new Error(
'experimentalUseImportModule is only support for webpack >= 5.32.0'
);
}
if (typeof compiler.options.experiments.executeModule === 'undefined') {
// eslint-disable-next-line no-param-reassign
compiler.options.experiments.executeModule = true;
}
}

// TODO bug in webpack, remove it after it will be fixed
// webpack tries to `require` loader firstly when serializer doesn't found
if (
Expand Down Expand Up @@ -399,7 +415,9 @@ class MiniCssExtractPlugin {

normalModuleHook.tap(pluginName, (loaderContext) => {
// eslint-disable-next-line no-param-reassign
loaderContext[pluginSymbol] = true;
loaderContext[pluginSymbol] = {
experimentalUseImportModule: this.options.experimentalUseImportModule,
};
});
});

Expand Down
3 changes: 3 additions & 0 deletions src/loader-options.json
Expand Up @@ -18,6 +18,9 @@
"esModule": {
"type": "boolean"
},
"layer": {
"type": "string"
},
"modules": {
"type": "object",
"additionalProperties": false,
Expand Down

0 comments on commit 8471ac2

Please sign in to comment.