Skip to content
This repository was archived by the owner on Jan 28, 2023. It is now read-only.

Commit 2b6fcf2

Browse files
authored
fix: onerror/onload memory leak (webpack-contrib#640)
1 parent f448ee1 commit 2b6fcf2

File tree

9 files changed

+139
-83
lines changed

9 files changed

+139
-83
lines changed

src/CssLoadingRuntimeModule.js

+17-11
Original file line numberDiff line numberDiff line change
@@ -60,17 +60,23 @@ module.exports = class CssLoadingRuntimeModule extends RuntimeModule {
6060
this.runtimeOptions.linkType
6161
? `linkTag.type = ${JSON.stringify(this.runtimeOptions.linkType)};`
6262
: '',
63-
'linkTag.onload = resolve;',
64-
'linkTag.onerror = function(event) {',
65-
Template.indent([
66-
'var request = event && event.target && event.target.href || fullhref;',
67-
'var err = new Error("Loading CSS chunk " + chunkId + " failed.\\n(" + request + ")");',
68-
'err.code = "CSS_CHUNK_LOAD_FAILED";',
69-
'err.request = request;',
70-
'linkTag.parentNode.removeChild(linkTag)',
71-
'reject(err);',
72-
]),
73-
'};',
63+
`var onLinkComplete = ${runtimeTemplate.basicFunction('event', [
64+
'// avoid mem leaks.',
65+
'linkTag.onerror = linkTag.onload = null;',
66+
"if (event.type === 'load') {",
67+
Template.indent(['resolve();']),
68+
'} else {',
69+
Template.indent([
70+
'var request = event && event.target && event.target.href || fullhref;',
71+
'var err = new Error("Loading CSS chunk " + chunkId + " failed.\\n(" + request + ")");',
72+
'err.code = "CSS_CHUNK_LOAD_FAILED";',
73+
'err.request = request;',
74+
'linkTag.parentNode.removeChild(linkTag)',
75+
'reject(err);',
76+
]),
77+
'}',
78+
])}`,
79+
'linkTag.onerror = linkTag.onload = onLinkComplete;',
7480
'linkTag.href = fullhref;',
7581
crossOriginLoading
7682
? Template.asString([

src/index.js

+17-9
Original file line numberDiff line numberDiff line change
@@ -405,18 +405,26 @@ class MiniCssExtractPlugin {
405405
this.runtimeOptions.linkType
406406
)};`
407407
: '',
408-
'linkTag.onload = resolve;',
409-
'linkTag.onerror = function(event) {',
408+
'var onLinkComplete = function (event) {',
410409
Template.indent([
411-
'var request = event && event.target && event.target.href || fullhref;',
412-
'var err = new Error("Loading CSS chunk " + chunkId + " failed.\\n(" + request + ")");',
413-
'err.code = "CSS_CHUNK_LOAD_FAILED";',
414-
'err.request = request;',
415-
'delete installedCssChunks[chunkId]',
416-
'linkTag.parentNode.removeChild(linkTag)',
417-
'reject(err);',
410+
'// avoid mem leaks.',
411+
'linkTag.onerror = linkTag.onload = null;',
412+
"if (event.type === 'load') {",
413+
Template.indent(['resolve();']),
414+
'} else {',
415+
Template.indent([
416+
'var request = event && event.target && event.target.href || fullhref;',
417+
'var err = new Error("Loading CSS chunk " + chunkId + " failed.\\n(" + request + ")");',
418+
'err.code = "CSS_CHUNK_LOAD_FAILED";',
419+
'err.request = request;',
420+
'delete installedCssChunks[chunkId]',
421+
'linkTag.parentNode.removeChild(linkTag)',
422+
'reject(err);',
423+
]),
424+
'}',
418425
]),
419426
'};',
427+
'linkTag.onerror = linkTag.onload = onLinkComplete;',
420428
'linkTag.href = fullhref;',
421429
crossOriginLoading
422430
? Template.asString([

test/cases/hmr/expected/webpack-5/main.js

+15-9
Original file line numberDiff line numberDiff line change
@@ -827,15 +827,21 @@ module.exports = function (urlString) {
827827
/******/
828828
/******/ linkTag.rel = "stylesheet";
829829
/******/ linkTag.type = "text/css";
830-
/******/ linkTag.onload = resolve;
831-
/******/ linkTag.onerror = function(event) {
832-
/******/ var request = event && event.target && event.target.href || fullhref;
833-
/******/ var err = new Error("Loading CSS chunk " + chunkId + " failed.\n(" + request + ")");
834-
/******/ err.code = "CSS_CHUNK_LOAD_FAILED";
835-
/******/ err.request = request;
836-
/******/ linkTag.parentNode.removeChild(linkTag)
837-
/******/ reject(err);
838-
/******/ };
830+
/******/ var onLinkComplete = (event) => {
831+
/******/ // avoid mem leaks.
832+
/******/ linkTag.onerror = linkTag.onload = null;
833+
/******/ if (event.type === 'load') {
834+
/******/ resolve();
835+
/******/ } else {
836+
/******/ var request = event && event.target && event.target.href || fullhref;
837+
/******/ var err = new Error("Loading CSS chunk " + chunkId + " failed.\n(" + request + ")");
838+
/******/ err.code = "CSS_CHUNK_LOAD_FAILED";
839+
/******/ err.request = request;
840+
/******/ linkTag.parentNode.removeChild(linkTag)
841+
/******/ reject(err);
842+
/******/ }
843+
/******/ }
844+
/******/ linkTag.onerror = linkTag.onload = onLinkComplete;
839845
/******/ linkTag.href = fullhref;
840846
/******/
841847
/******/ document.head.appendChild(linkTag);

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

+15-9
Original file line numberDiff line numberDiff line change
@@ -104,16 +104,22 @@
104104
/******/
105105
/******/ linkTag.rel = "stylesheet";
106106
/******/ linkTag.type = "text/css";
107-
/******/ linkTag.onload = resolve;
108-
/******/ linkTag.onerror = function(event) {
109-
/******/ var request = event && event.target && event.target.href || fullhref;
110-
/******/ var err = new Error("Loading CSS chunk " + chunkId + " failed.\n(" + request + ")");
111-
/******/ err.code = "CSS_CHUNK_LOAD_FAILED";
112-
/******/ err.request = request;
113-
/******/ delete installedCssChunks[chunkId]
114-
/******/ linkTag.parentNode.removeChild(linkTag)
115-
/******/ reject(err);
107+
/******/ var onLinkComplete = function (event) {
108+
/******/ // avoid mem leaks.
109+
/******/ linkTag.onerror = linkTag.onload = null;
110+
/******/ if (event.type === 'load') {
111+
/******/ resolve();
112+
/******/ } else {
113+
/******/ var request = event && event.target && event.target.href || fullhref;
114+
/******/ var err = new Error("Loading CSS chunk " + chunkId + " failed.\n(" + request + ")");
115+
/******/ err.code = "CSS_CHUNK_LOAD_FAILED";
116+
/******/ err.request = request;
117+
/******/ delete installedCssChunks[chunkId]
118+
/******/ linkTag.parentNode.removeChild(linkTag)
119+
/******/ reject(err);
120+
/******/ }
116121
/******/ };
122+
/******/ linkTag.onerror = linkTag.onload = onLinkComplete;
117123
/******/ linkTag.href = fullhref;
118124
/******/
119125
/******/ (function (linkTag) {

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

+15-9
Original file line numberDiff line numberDiff line change
@@ -162,15 +162,21 @@
162162
/******/
163163
/******/ linkTag.rel = "stylesheet";
164164
/******/ linkTag.type = "text/css";
165-
/******/ linkTag.onload = resolve;
166-
/******/ linkTag.onerror = function(event) {
167-
/******/ var request = event && event.target && event.target.href || fullhref;
168-
/******/ var err = new Error("Loading CSS chunk " + chunkId + " failed.\n(" + request + ")");
169-
/******/ err.code = "CSS_CHUNK_LOAD_FAILED";
170-
/******/ err.request = request;
171-
/******/ linkTag.parentNode.removeChild(linkTag)
172-
/******/ reject(err);
173-
/******/ };
165+
/******/ var onLinkComplete = (event) => {
166+
/******/ // avoid mem leaks.
167+
/******/ linkTag.onerror = linkTag.onload = null;
168+
/******/ if (event.type === 'load') {
169+
/******/ resolve();
170+
/******/ } else {
171+
/******/ var request = event && event.target && event.target.href || fullhref;
172+
/******/ var err = new Error("Loading CSS chunk " + chunkId + " failed.\n(" + request + ")");
173+
/******/ err.code = "CSS_CHUNK_LOAD_FAILED";
174+
/******/ err.request = request;
175+
/******/ linkTag.parentNode.removeChild(linkTag)
176+
/******/ reject(err);
177+
/******/ }
178+
/******/ }
179+
/******/ linkTag.onerror = linkTag.onload = onLinkComplete;
174180
/******/ linkTag.href = fullhref;
175181
/******/
176182
/******/ (function (linkTag) {

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

+15-9
Original file line numberDiff line numberDiff line change
@@ -104,16 +104,22 @@
104104
/******/
105105
/******/ linkTag.rel = "stylesheet";
106106
/******/ linkTag.type = "text/css";
107-
/******/ linkTag.onload = resolve;
108-
/******/ linkTag.onerror = function(event) {
109-
/******/ var request = event && event.target && event.target.href || fullhref;
110-
/******/ var err = new Error("Loading CSS chunk " + chunkId + " failed.\n(" + request + ")");
111-
/******/ err.code = "CSS_CHUNK_LOAD_FAILED";
112-
/******/ err.request = request;
113-
/******/ delete installedCssChunks[chunkId]
114-
/******/ linkTag.parentNode.removeChild(linkTag)
115-
/******/ reject(err);
107+
/******/ var onLinkComplete = function (event) {
108+
/******/ // avoid mem leaks.
109+
/******/ linkTag.onerror = linkTag.onload = null;
110+
/******/ if (event.type === 'load') {
111+
/******/ resolve();
112+
/******/ } else {
113+
/******/ var request = event && event.target && event.target.href || fullhref;
114+
/******/ var err = new Error("Loading CSS chunk " + chunkId + " failed.\n(" + request + ")");
115+
/******/ err.code = "CSS_CHUNK_LOAD_FAILED";
116+
/******/ err.request = request;
117+
/******/ delete installedCssChunks[chunkId]
118+
/******/ linkTag.parentNode.removeChild(linkTag)
119+
/******/ reject(err);
120+
/******/ }
116121
/******/ };
122+
/******/ linkTag.onerror = linkTag.onload = onLinkComplete;
117123
/******/ linkTag.href = fullhref;
118124
/******/
119125
/******/ var target = document.querySelector("script[src='1.js']");

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

+15-9
Original file line numberDiff line numberDiff line change
@@ -162,15 +162,21 @@
162162
/******/
163163
/******/ linkTag.rel = "stylesheet";
164164
/******/ linkTag.type = "text/css";
165-
/******/ linkTag.onload = resolve;
166-
/******/ linkTag.onerror = function(event) {
167-
/******/ var request = event && event.target && event.target.href || fullhref;
168-
/******/ var err = new Error("Loading CSS chunk " + chunkId + " failed.\n(" + request + ")");
169-
/******/ err.code = "CSS_CHUNK_LOAD_FAILED";
170-
/******/ err.request = request;
171-
/******/ linkTag.parentNode.removeChild(linkTag)
172-
/******/ reject(err);
173-
/******/ };
165+
/******/ var onLinkComplete = (event) => {
166+
/******/ // avoid mem leaks.
167+
/******/ linkTag.onerror = linkTag.onload = null;
168+
/******/ if (event.type === 'load') {
169+
/******/ resolve();
170+
/******/ } else {
171+
/******/ var request = event && event.target && event.target.href || fullhref;
172+
/******/ var err = new Error("Loading CSS chunk " + chunkId + " failed.\n(" + request + ")");
173+
/******/ err.code = "CSS_CHUNK_LOAD_FAILED";
174+
/******/ err.request = request;
175+
/******/ linkTag.parentNode.removeChild(linkTag)
176+
/******/ reject(err);
177+
/******/ }
178+
/******/ }
179+
/******/ linkTag.onerror = linkTag.onload = onLinkComplete;
174180
/******/ linkTag.href = fullhref;
175181
/******/
176182
/******/ var target = document.querySelector("script[src='1.js']");

test/cases/insert-undefined/expected/webpack-4/main.js

+15-9
Original file line numberDiff line numberDiff line change
@@ -104,16 +104,22 @@
104104
/******/
105105
/******/ linkTag.rel = "stylesheet";
106106
/******/ linkTag.type = "text/css";
107-
/******/ linkTag.onload = resolve;
108-
/******/ linkTag.onerror = function(event) {
109-
/******/ var request = event && event.target && event.target.href || fullhref;
110-
/******/ var err = new Error("Loading CSS chunk " + chunkId + " failed.\n(" + request + ")");
111-
/******/ err.code = "CSS_CHUNK_LOAD_FAILED";
112-
/******/ err.request = request;
113-
/******/ delete installedCssChunks[chunkId]
114-
/******/ linkTag.parentNode.removeChild(linkTag)
115-
/******/ reject(err);
107+
/******/ var onLinkComplete = function (event) {
108+
/******/ // avoid mem leaks.
109+
/******/ linkTag.onerror = linkTag.onload = null;
110+
/******/ if (event.type === 'load') {
111+
/******/ resolve();
112+
/******/ } else {
113+
/******/ var request = event && event.target && event.target.href || fullhref;
114+
/******/ var err = new Error("Loading CSS chunk " + chunkId + " failed.\n(" + request + ")");
115+
/******/ err.code = "CSS_CHUNK_LOAD_FAILED";
116+
/******/ err.request = request;
117+
/******/ delete installedCssChunks[chunkId]
118+
/******/ linkTag.parentNode.removeChild(linkTag)
119+
/******/ reject(err);
120+
/******/ }
116121
/******/ };
122+
/******/ linkTag.onerror = linkTag.onload = onLinkComplete;
117123
/******/ linkTag.href = fullhref;
118124
/******/
119125
/******/ document.head.appendChild(linkTag);

test/cases/insert-undefined/expected/webpack-5/main.js

+15-9
Original file line numberDiff line numberDiff line change
@@ -162,15 +162,21 @@
162162
/******/
163163
/******/ linkTag.rel = "stylesheet";
164164
/******/ linkTag.type = "text/css";
165-
/******/ linkTag.onload = resolve;
166-
/******/ linkTag.onerror = function(event) {
167-
/******/ var request = event && event.target && event.target.href || fullhref;
168-
/******/ var err = new Error("Loading CSS chunk " + chunkId + " failed.\n(" + request + ")");
169-
/******/ err.code = "CSS_CHUNK_LOAD_FAILED";
170-
/******/ err.request = request;
171-
/******/ linkTag.parentNode.removeChild(linkTag)
172-
/******/ reject(err);
173-
/******/ };
165+
/******/ var onLinkComplete = (event) => {
166+
/******/ // avoid mem leaks.
167+
/******/ linkTag.onerror = linkTag.onload = null;
168+
/******/ if (event.type === 'load') {
169+
/******/ resolve();
170+
/******/ } else {
171+
/******/ var request = event && event.target && event.target.href || fullhref;
172+
/******/ var err = new Error("Loading CSS chunk " + chunkId + " failed.\n(" + request + ")");
173+
/******/ err.code = "CSS_CHUNK_LOAD_FAILED";
174+
/******/ err.request = request;
175+
/******/ linkTag.parentNode.removeChild(linkTag)
176+
/******/ reject(err);
177+
/******/ }
178+
/******/ }
179+
/******/ linkTag.onerror = linkTag.onload = onLinkComplete;
174180
/******/ linkTag.href = fullhref;
175181
/******/
176182
/******/ document.head.appendChild(linkTag);

0 commit comments

Comments
 (0)