Skip to content

Commit 3a68a3e

Browse files
committed
feat: add a noRuntime option
feat: add a noRuntime option
1 parent e67af52 commit 3a68a3e

6 files changed

+208
-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

+105
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
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, bundle) => {
35+
expect(dom.serialize()).toMatchSnapshot("DOM");
36+
expect(bundle).toContain("webpack/runtime/css loading");
37+
expect(bundle).toContain("webpack/runtime/get mini-css chunk filename");
38+
});
39+
40+
expect(getWarnings(stats)).toMatchSnapshot("warnings");
41+
expect(getErrors(stats)).toMatchSnapshot("errors");
42+
});
43+
44+
it(`should work when noRuntime option is "false"`, async () => {
45+
const compiler = getCompiler(
46+
"attributes.js",
47+
{},
48+
{
49+
output: {
50+
publicPath: "",
51+
path: path.resolve(__dirname, "../outputs"),
52+
filename: "[name].bundle.js",
53+
},
54+
plugins: [
55+
new MiniCssExtractPlugin({
56+
noRuntime: false,
57+
filename: "[name].css",
58+
}),
59+
],
60+
}
61+
);
62+
const stats = await compile(compiler);
63+
64+
runInJsDom("main.bundle.js", compiler, stats, (dom, bundle) => {
65+
expect(dom.serialize()).toMatchSnapshot("DOM");
66+
expect(bundle).toContain("webpack/runtime/css loading");
67+
expect(bundle).toContain("webpack/runtime/get mini-css chunk filename");
68+
});
69+
70+
expect(getWarnings(stats)).toMatchSnapshot("warnings");
71+
expect(getErrors(stats)).toMatchSnapshot("errors");
72+
});
73+
74+
it(`should work when noRuntime option is "true"`, async () => {
75+
const compiler = getCompiler(
76+
"attributes.js",
77+
{},
78+
{
79+
output: {
80+
publicPath: "",
81+
path: path.resolve(__dirname, "../outputs"),
82+
filename: "[name].bundle.js",
83+
},
84+
plugins: [
85+
new MiniCssExtractPlugin({
86+
noRuntime: true,
87+
filename: "[name].css",
88+
}),
89+
],
90+
}
91+
);
92+
const stats = await compile(compiler);
93+
94+
runInJsDom("main.bundle.js", compiler, stats, (dom, bundle) => {
95+
expect(dom.serialize()).toMatchSnapshot("DOM");
96+
expect(bundle).not.toContain("webpack/runtime/css loading");
97+
expect(bundle).not.toContain(
98+
"webpack/runtime/get mini-css chunk filename"
99+
);
100+
});
101+
102+
expect(getWarnings(stats)).toMatchSnapshot("warnings");
103+
expect(getErrors(stats)).toMatchSnapshot("errors");
104+
});
105+
});

0 commit comments

Comments
 (0)