Skip to content

Commit 845b358

Browse files
committed
feat: add a noRuntime option
1 parent e67af52 commit 845b358

6 files changed

+200
-8
lines changed

Diff for: README.md

+30
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ module.exports = {
8787
| **[`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 |
8888
| **[`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 |
8989
| **[`linkType`](#linkType)** | `{String\|Boolean}` | `text/css` | Allows loading asynchronous chunks with a custom link type |
90+
| **[`noRuntime`](#linkType)** | `{Boolean}` | `false` | Skips the runtime generation |
9091
| **[`experimentalUseImportModule`](#experimentalUseImportModule)** | `{Boolean}` | `false` | Use an experimental webpack API to execute modules instead of child compilers |
9192

9293
#### `filename`
@@ -265,6 +266,35 @@ module.exports = {
265266
};
266267
```
267268

269+
#### `noRuntime`
270+
271+
##### `Boolean`
272+
273+
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.
274+
275+
`true` to skip.
276+
277+
**webpack.config.js**
278+
279+
```js
280+
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
281+
module.exports = {
282+
plugins: [
283+
new MiniCssExtractPlugin({
284+
skipRuntimeLoading: true,
285+
}),
286+
],
287+
module: {
288+
rules: [
289+
{
290+
test: /\.css$/i,
291+
use: [MiniCssExtractPlugin.loader, "css-loader"],
292+
},
293+
],
294+
},
295+
};
296+
```
297+
268298
#### `experimentalUseImportModule`
269299

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

Diff for: src/index.js

+5
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,7 @@ class MiniCssExtractPlugin {
337337
filename: DEFAULT_FILENAME,
338338
ignoreOrder: false,
339339
experimentalUseImportModule: false,
340+
noRuntime: false,
340341
},
341342
options
342343
);
@@ -520,6 +521,10 @@ class MiniCssExtractPlugin {
520521
}
521522
});
522523

524+
// All the code below is dedicated to the runtime and
525+
// can be skipped in a noRuntime context
526+
if (this.options.noRuntime) return;
527+
523528
const { Template } = webpack;
524529

525530
const { RuntimeGlobals, runtime } = webpack;

Diff for: src/plugin-options.json

+5
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@
6565
],
6666
"description": "This option allows loading asynchronous chunks with a custom link type",
6767
"link": "https://github.com/webpack-contrib/mini-css-extract-plugin#linktype"
68+
},
69+
"noRuntime": {
70+
"type": "boolean",
71+
"description": "An option to avoid the runtime generation. Assets are still extracted and can be used for a custom loading methods.",
72+
"link": "https://github.com/webpack-contrib/mini-css-extract-plugin#noRuntime"
6873
}
6974
}
7075
}

Diff for: test/__snapshots__/noRuntime-option.test.js.snap

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`noRuntime option should work when noRuntime option is "false": DOM 1`] = `
4+
"<!DOCTYPE html><html><head>
5+
<title>style-loader test</title>
6+
<style id=\\"existing-style\\">.existing { color: yellow }</style>
7+
<link rel=\\"stylesheet\\" type=\\"text/css\\" href=\\"simple.css\\"><script charset=\\"utf-8\\" src=\\"simple.bundle.js\\"></script></head>
8+
<body>
9+
<h1>Body</h1>
10+
<div class=\\"target\\"></div>
11+
<iframe class=\\"iframeTarget\\"></iframe>
12+
13+
14+
</body></html>"
15+
`;
16+
17+
exports[`noRuntime option should work when noRuntime option is "false": errors 1`] = `Array []`;
18+
19+
exports[`noRuntime option should work when noRuntime option is "false": warnings 1`] = `Array []`;
20+
21+
exports[`noRuntime option should work when noRuntime option is "true": DOM 1`] = `
22+
"<!DOCTYPE html><html><head>
23+
<title>style-loader test</title>
24+
<style id=\\"existing-style\\">.existing { color: yellow }</style>
25+
<script charset=\\"utf-8\\" src=\\"simple.bundle.js\\"></script></head>
26+
<body>
27+
<h1>Body</h1>
28+
<div class=\\"target\\"></div>
29+
<iframe class=\\"iframeTarget\\"></iframe>
30+
31+
32+
</body></html>"
33+
`;
34+
35+
exports[`noRuntime option should work when noRuntime option is "true": errors 1`] = `Array []`;
36+
37+
exports[`noRuntime option should work when noRuntime option is "true": warnings 1`] = `Array []`;
38+
39+
exports[`noRuntime option should work without noRuntime option: DOM 1`] = `
40+
"<!DOCTYPE html><html><head>
41+
<title>style-loader test</title>
42+
<style id=\\"existing-style\\">.existing { color: yellow }</style>
43+
<link rel=\\"stylesheet\\" type=\\"text/css\\" href=\\"simple.css\\"><script charset=\\"utf-8\\" src=\\"simple.bundle.js\\"></script></head>
44+
<body>
45+
<h1>Body</h1>
46+
<div class=\\"target\\"></div>
47+
<iframe class=\\"iframeTarget\\"></iframe>
48+
49+
50+
</body></html>"
51+
`;
52+
53+
exports[`noRuntime option should work without noRuntime option: errors 1`] = `Array []`;
54+
55+
exports[`noRuntime option should work without noRuntime option: warnings 1`] = `Array []`;

Diff for: test/__snapshots__/validate-plugin-options.test.js.snap

+8-8
Original file line numberDiff line numberDiff line change
@@ -117,47 +117,47 @@ exports[`validate options should throw an error on the "linkType" option with "i
117117
exports[`validate options should throw an error on the "unknown" option with "/test/" value 1`] = `
118118
"Invalid options object. Mini CSS Extract Plugin has been initialized using an options object that does not match the API schema.
119119
- options has an unknown property 'unknown'. These properties are valid:
120-
object { filename?, chunkFilename?, experimentalUseImportModule?, ignoreOrder?, insert?, attributes?, linkType? }"
120+
object { filename?, chunkFilename?, experimentalUseImportModule?, ignoreOrder?, insert?, attributes?, linkType?, noRuntime? }"
121121
`;
122122
123123
exports[`validate options should throw an error on the "unknown" option with "[]" value 1`] = `
124124
"Invalid options object. Mini CSS Extract Plugin has been initialized using an options object that does not match the API schema.
125125
- options has an unknown property 'unknown'. These properties are valid:
126-
object { filename?, chunkFilename?, experimentalUseImportModule?, ignoreOrder?, insert?, attributes?, linkType? }"
126+
object { filename?, chunkFilename?, experimentalUseImportModule?, ignoreOrder?, insert?, attributes?, linkType?, noRuntime? }"
127127
`;
128128
129129
exports[`validate options should throw an error on the "unknown" option with "{"foo":"bar"}" value 1`] = `
130130
"Invalid options object. Mini CSS Extract Plugin has been initialized using an options object that does not match the API schema.
131131
- options has an unknown property 'unknown'. These properties are valid:
132-
object { filename?, chunkFilename?, experimentalUseImportModule?, ignoreOrder?, insert?, attributes?, linkType? }"
132+
object { filename?, chunkFilename?, experimentalUseImportModule?, ignoreOrder?, insert?, attributes?, linkType?, noRuntime? }"
133133
`;
134134
135135
exports[`validate options should throw an error on the "unknown" option with "{}" value 1`] = `
136136
"Invalid options object. Mini CSS Extract Plugin has been initialized using an options object that does not match the API schema.
137137
- options has an unknown property 'unknown'. These properties are valid:
138-
object { filename?, chunkFilename?, experimentalUseImportModule?, ignoreOrder?, insert?, attributes?, linkType? }"
138+
object { filename?, chunkFilename?, experimentalUseImportModule?, ignoreOrder?, insert?, attributes?, linkType?, noRuntime? }"
139139
`;
140140
141141
exports[`validate options should throw an error on the "unknown" option with "1" value 1`] = `
142142
"Invalid options object. Mini CSS Extract Plugin has been initialized using an options object that does not match the API schema.
143143
- options has an unknown property 'unknown'. These properties are valid:
144-
object { filename?, chunkFilename?, experimentalUseImportModule?, ignoreOrder?, insert?, attributes?, linkType? }"
144+
object { filename?, chunkFilename?, experimentalUseImportModule?, ignoreOrder?, insert?, attributes?, linkType?, noRuntime? }"
145145
`;
146146
147147
exports[`validate options should throw an error on the "unknown" option with "false" value 1`] = `
148148
"Invalid options object. Mini CSS Extract Plugin has been initialized using an options object that does not match the API schema.
149149
- options has an unknown property 'unknown'. These properties are valid:
150-
object { filename?, chunkFilename?, experimentalUseImportModule?, ignoreOrder?, insert?, attributes?, linkType? }"
150+
object { filename?, chunkFilename?, experimentalUseImportModule?, ignoreOrder?, insert?, attributes?, linkType?, noRuntime? }"
151151
`;
152152
153153
exports[`validate options should throw an error on the "unknown" option with "test" value 1`] = `
154154
"Invalid options object. Mini CSS Extract Plugin has been initialized using an options object that does not match the API schema.
155155
- options has an unknown property 'unknown'. These properties are valid:
156-
object { filename?, chunkFilename?, experimentalUseImportModule?, ignoreOrder?, insert?, attributes?, linkType? }"
156+
object { filename?, chunkFilename?, experimentalUseImportModule?, ignoreOrder?, insert?, attributes?, linkType?, noRuntime? }"
157157
`;
158158
159159
exports[`validate options should throw an error on the "unknown" option with "true" value 1`] = `
160160
"Invalid options object. Mini CSS Extract Plugin has been initialized using an options object that does not match the API schema.
161161
- options has an unknown property 'unknown'. These properties are valid:
162-
object { filename?, chunkFilename?, experimentalUseImportModule?, ignoreOrder?, insert?, attributes?, linkType? }"
162+
object { filename?, chunkFilename?, experimentalUseImportModule?, ignoreOrder?, insert?, attributes?, linkType?, noRuntime? }"
163163
`;

Diff for: test/noRuntime-option.test.js

+97
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/* eslint-env browser */
2+
import path from "path";
3+
4+
import MiniCssExtractPlugin from "../src/cjs";
5+
6+
import {
7+
compile,
8+
getCompiler,
9+
getErrors,
10+
getWarnings,
11+
runInJsDom,
12+
} from "./helpers/index";
13+
14+
describe("noRuntime option", () => {
15+
it(`should work without noRuntime option`, async () => {
16+
const compiler = getCompiler(
17+
"attributes.js",
18+
{},
19+
{
20+
output: {
21+
publicPath: "",
22+
path: path.resolve(__dirname, "../outputs"),
23+
filename: "[name].bundle.js",
24+
},
25+
plugins: [
26+
new MiniCssExtractPlugin({
27+
filename: "[name].css",
28+
}),
29+
],
30+
}
31+
);
32+
const stats = await compile(compiler);
33+
34+
runInJsDom("main.bundle.js", compiler, stats, (dom) => {
35+
expect(dom.serialize()).toMatchSnapshot("DOM");
36+
});
37+
38+
expect(getWarnings(stats)).toMatchSnapshot("warnings");
39+
expect(getErrors(stats)).toMatchSnapshot("errors");
40+
});
41+
42+
it(`should work when noRuntime option is "false"`, async () => {
43+
const compiler = getCompiler(
44+
"attributes.js",
45+
{},
46+
{
47+
output: {
48+
publicPath: "",
49+
path: path.resolve(__dirname, "../outputs"),
50+
filename: "[name].bundle.js",
51+
},
52+
plugins: [
53+
new MiniCssExtractPlugin({
54+
noRuntime: false,
55+
filename: "[name].css",
56+
}),
57+
],
58+
}
59+
);
60+
const stats = await compile(compiler);
61+
62+
runInJsDom("main.bundle.js", compiler, stats, (dom) => {
63+
expect(dom.serialize()).toMatchSnapshot("DOM");
64+
});
65+
66+
expect(getWarnings(stats)).toMatchSnapshot("warnings");
67+
expect(getErrors(stats)).toMatchSnapshot("errors");
68+
});
69+
70+
it(`should work when noRuntime option is "true"`, async () => {
71+
const compiler = getCompiler(
72+
"attributes.js",
73+
{},
74+
{
75+
output: {
76+
publicPath: "",
77+
path: path.resolve(__dirname, "../outputs"),
78+
filename: "[name].bundle.js",
79+
},
80+
plugins: [
81+
new MiniCssExtractPlugin({
82+
noRuntime: true,
83+
filename: "[name].css",
84+
}),
85+
],
86+
}
87+
);
88+
const stats = await compile(compiler);
89+
90+
runInJsDom("main.bundle.js", compiler, stats, (dom) => {
91+
expect(dom.serialize()).toMatchSnapshot("DOM");
92+
});
93+
94+
expect(getWarnings(stats)).toMatchSnapshot("warnings");
95+
expect(getErrors(stats)).toMatchSnapshot("errors");
96+
});
97+
});

0 commit comments

Comments
 (0)