Skip to content

Commit

Permalink
feat: add a noRuntime option
Browse files Browse the repository at this point in the history
  • Loading branch information
cbazureau committed Sep 10, 2021
1 parent e67af52 commit 845b358
Show file tree
Hide file tree
Showing 6 changed files with 200 additions and 8 deletions.
30 changes: 30 additions & 0 deletions README.md
Expand Up @@ -87,6 +87,7 @@ module.exports = {
| **[`insert`](#insert)** | `{String\|Function}` | `document.head.appendChild(linkTag);` | Inserts the `link` tag at the given position for [non-initial (async)](https://webpack.js.org/concepts/under-the-hood/#chunks) CSS chunks |
| **[`attributes`](#attributes)** | `{Object}` | `{}` | Adds custom attributes to the `link` tag for [non-initial (async)](https://webpack.js.org/concepts/under-the-hood/#chunks) CSS chunks |
| **[`linkType`](#linkType)** | `{String\|Boolean}` | `text/css` | Allows loading asynchronous chunks with a custom link type |
| **[`noRuntime`](#linkType)** | `{Boolean}` | `false` | Skips the runtime generation |
| **[`experimentalUseImportModule`](#experimentalUseImportModule)** | `{Boolean}` | `false` | Use an experimental webpack API to execute modules instead of child compilers |

#### `filename`
Expand Down Expand Up @@ -265,6 +266,35 @@ module.exports = {
};
```

#### `noRuntime`

##### `Boolean`

An option to avoid the runtime generation. Assets are still extracted and can be used for a custom loading methods. For example, you can use [assets-webpack-plugin](https://github.com/ztoben/assets-webpack-plugin) to retreive them then use your own runtime code to download assets when needed.

`true` to skip.

**webpack.config.js**

```js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [
new MiniCssExtractPlugin({
skipRuntimeLoading: true,
}),
],
module: {
rules: [
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
],
},
};
```

#### `experimentalUseImportModule`

Use an experimental webpack API to execute modules instead of child compilers.
Expand Down
5 changes: 5 additions & 0 deletions src/index.js
Expand Up @@ -337,6 +337,7 @@ class MiniCssExtractPlugin {
filename: DEFAULT_FILENAME,
ignoreOrder: false,
experimentalUseImportModule: false,
noRuntime: false,
},
options
);
Expand Down Expand Up @@ -520,6 +521,10 @@ class MiniCssExtractPlugin {
}
});

// All the code below is dedicated to the runtime and
// can be skipped in a noRuntime context
if (this.options.noRuntime) return;

const { Template } = webpack;

const { RuntimeGlobals, runtime } = webpack;
Expand Down
5 changes: 5 additions & 0 deletions src/plugin-options.json
Expand Up @@ -65,6 +65,11 @@
],
"description": "This option allows loading asynchronous chunks with a custom link type",
"link": "https://github.com/webpack-contrib/mini-css-extract-plugin#linktype"
},
"noRuntime": {
"type": "boolean",
"description": "An option to avoid the runtime generation. Assets are still extracted and can be used for a custom loading methods.",
"link": "https://github.com/webpack-contrib/mini-css-extract-plugin#noRuntime"
}
}
}
55 changes: 55 additions & 0 deletions test/__snapshots__/noRuntime-option.test.js.snap
@@ -0,0 +1,55 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`noRuntime option should work when noRuntime option is "false": DOM 1`] = `
"<!DOCTYPE html><html><head>
<title>style-loader test</title>
<style id=\\"existing-style\\">.existing { color: yellow }</style>
<link rel=\\"stylesheet\\" type=\\"text/css\\" href=\\"simple.css\\"><script charset=\\"utf-8\\" src=\\"simple.bundle.js\\"></script></head>
<body>
<h1>Body</h1>
<div class=\\"target\\"></div>
<iframe class=\\"iframeTarget\\"></iframe>
</body></html>"
`;
exports[`noRuntime option should work when noRuntime option is "false": errors 1`] = `Array []`;
exports[`noRuntime option should work when noRuntime option is "false": warnings 1`] = `Array []`;
exports[`noRuntime option should work when noRuntime option is "true": DOM 1`] = `
"<!DOCTYPE html><html><head>
<title>style-loader test</title>
<style id=\\"existing-style\\">.existing { color: yellow }</style>
<script charset=\\"utf-8\\" src=\\"simple.bundle.js\\"></script></head>
<body>
<h1>Body</h1>
<div class=\\"target\\"></div>
<iframe class=\\"iframeTarget\\"></iframe>
</body></html>"
`;
exports[`noRuntime option should work when noRuntime option is "true": errors 1`] = `Array []`;
exports[`noRuntime option should work when noRuntime option is "true": warnings 1`] = `Array []`;
exports[`noRuntime option should work without noRuntime option: DOM 1`] = `
"<!DOCTYPE html><html><head>
<title>style-loader test</title>
<style id=\\"existing-style\\">.existing { color: yellow }</style>
<link rel=\\"stylesheet\\" type=\\"text/css\\" href=\\"simple.css\\"><script charset=\\"utf-8\\" src=\\"simple.bundle.js\\"></script></head>
<body>
<h1>Body</h1>
<div class=\\"target\\"></div>
<iframe class=\\"iframeTarget\\"></iframe>
</body></html>"
`;
exports[`noRuntime option should work without noRuntime option: errors 1`] = `Array []`;
exports[`noRuntime option should work without noRuntime option: warnings 1`] = `Array []`;
16 changes: 8 additions & 8 deletions test/__snapshots__/validate-plugin-options.test.js.snap
Expand Up @@ -117,47 +117,47 @@ exports[`validate options should throw an error on the "linkType" option with "i
exports[`validate options should throw an error on the "unknown" option with "/test/" value 1`] = `
"Invalid options object. Mini CSS Extract Plugin has been initialized using an options object that does not match the API schema.
- options has an unknown property 'unknown'. These properties are valid:
object { filename?, chunkFilename?, experimentalUseImportModule?, ignoreOrder?, insert?, attributes?, linkType? }"
object { filename?, chunkFilename?, experimentalUseImportModule?, ignoreOrder?, insert?, attributes?, linkType?, noRuntime? }"
`;
exports[`validate options should throw an error on the "unknown" option with "[]" value 1`] = `
"Invalid options object. Mini CSS Extract Plugin has been initialized using an options object that does not match the API schema.
- options has an unknown property 'unknown'. These properties are valid:
object { filename?, chunkFilename?, experimentalUseImportModule?, ignoreOrder?, insert?, attributes?, linkType? }"
object { filename?, chunkFilename?, experimentalUseImportModule?, ignoreOrder?, insert?, attributes?, linkType?, noRuntime? }"
`;
exports[`validate options should throw an error on the "unknown" option with "{"foo":"bar"}" value 1`] = `
"Invalid options object. Mini CSS Extract Plugin has been initialized using an options object that does not match the API schema.
- options has an unknown property 'unknown'. These properties are valid:
object { filename?, chunkFilename?, experimentalUseImportModule?, ignoreOrder?, insert?, attributes?, linkType? }"
object { filename?, chunkFilename?, experimentalUseImportModule?, ignoreOrder?, insert?, attributes?, linkType?, noRuntime? }"
`;
exports[`validate options should throw an error on the "unknown" option with "{}" value 1`] = `
"Invalid options object. Mini CSS Extract Plugin has been initialized using an options object that does not match the API schema.
- options has an unknown property 'unknown'. These properties are valid:
object { filename?, chunkFilename?, experimentalUseImportModule?, ignoreOrder?, insert?, attributes?, linkType? }"
object { filename?, chunkFilename?, experimentalUseImportModule?, ignoreOrder?, insert?, attributes?, linkType?, noRuntime? }"
`;
exports[`validate options should throw an error on the "unknown" option with "1" value 1`] = `
"Invalid options object. Mini CSS Extract Plugin has been initialized using an options object that does not match the API schema.
- options has an unknown property 'unknown'. These properties are valid:
object { filename?, chunkFilename?, experimentalUseImportModule?, ignoreOrder?, insert?, attributes?, linkType? }"
object { filename?, chunkFilename?, experimentalUseImportModule?, ignoreOrder?, insert?, attributes?, linkType?, noRuntime? }"
`;
exports[`validate options should throw an error on the "unknown" option with "false" value 1`] = `
"Invalid options object. Mini CSS Extract Plugin has been initialized using an options object that does not match the API schema.
- options has an unknown property 'unknown'. These properties are valid:
object { filename?, chunkFilename?, experimentalUseImportModule?, ignoreOrder?, insert?, attributes?, linkType? }"
object { filename?, chunkFilename?, experimentalUseImportModule?, ignoreOrder?, insert?, attributes?, linkType?, noRuntime? }"
`;
exports[`validate options should throw an error on the "unknown" option with "test" value 1`] = `
"Invalid options object. Mini CSS Extract Plugin has been initialized using an options object that does not match the API schema.
- options has an unknown property 'unknown'. These properties are valid:
object { filename?, chunkFilename?, experimentalUseImportModule?, ignoreOrder?, insert?, attributes?, linkType? }"
object { filename?, chunkFilename?, experimentalUseImportModule?, ignoreOrder?, insert?, attributes?, linkType?, noRuntime? }"
`;
exports[`validate options should throw an error on the "unknown" option with "true" value 1`] = `
"Invalid options object. Mini CSS Extract Plugin has been initialized using an options object that does not match the API schema.
- options has an unknown property 'unknown'. These properties are valid:
object { filename?, chunkFilename?, experimentalUseImportModule?, ignoreOrder?, insert?, attributes?, linkType? }"
object { filename?, chunkFilename?, experimentalUseImportModule?, ignoreOrder?, insert?, attributes?, linkType?, noRuntime? }"
`;
97 changes: 97 additions & 0 deletions test/noRuntime-option.test.js
@@ -0,0 +1,97 @@
/* eslint-env browser */
import path from "path";

import MiniCssExtractPlugin from "../src/cjs";

import {
compile,
getCompiler,
getErrors,
getWarnings,
runInJsDom,
} from "./helpers/index";

describe("noRuntime option", () => {
it(`should work without noRuntime option`, async () => {
const compiler = getCompiler(
"attributes.js",
{},
{
output: {
publicPath: "",
path: path.resolve(__dirname, "../outputs"),
filename: "[name].bundle.js",
},
plugins: [
new MiniCssExtractPlugin({
filename: "[name].css",
}),
],
}
);
const stats = await compile(compiler);

runInJsDom("main.bundle.js", compiler, stats, (dom) => {
expect(dom.serialize()).toMatchSnapshot("DOM");
});

expect(getWarnings(stats)).toMatchSnapshot("warnings");
expect(getErrors(stats)).toMatchSnapshot("errors");
});

it(`should work when noRuntime option is "false"`, async () => {
const compiler = getCompiler(
"attributes.js",
{},
{
output: {
publicPath: "",
path: path.resolve(__dirname, "../outputs"),
filename: "[name].bundle.js",
},
plugins: [
new MiniCssExtractPlugin({
noRuntime: false,
filename: "[name].css",
}),
],
}
);
const stats = await compile(compiler);

runInJsDom("main.bundle.js", compiler, stats, (dom) => {
expect(dom.serialize()).toMatchSnapshot("DOM");
});

expect(getWarnings(stats)).toMatchSnapshot("warnings");
expect(getErrors(stats)).toMatchSnapshot("errors");
});

it(`should work when noRuntime option is "true"`, async () => {
const compiler = getCompiler(
"attributes.js",
{},
{
output: {
publicPath: "",
path: path.resolve(__dirname, "../outputs"),
filename: "[name].bundle.js",
},
plugins: [
new MiniCssExtractPlugin({
noRuntime: true,
filename: "[name].css",
}),
],
}
);
const stats = await compile(compiler);

runInJsDom("main.bundle.js", compiler, stats, (dom) => {
expect(dom.serialize()).toMatchSnapshot("DOM");
});

expect(getWarnings(stats)).toMatchSnapshot("warnings");
expect(getErrors(stats)).toMatchSnapshot("errors");
});
});

0 comments on commit 845b358

Please sign in to comment.