Skip to content

Commit 39f3332

Browse files
Merge remote-tracking branch 'origin/master'
2 parents 3246bc2 + fdc5e7b commit 39f3332

File tree

19 files changed

+1373
-912
lines changed

19 files changed

+1373
-912
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ If you like our work, check out our Redux-based router <a href="https://github.c
66
<a href="https://www.npmjs.com/package/extract-css-chunks-webpack-plugin">
77
<img src="https://img.shields.io/npm/v/extract-css-chunks-webpack-plugin.svg" alt="Version" />
88
</a>
9-
9+
<img src="https://ssl.google-analytics.com/collect?v=1&t=event&ec=email&ea=open&t=event&tid=UA-120967034-1&z=1589684734&cid=9befe819-70e1-278b-50fc-859e6d1970cb&dt=ExtractCssChunks&dp=/email/ExtractCssChunks">
1010
<a href="https://travis-ci.org/faceyspacey/extract-css-chunks-webpack-plugin">
1111
<img src="https://travis-ci.org/faceyspacey/extract-css-chunks-webpack-plugin.svg?branch=master" alt="Build Status" />
1212
</a>

index.d.ts

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
declare module 'extract-css-chunks-webpack-plugin' {
2+
import { ChunkData, Plugin } from 'webpack';
3+
4+
class ExtractCssChunksPlugin extends Plugin {
5+
static loader: string;
6+
7+
constructor(options?: ExtractCssChunksPlugin.PluginOptions);
8+
}
9+
10+
namespace ExtractCssChunksPlugin {
11+
interface PluginOptions {
12+
/**
13+
* The filename of the entry chunk.
14+
*/
15+
filename?: string;
16+
/**
17+
* The filename of non-entry chunks.
18+
*/
19+
chunkFilename?: string;
20+
/**
21+
* Generates a file name (or template) based on chunk data.
22+
*/
23+
moduleFilename?: (chunk: ChunkData) => string;
24+
/**
25+
* Remove warnings about conflicting order.
26+
*/
27+
ignoreOrder?: boolean;
28+
/**
29+
* Inserts `<link>` at the given position (https://github.com/faceyspacey/extract-css-chunks-webpack-pluginn#insert).
30+
*/
31+
insert?: string | Function;
32+
}
33+
}
34+
35+
export = ExtractCssChunksPlugin;
36+
}

package.json

+12-10
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
"extract-css-chunks-webpack-plugin"
3232
],
3333
"main": "dist/cjs.js",
34+
"types": "index.d.ts",
3435
"engines": {
3536
"node": ">= 6.9.0"
3637
},
@@ -59,7 +60,8 @@
5960
"travis": "npm run ci:coverage"
6061
},
6162
"files": [
62-
"dist"
63+
"dist",
64+
"index.d.ts"
6365
],
6466
"peerDependencies": {
6567
"webpack": "^4.4.0 || ^5.0.0"
@@ -68,34 +70,34 @@
6870
"loader-utils": "^2.0.0",
6971
"normalize-url": "1.9.1",
7072
"schema-utils": "^1.0.0",
71-
"webpack-external-import": "^2.0.0",
73+
"webpack-external-import": "^2.2.4",
7274
"webpack-sources": "^1.1.0"
7375
},
7476
"devDependencies": {
7577
"@babel/cli": "7.8.4",
7678
"@babel/core": "7.9.0",
77-
"@babel/preset-env": "7.9.0",
79+
"@babel/preset-env": "7.9.5",
7880
"@commitlint/cli": "8.3.5",
7981
"@commitlint/config-conventional": "8.3.4",
8082
"@webpack-contrib/defaults": "6.3.0",
8183
"@webpack-contrib/eslint-config-webpack": "3.0.0",
8284
"babel-eslint": "10.1.0",
83-
"babel-jest": "25.1.0",
84-
"commitizen": "4.0.3",
85+
"babel-jest": "25.5.1",
86+
"commitizen": "4.0.4",
8587
"commitlint-azure-pipelines-cli": "1.0.3",
8688
"cross-env": "7.0.2",
87-
"css-loader": "3.4.2",
89+
"css-loader": "3.5.2",
8890
"cz-conventional-changelog": "3.1.0",
8991
"del": "5.1.0",
9092
"del-cli": "3.0.0",
9193
"es-check": "5.1.0",
9294
"eslint": "6.8.0",
9395
"eslint-config-prettier": "6.10.1",
94-
"eslint-plugin-import": "2.20.1",
96+
"eslint-plugin-import": "2.20.2",
9597
"eslint-plugin-prettier": "3.1.2",
9698
"file-loader": "6.0.0",
9799
"husky": "4.2.3",
98-
"jest": "25.1.0",
100+
"jest": "25.5.4",
99101
"jest-dev-server": "4.4.0",
100102
"jest-junit": "10.0.0",
101103
"jest-puppeteer": "4.4.0",
@@ -106,8 +108,8 @@
106108
"prettier": "1.19.1",
107109
"puppeteer": "2.1.1",
108110
"serve": "11.3.0",
109-
"standard-version": "7.1.0",
110-
"webpack": "4.42.0",
111+
"standard-version": "8.0.1",
112+
"webpack": "4.43.0",
111113
"webpack-cli": "3.3.11",
112114
"webpack-dev-server": "3.10.3"
113115
}

src/index.js

+19-6
Original file line numberDiff line numberDiff line change
@@ -323,10 +323,13 @@ class ExtractCssChunksPlugin {
323323
}
324324
);
325325
const { insert } = this.options;
326+
const supportsPreload =
327+
'(function() { try { return document.createElement("link").relList.supports("preload"); } catch(e) { return false; }}());';
326328
return Template.asString([
327329
source,
328330
'',
329331
`// ${pluginName} CSS loading`,
332+
`var supportsPreload = ${supportsPreload}`,
330333
`var cssChunks = ${JSON.stringify(chunkMap)};`,
331334
'if(installedCssChunks[chunkId]) promises.push(installedCssChunks[chunkId]);',
332335
'else if(installedCssChunks[chunkId] !== 0 && cssChunks[chunkId]) {',
@@ -340,8 +343,7 @@ class ExtractCssChunksPlugin {
340343
Template.indent([
341344
'var tag = existingLinkTags[i];',
342345
'var dataHref = tag.getAttribute("data-href") || tag.getAttribute("href");',
343-
'if(tag.rel === "stylesheet" && (dataHref === href || dataHref === fullhref)) return resolve();',
344-
]),
346+
'if((tag.rel === "stylesheet" || tag.rel === "preload") && (dataHref === href || dataHref === fullhref)) return resolve();', ]),
345347
'}',
346348
'var existingStyleTags = document.getElementsByTagName("style");',
347349
'for(var i = 0; i < existingStyleTags.length; i++) {',
@@ -352,8 +354,8 @@ class ExtractCssChunksPlugin {
352354
]),
353355
'}',
354356
'var linkTag = document.createElement("link");',
355-
'linkTag.rel = "stylesheet";',
356-
'linkTag.type = "text/css";',
357+
'linkTag.rel = supportsPreload ? "preload": "stylesheet";',
358+
'supportsPreload ? linkTag.as = "style" : linkTag.type = "text/css";',
357359
'linkTag.onload = resolve;',
358360
'linkTag.onerror = function(event) {',
359361
Template.indent([
@@ -379,11 +381,22 @@ class ExtractCssChunksPlugin {
379381
])
380382
: '',
381383
insert
382-
? 'insert(linkTag);'
384+
? `var insert = ${insert};\ninsert(linkTag);`
383385
: 'var head = document.getElementsByTagName("head")[0]; head.appendChild(linkTag)',
384386
]),
385387
'}).then(function() {',
386-
Template.indent(['installedCssChunks[chunkId] = 0;']),
388+
Template.indent([
389+
'installedCssChunks[chunkId] = 0;',
390+
'if(supportsPreload) {',
391+
Template.indent([
392+
'var execLinkTag = document.createElement("link");',
393+
`execLinkTag.href = ${mainTemplate.requireFn}.p + ${linkHrefPath};`,
394+
'execLinkTag.rel = "stylesheet";',
395+
'execLinkTag.type = "text/css";',
396+
'document.body.appendChild(execLinkTag);',
397+
]),
398+
'}',
399+
]),
387400
'}));',
388401
]),
389402
'}',

test/HMR.test.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ describe('HMR', () => {
3030

3131
jest.spyOn(Date, 'now').mockImplementation(() => 1479427200000);
3232

33-
document.head.innerHTML = '<link rel="stylesheet" href="/dist/main.css" />';
33+
document.head.innerHTML =
34+
'<link rel="preload" as="style" href="/dist/main.css" />';
3435
document.body.innerHTML = '<script src="/dist/main.js"></script>';
3536
});
3637

test/__snapshots__/HMR.test.js.snap

+6-6
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
exports[`HMR should handle error event 1`] = `"[HMR] css reload %s"`;
44

5-
exports[`HMR should handle error event 2`] = `"<link rel=\\"stylesheet\\" href=\\"/dist/main.css\\"><link rel=\\"stylesheet\\" href=\\"http://localhost/dist/main.css?1479427200000\\">"`;
5+
exports[`HMR should handle error event 2`] = `"<link rel=\\"preload\\" as=\\"style\\" href=\\"/dist/main.css\\"><link rel=\\"preload\\" as=\\"style\\" href=\\"http://localhost/dist/main.css?1479427200000\\">"`;
66
77
exports[`HMR should reloads with # link href 1`] = `"[HMR] css reload %s"`;
88
@@ -18,22 +18,22 @@ exports[`HMR should reloads with link without href 2`] = `"<link rel=\\"styleshe
1818
1919
exports[`HMR should reloads with locals 1`] = `"[HMR] Detected local css modules. Reload all css"`;
2020
21-
exports[`HMR should reloads with locals 2`] = `"<link rel=\\"stylesheet\\" href=\\"/dist/main.css\\"><link rel=\\"stylesheet\\" href=\\"http://localhost/dist/main.css?1479427200000\\">"`;
21+
exports[`HMR should reloads with locals 2`] = `"<link rel=\\"preload\\" as=\\"style\\" href=\\"/dist/main.css\\"><link rel=\\"preload\\" as=\\"style\\" href=\\"http://localhost/dist/main.css?1479427200000\\">"`;
2222
2323
exports[`HMR should reloads with non http/https link href 1`] = `"[HMR] css reload %s"`;
2424
2525
exports[`HMR should reloads with non http/https link href 2`] = `"<link rel=\\"stylesheet\\" href=\\"/dist/main.css\\"><link rel=\\"stylesheet\\" href=\\"http://localhost/dist/main.css?1479427200000\\"><link rel=\\"shortcut icon\\" href=\\"data:;base64,=\\">"`;
2626
2727
exports[`HMR should reloads with reloadAll option 1`] = `"[HMR] Reload all css"`;
2828
29-
exports[`HMR should reloads with reloadAll option 2`] = `"<link rel=\\"stylesheet\\" href=\\"/dist/main.css\\"><link rel=\\"stylesheet\\" href=\\"http://localhost/dist/main.css?1479427200000\\">"`;
29+
exports[`HMR should reloads with reloadAll option 2`] = `"<link rel=\\"preload\\" as=\\"style\\" href=\\"/dist/main.css\\"><link rel=\\"preload\\" as=\\"style\\" href=\\"http://localhost/dist/main.css?1479427200000\\">"`;
3030
3131
exports[`HMR should works 1`] = `"[HMR] css reload %s"`;
3232
33-
exports[`HMR should works 2`] = `"<link rel=\\"stylesheet\\" href=\\"/dist/main.css\\"><link rel=\\"stylesheet\\" href=\\"http://localhost/dist/main.css?1479427200000\\">"`;
33+
exports[`HMR should works 2`] = `"<link rel=\\"preload\\" as=\\"style\\" href=\\"/dist/main.css\\"><link rel=\\"preload\\" as=\\"style\\" href=\\"http://localhost/dist/main.css?1479427200000\\">"`;
3434
3535
exports[`HMR should works with multiple updates 1`] = `"[HMR] css reload %s"`;
3636
37-
exports[`HMR should works with multiple updates 2`] = `"<link rel=\\"stylesheet\\" href=\\"/dist/main.css\\"><link rel=\\"stylesheet\\" href=\\"http://localhost/dist/main.css?1479427200000\\">"`;
37+
exports[`HMR should works with multiple updates 2`] = `"<link rel=\\"preload\\" as=\\"style\\" href=\\"/dist/main.css\\"><link rel=\\"preload\\" as=\\"style\\" href=\\"http://localhost/dist/main.css?1479427200000\\">"`;
3838
39-
exports[`HMR should works with multiple updates 3`] = `"<link rel=\\"stylesheet\\" href=\\"http://localhost/dist/main.css?1479427200000\\"><link rel=\\"stylesheet\\" href=\\"http://localhost/dist/main.css?1479427200001\\">"`;
39+
exports[`HMR should works with multiple updates 3`] = `"<link rel=\\"preload\\" as=\\"style\\" href=\\"http://localhost/dist/main.css?1479427200000\\"><link rel=\\"preload\\" as=\\"style\\" href=\\"http://localhost/dist/main.css?1479427200001\\">"`;

test/cases/insert-function/expected/main.js

+12-11
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
/******/
8383
/******/
8484
/******/ // extract-css-chunks-webpack-plugin CSS loading
85+
/******/ var supportsPreload = (function() { try { return document.createElement("link").relList.supports("preload"); } catch(e) { return false; }}());
8586
/******/ var cssChunks = {"1":1};
8687
/******/ if(installedCssChunks[chunkId]) promises.push(installedCssChunks[chunkId]);
8788
/******/ else if(installedCssChunks[chunkId] !== 0 && cssChunks[chunkId]) {
@@ -92,7 +93,7 @@
9293
/******/ for(var i = 0; i < existingLinkTags.length; i++) {
9394
/******/ var tag = existingLinkTags[i];
9495
/******/ var dataHref = tag.getAttribute("data-href") || tag.getAttribute("href");
95-
/******/ if(tag.rel === "stylesheet" && (dataHref === href || dataHref === fullhref)) return resolve();
96+
/******/ if((tag.rel === "stylesheet" || tag.rel === "preload") && (dataHref === href || dataHref === fullhref)) return resolve();
9697
/******/ }
9798
/******/ var existingStyleTags = document.getElementsByTagName("style");
9899
/******/ for(var i = 0; i < existingStyleTags.length; i++) {
@@ -101,8 +102,8 @@
101102
/******/ if(dataHref === href || dataHref === fullhref) return resolve();
102103
/******/ }
103104
/******/ var linkTag = document.createElement("link");
104-
/******/ linkTag.rel = "stylesheet";
105-
/******/ linkTag.type = "text/css";
105+
/******/ linkTag.rel = supportsPreload ? "preload": "stylesheet";
106+
/******/ supportsPreload ? linkTag.as = "style" : linkTag.type = "text/css";
106107
/******/ linkTag.onload = resolve;
107108
/******/ linkTag.onerror = function(event) {
108109
/******/ var request = event && event.target && event.target.src || fullhref;
@@ -122,16 +123,16 @@
122123
/******/ reference.parentNode.insertBefore(linkTag, reference);
123124
/******/ }
124125
/******/ };
125-
/******/ if (typeof insert === 'function') { insert(linkTag); }
126-
/******/ else { var target = document.querySelector(function insert(linkTag) {
127-
/******/ const reference = document.querySelector('.hot-reload');
128-
/******/
129-
/******/ if (reference) {
130-
/******/ reference.parentNode.insertBefore(linkTag, reference);
131-
/******/ }
132-
/******/ }); target && insert === 'body' ? target && target.insertBefore(linkTag,target.firstChild) : target.appendChild(linkTag); }
126+
/******/ insert(linkTag);
133127
/******/ }).then(function() {
134128
/******/ installedCssChunks[chunkId] = 0;
129+
/******/ if(supportsPreload) {
130+
/******/ var execLinkTag = document.createElement("link");
131+
/******/ execLinkTag.href = __webpack_require__.p + "" + chunkId + ".css";
132+
/******/ execLinkTag.rel = "stylesheet";
133+
/******/ execLinkTag.type = "text/css";
134+
/******/ document.body.appendChild(execLinkTag);
135+
/******/ }
135136
/******/ }));
136137
/******/ }
137138
/******/

test/cases/insert-function/webpack.config.e2e.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,9 @@ module.exports = {
6464
new Self({
6565
filename: '[name].css',
6666
chunkFilename: '[id].css',
67-
insert: 'body',
67+
insert: (linkTag) => {
68+
document.head.appendChild(linkTag)
69+
},
6870
}),
6971
],
7072
devServer: {

test/cases/insert-string/expected/main.js

+13-6
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
/******/
8383
/******/
8484
/******/ // extract-css-chunks-webpack-plugin CSS loading
85+
/******/ var supportsPreload = (function() { try { return document.createElement("link").relList.supports("preload"); } catch(e) { return false; }}());
8586
/******/ var cssChunks = {"1":1};
8687
/******/ if(installedCssChunks[chunkId]) promises.push(installedCssChunks[chunkId]);
8788
/******/ else if(installedCssChunks[chunkId] !== 0 && cssChunks[chunkId]) {
@@ -92,7 +93,7 @@
9293
/******/ for(var i = 0; i < existingLinkTags.length; i++) {
9394
/******/ var tag = existingLinkTags[i];
9495
/******/ var dataHref = tag.getAttribute("data-href") || tag.getAttribute("href");
95-
/******/ if(tag.rel === "stylesheet" && (dataHref === href || dataHref === fullhref)) return resolve();
96+
/******/ if((tag.rel === "stylesheet" || tag.rel === "preload") && (dataHref === href || dataHref === fullhref)) return resolve();
9697
/******/ }
9798
/******/ var existingStyleTags = document.getElementsByTagName("style");
9899
/******/ for(var i = 0; i < existingStyleTags.length; i++) {
@@ -101,8 +102,8 @@
101102
/******/ if(dataHref === href || dataHref === fullhref) return resolve();
102103
/******/ }
103104
/******/ var linkTag = document.createElement("link");
104-
/******/ linkTag.rel = "stylesheet";
105-
/******/ linkTag.type = "text/css";
105+
/******/ linkTag.rel = supportsPreload ? "preload": "stylesheet";
106+
/******/ supportsPreload ? linkTag.as = "style" : linkTag.type = "text/css";
106107
/******/ linkTag.onload = resolve;
107108
/******/ linkTag.onerror = function(event) {
108109
/******/ var request = event && event.target && event.target.src || fullhref;
@@ -115,11 +116,17 @@
115116
/******/ };
116117
/******/ linkTag.href = fullhref;
117118
/******/
118-
/******/ var insert = "body";
119-
/******/ if (typeof insert === 'function') { insert(linkTag); }
120-
/******/ else { var target = document.querySelector("body"); target && insert === 'body' ? target && target.insertBefore(linkTag,target.firstChild) : target.appendChild(linkTag); }
119+
/******/ var insert = body;
120+
/******/ insert(linkTag);
121121
/******/ }).then(function() {
122122
/******/ installedCssChunks[chunkId] = 0;
123+
/******/ if(supportsPreload) {
124+
/******/ var execLinkTag = document.createElement("link");
125+
/******/ execLinkTag.href = __webpack_require__.p + "" + chunkId + ".css";
126+
/******/ execLinkTag.rel = "stylesheet";
127+
/******/ execLinkTag.type = "text/css";
128+
/******/ document.body.appendChild(execLinkTag);
129+
/******/ }
123130
/******/ }));
124131
/******/ }
125132
/******/

test/cases/insert-string/webpack.config.e2e.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ module.exports = {
6464
new Self({
6565
filename: '[name].css',
6666
chunkFilename: '[id].css',
67-
insert: 'body',
67+
insert: '(linkTag) => { document.head.appendChild(linkTag) }',
6868
}),
6969
],
7070
devServer: {
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
body {
22
background: red;
3-
background-image: url(cd0bb358c45b584743d8ce4991777c42.svg);
3+
background-image: url(c9e192c015437a21dea1faa1d30f4941.svg);
44
}
55

Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
body {
22
background: green;
3-
background-image: url(../../cd0bb358c45b584743d8ce4991777c42.svg);
3+
background-image: url(../../c9e192c015437a21dea1faa1d30f4941.svg);
44
}
55

Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
body {
22
background: red;
3-
background-image: url(../cd0bb358c45b584743d8ce4991777c42.svg);
3+
background-image: url(../c9e192c015437a21dea1faa1d30f4941.svg);
44
}
55

Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
body {
22
background: red;
3-
background-image: url(/static/img/cd0bb358c45b584743d8ce4991777c42.svg);
3+
background-image: url(/static/img/c9e192c015437a21dea1faa1d30f4941.svg);
44
}
55

Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
body {
22
background: red;
3-
background-image: url(/static/img/cd0bb358c45b584743d8ce4991777c42.svg);
3+
background-image: url(/static/img/c9e192c015437a21dea1faa1d30f4941.svg);
44
}
55

test/cases/split-chunks/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
// eslint-disable-next-line import/no-extraneous-dependencies
1+
// eslint-disable-next-line
22
import 'bootstrap.css';
33
import './style.css';

test/cases/split-chunks/node_modules/bootstrap.css

-4
This file was deleted.

0 commit comments

Comments
 (0)