Skip to content

Commit 91ceaf2

Browse files
fix: algorithm for importing modules (#449)
1 parent 1138ed7 commit 91ceaf2

File tree

15 files changed

+290
-36
lines changed

15 files changed

+290
-36
lines changed

src/index.js

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -161,9 +161,7 @@ if (content.locals) {
161161
162162
exported.use = function() {
163163
if (!(refs++)) {
164-
var id = ${loaderUtils.stringifyRequest(this, `!!${request}`)};
165-
166-
dispose = api(id, content, options);
164+
dispose = api(module.id, content, options);
167165
}
168166
169167
return exported;
@@ -251,8 +249,7 @@ var options = ${JSON.stringify(options)};
251249
options.insert = ${insert};
252250
options.singleton = ${isSingleton};
253251
254-
var id = ${loaderUtils.stringifyRequest(this, `!!${request}`)};
255-
var update = api(id, content, options);
252+
var update = api(module.id, content, options);
256253
257254
var exported = content.locals ? content.locals : {};
258255

src/runtime/injectStylesIntoStyleTag.js

Lines changed: 41 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
const stylesInDom = {};
2-
31
const isOldIE = (function isOldIE() {
42
let memo;
53

@@ -46,38 +44,22 @@ const getTarget = (function getTarget() {
4644
};
4745
})();
4846

49-
function addModulesToDom(id, list, options) {
50-
if (Object.prototype.toString.call(list) !== '[object Array]') {
51-
return;
52-
}
53-
54-
id = options.base ? id + options.base : id;
55-
56-
if (!stylesInDom[id]) {
57-
stylesInDom[id] = [];
58-
}
47+
const stylesInDom = {};
5948

49+
function modulesToDom(moduleId, list, options) {
6050
for (let i = 0; i < list.length; i++) {
61-
const item = list[i];
62-
const part = { css: item[1], media: item[2], sourceMap: item[3] };
63-
const styleInDomById = stylesInDom[id];
51+
const part = {
52+
css: list[i][1],
53+
media: list[i][2],
54+
sourceMap: list[i][3],
55+
};
6456

65-
if (styleInDomById[i]) {
66-
styleInDomById[i].updater(part);
57+
if (stylesInDom[moduleId][i]) {
58+
stylesInDom[moduleId][i](part);
6759
} else {
68-
styleInDomById.push({ updater: addStyle(part, options) });
60+
stylesInDom[moduleId].push(addStyle(part, options));
6961
}
7062
}
71-
72-
for (let j = list.length; j < stylesInDom[id].length; j++) {
73-
stylesInDom[id][j].updater();
74-
}
75-
76-
stylesInDom[id].length = list.length;
77-
78-
if (stylesInDom[id].length === 0) {
79-
delete stylesInDom[id];
80-
}
8163
}
8264

8365
function insertStyleElement(options) {
@@ -230,7 +212,7 @@ function addStyle(obj, options) {
230212
};
231213
}
232214

233-
module.exports = (id, list, options) => {
215+
module.exports = (moduleId, list, options) => {
234216
options = options || {};
235217

236218
// Force single-tag solution on IE6-9, which has a hard limit on the # of <style>
@@ -239,9 +221,37 @@ module.exports = (id, list, options) => {
239221
options.singleton = isOldIE();
240222
}
241223

242-
addModulesToDom(id, list, options);
224+
moduleId = options.base ? moduleId + options.base : moduleId;
225+
226+
list = list || [];
227+
228+
if (!stylesInDom[moduleId]) {
229+
stylesInDom[moduleId] = [];
230+
}
231+
232+
modulesToDom(moduleId, list, options);
243233

244234
return function update(newList) {
245-
addModulesToDom(id, newList || [], options);
235+
newList = newList || [];
236+
237+
if (Object.prototype.toString.call(newList) !== '[object Array]') {
238+
return;
239+
}
240+
241+
if (!stylesInDom[moduleId]) {
242+
stylesInDom[moduleId] = [];
243+
}
244+
245+
modulesToDom(moduleId, newList, options);
246+
247+
for (let j = newList.length; j < stylesInDom[moduleId].length; j++) {
248+
stylesInDom[moduleId][j]();
249+
}
250+
251+
stylesInDom[moduleId].length = newList.length;
252+
253+
if (stylesInDom[moduleId].length === 0) {
254+
delete stylesInDom[moduleId];
255+
}
246256
};
247257
};

test/__snapshots__/loader.test.js.snap

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,30 @@ exports[`loader should work when the "injectType" option is "lazySingletonStyleT
362362
363363
exports[`loader should work when the "injectType" option is "lazySingletonStyleTag" and ES module syntax used: warnings 1`] = `Array []`;
364364
365+
exports[`loader should work when the "injectType" option is "lazySingletonStyleTag" and files have same name: DOM 1`] = `
366+
"<!DOCTYPE html><html><head>
367+
<title>style-loader test</title>
368+
<style id=\\"existing-style\\">.existing { color: yellow }</style>
369+
<style>.foo {
370+
color: red;
371+
}
372+
.bar {
373+
color: blue;
374+
}
375+
</style></head>
376+
<body>
377+
<h1>Body</h1>
378+
<div class=\\"target\\"></div>
379+
<iframe class=\\"iframeTarget\\"></iframe>
380+
381+
382+
</body></html>"
383+
`;
384+
385+
exports[`loader should work when the "injectType" option is "lazySingletonStyleTag" and files have same name: errors 1`] = `Array []`;
386+
387+
exports[`loader should work when the "injectType" option is "lazySingletonStyleTag" and files have same name: warnings 1`] = `Array []`;
388+
365389
exports[`loader should work when the "injectType" option is "lazySingletonStyleTag": DOM 1`] = `
366390
"<!DOCTYPE html><html><head>
367391
<title>style-loader test</title>
@@ -434,6 +458,30 @@ exports[`loader should work when the "injectType" option is "lazyStyleTag" and E
434458
435459
exports[`loader should work when the "injectType" option is "lazyStyleTag" and ES module syntax used: warnings 1`] = `Array []`;
436460
461+
exports[`loader should work when the "injectType" option is "lazyStyleTag" and files have same name: DOM 1`] = `
462+
"<!DOCTYPE html><html><head>
463+
<title>style-loader test</title>
464+
<style id=\\"existing-style\\">.existing { color: yellow }</style>
465+
<style>.foo {
466+
color: red;
467+
}
468+
</style><style>.bar {
469+
color: blue;
470+
}
471+
</style></head>
472+
<body>
473+
<h1>Body</h1>
474+
<div class=\\"target\\"></div>
475+
<iframe class=\\"iframeTarget\\"></iframe>
476+
477+
478+
</body></html>"
479+
`;
480+
481+
exports[`loader should work when the "injectType" option is "lazyStyleTag" and files have same name: errors 1`] = `Array []`;
482+
483+
exports[`loader should work when the "injectType" option is "lazyStyleTag" and files have same name: warnings 1`] = `Array []`;
484+
437485
exports[`loader should work when the "injectType" option is "lazyStyleTag": DOM 1`] = `
438486
"<!DOCTYPE html><html><head>
439487
<title>style-loader test</title>
@@ -494,6 +542,24 @@ exports[`loader should work when the "injectType" option is "linkTag" and ES mod
494542
495543
exports[`loader should work when the "injectType" option is "linkTag" and ES module syntax used: warnings 1`] = `Array []`;
496544
545+
exports[`loader should work when the "injectType" option is "linkTag" and files have same name: DOM 1`] = `
546+
"<!DOCTYPE html><html><head>
547+
<title>style-loader test</title>
548+
<style id=\\"existing-style\\">.existing { color: yellow }</style>
549+
<link rel=\\"stylesheet\\" href=\\"04ef9d7491cb6b87d905831b3cb52fdc.css\\"><link rel=\\"stylesheet\\" href=\\"a948740e081d1358c62c536683d63685.css\\"></head>
550+
<body>
551+
<h1>Body</h1>
552+
<div class=\\"target\\"></div>
553+
<iframe class=\\"iframeTarget\\"></iframe>
554+
555+
556+
</body></html>"
557+
`;
558+
559+
exports[`loader should work when the "injectType" option is "linkTag" and files have same name: errors 1`] = `Array []`;
560+
561+
exports[`loader should work when the "injectType" option is "linkTag" and files have same name: warnings 1`] = `Array []`;
562+
497563
exports[`loader should work when the "injectType" option is "linkTag": DOM 1`] = `
498564
"<!DOCTYPE html><html><head>
499565
<title>style-loader test</title>
@@ -560,6 +626,30 @@ exports[`loader should work when the "injectType" option is "singletonStyleTag"
560626
561627
exports[`loader should work when the "injectType" option is "singletonStyleTag" and ES module syntax used: warnings 1`] = `Array []`;
562628
629+
exports[`loader should work when the "injectType" option is "singletonStyleTag" and files have same name: DOM 1`] = `
630+
"<!DOCTYPE html><html><head>
631+
<title>style-loader test</title>
632+
<style id=\\"existing-style\\">.existing { color: yellow }</style>
633+
<style>.foo {
634+
color: red;
635+
}
636+
.bar {
637+
color: blue;
638+
}
639+
</style></head>
640+
<body>
641+
<h1>Body</h1>
642+
<div class=\\"target\\"></div>
643+
<iframe class=\\"iframeTarget\\"></iframe>
644+
645+
646+
</body></html>"
647+
`;
648+
649+
exports[`loader should work when the "injectType" option is "singletonStyleTag" and files have same name: errors 1`] = `Array []`;
650+
651+
exports[`loader should work when the "injectType" option is "singletonStyleTag" and files have same name: warnings 1`] = `Array []`;
652+
563653
exports[`loader should work when the "injectType" option is "singletonStyleTag": DOM 1`] = `
564654
"<!DOCTYPE html><html><head>
565655
<title>style-loader test</title>
@@ -632,6 +722,30 @@ exports[`loader should work when the "injectType" option is "styleTag" and ES mo
632722
633723
exports[`loader should work when the "injectType" option is "styleTag" and ES module syntax used: warnings 1`] = `Array []`;
634724
725+
exports[`loader should work when the "injectType" option is "styleTag" and files have same name: DOM 1`] = `
726+
"<!DOCTYPE html><html><head>
727+
<title>style-loader test</title>
728+
<style id=\\"existing-style\\">.existing { color: yellow }</style>
729+
<style>.foo {
730+
color: red;
731+
}
732+
</style><style>.bar {
733+
color: blue;
734+
}
735+
</style></head>
736+
<body>
737+
<h1>Body</h1>
738+
<div class=\\"target\\"></div>
739+
<iframe class=\\"iframeTarget\\"></iframe>
740+
741+
742+
</body></html>"
743+
`;
744+
745+
exports[`loader should work when the "injectType" option is "styleTag" and files have same name: errors 1`] = `Array []`;
746+
747+
exports[`loader should work when the "injectType" option is "styleTag" and files have same name: warnings 1`] = `Array []`;
748+
635749
exports[`loader should work when the "injectType" option is "styleTag": DOM 1`] = `
636750
"<!DOCTYPE html><html><head>
637751
<title>style-loader test</title>

test/fixtures/lazy-multiple.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import style from './nested/style.css';
2+
import otherStyle from './other-nested/style.css';
3+
4+
style.use();
5+
otherStyle.use();

test/fixtures/multiple.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import './nested/style.css';
2+
import './other-nested/style.css';

test/fixtures/nested/style.css

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.foo {
2+
color: red;
3+
}

test/fixtures/other-nested/style.css

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.bar {
2+
color: blue;
3+
}

test/loader.test.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,21 @@ describe('loader', () => {
287287
expect(getErrors(stats)).toMatchSnapshot('errors');
288288
});
289289

290+
it(`should work when the "injectType" option is "${injectType}" and files have same name`, async () => {
291+
expect.assertions(3);
292+
293+
const entry = getEntryByInjectType('multiple.js', injectType);
294+
const compiler = getCompiler(entry, { injectType });
295+
const stats = await compile(compiler);
296+
297+
runInJsDom('main.bundle.js', compiler, stats, (dom) => {
298+
expect(dom.serialize()).toMatchSnapshot('DOM');
299+
});
300+
301+
expect(getWarnings(stats)).toMatchSnapshot('warnings');
302+
expect(getErrors(stats)).toMatchSnapshot('errors');
303+
});
304+
290305
if (['lazyStyleTag', 'lazySingletonStyleTag'].includes(injectType)) {
291306
it(`should work when ref is negative when the "injectType" option is "${injectType}"`, async () => {
292307
expect.assertions(3);

test/manual/index.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,11 @@ <h2>Order</h2>
7070
<div class="order">BACKGROUND SHOULD BE RED</div>
7171
</section>
7272

73+
<section>
74+
<h2>Duplicate</h2>
75+
<div class="duplicate">SHOULD BE BLUE</div>
76+
</section>
77+
7378
<section>
7479
<h2>Custom element</h2>
7580
<custom-square l="100" c="red"></custom-square>

test/manual/src/duplicate.css

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.duplicate {
2+
color: red;
3+
}

0 commit comments

Comments
 (0)