Skip to content

Commit 7122cde

Browse files
refactor!: the insert option can only be a selector or the path to the module
1 parent 11b8639 commit 7122cde

12 files changed

+180
-185
lines changed

README.md

Lines changed: 102 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -450,9 +450,7 @@ module.exports = {
450450
Type:
451451

452452
```ts
453-
type insert =
454-
| string
455-
| ((htmlElement: HTMLElement, options: Record<string, any>) => void);
453+
type insert = string;
456454
```
457455

458456
Default: `head`
@@ -462,9 +460,7 @@ This will cause CSS created by the loader to take priority over CSS already pres
462460
You can use other values if the standard behavior is not suitable for you, but we do not recommend doing this.
463461
If you target an [iframe](https://developer.mozilla.org/en-US/docs/Web/API/HTMLIFrameElement) make sure you have sufficient access rights, the styles will be injected into the content document head.
464462

465-
#### `string`
466-
467-
##### `Selector`
463+
#### `Selector`
468464

469465
Allows to setup custom [query selector](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector) where styles inject into the DOM.
470466

@@ -491,7 +487,7 @@ module.exports = {
491487
};
492488
```
493489

494-
##### `Absolute path to function`
490+
#### `Absolute path to function`
495491

496492
Allows to setup absolute path to custom function that allows to override default behavior and insert styles at any position.
497493

@@ -515,7 +511,7 @@ module.exports = {
515511
{
516512
loader: "style-loader",
517513
options: {
518-
insert: require.resolve("modulePath"),
514+
insert: require.resolve("./path-to-insert-module"),
519515
},
520516
},
521517
"css-loader",
@@ -528,17 +524,32 @@ module.exports = {
528524

529525
A new `<style>`/`<link>` elements will be inserted into at bottom of `body` tag.
530526

531-
#### `function`
527+
Examples:
532528

533-
Allows to override default behavior and insert styles at any position.
529+
Insert styles at top of `head` tag:
534530

535-
> **Warning**
536-
>
537-
> Do not forget that this code will be used in the browser and not all browsers support latest ECMA features like `let`, `const`, `arrow function expression` and etc, we recommend use only ECMA 5 features, but it is depends what browsers you want to support
531+
**insert-function.js**
538532

539-
> **Warning**
540-
>
541-
> Do not forget that some DOM methods may not be available in older browsers, we recommended use only [DOM core level 2 properties](https://caniuse.com/#search=DOM%20Core), but it is depends what browsers you want to support
533+
```js
534+
function insertAtTop(element) {
535+
var parent = document.querySelector("head");
536+
// eslint-disable-next-line no-underscore-dangle
537+
var lastInsertedElement = window._lastElementInsertedByStyleLoader;
538+
539+
if (!lastInsertedElement) {
540+
parent.insertBefore(element, parent.firstChild);
541+
} else if (lastInsertedElement.nextSibling) {
542+
parent.insertBefore(element, lastInsertedElement.nextSibling);
543+
} else {
544+
parent.appendChild(element);
545+
}
546+
547+
// eslint-disable-next-line no-underscore-dangle
548+
window._lastElementInsertedByStyleLoader = element;
549+
}
550+
551+
module.exports = insertAtTop;
552+
```
542553

543554
**webpack.config.js**
544555

@@ -552,23 +563,7 @@ module.exports = {
552563
{
553564
loader: "style-loader",
554565
options: {
555-
insert: function insertAtTop(element) {
556-
var parent = document.querySelector("head");
557-
// eslint-disable-next-line no-underscore-dangle
558-
var lastInsertedElement =
559-
window._lastElementInsertedByStyleLoader;
560-
561-
if (!lastInsertedElement) {
562-
parent.insertBefore(element, parent.firstChild);
563-
} else if (lastInsertedElement.nextSibling) {
564-
parent.insertBefore(element, lastInsertedElement.nextSibling);
565-
} else {
566-
parent.appendChild(element);
567-
}
568-
569-
// eslint-disable-next-line no-underscore-dangle
570-
window._lastElementInsertedByStyleLoader = element;
571-
},
566+
insert: require.resolve("./insert-function"),
572567
},
573568
},
574569
"css-loader",
@@ -579,10 +574,20 @@ module.exports = {
579574
};
580575
```
581576

582-
Insert styles at top of `head` tag.
583-
584577
You can pass any parameters to `style.use(options)` and this value will be passed to `insert` and `styleTagTransform` functions.
585578

579+
**insert-function.js**
580+
581+
```js
582+
function insertIntoTarget(element, options) {
583+
var parent = options.target || document.head;
584+
585+
parent.appendChild(element);
586+
}
587+
588+
module.exports = insertIntoTarget;
589+
```
590+
586591
**webpack.config.js**
587592

588593
```js
@@ -599,12 +604,8 @@ module.exports = {
599604
// Do not forget that this code will be used in the browser and
600605
// not all browsers support latest ECMA features like `let`, `const`, `arrow function expression` and etc,
601606
// we recommend use only ECMA 5 features,
602-
// but it is depends what browsers you want to support
603-
insert: function insertIntoTarget(element, options) {
604-
var parent = options.target || document.head;
605-
606-
parent.appendChild(element);
607-
},
607+
// but it depends what browsers you want to support
608+
insert: require.resolve("./insert-function.js"),
608609
},
609610
},
610611
"css-loader",
@@ -1031,7 +1032,28 @@ The loader generate:
10311032

10321033
#### Insert styles at top
10331034

1034-
Inserts styles at top of `head` tag.
1035+
Insert styles at top of `head` tag.
1036+
1037+
**insert-function.js**
1038+
1039+
```js
1040+
function insertAtTop(element) {
1041+
var parent = document.querySelector("head");
1042+
var lastInsertedElement = window._lastElementInsertedByStyleLoader;
1043+
1044+
if (!lastInsertedElement) {
1045+
parent.insertBefore(element, parent.firstChild);
1046+
} else if (lastInsertedElement.nextSibling) {
1047+
parent.insertBefore(element, lastInsertedElement.nextSibling);
1048+
} else {
1049+
parent.appendChild(element);
1050+
}
1051+
1052+
window._lastElementInsertedByStyleLoader = element;
1053+
}
1054+
1055+
module.exports = insertAtTop;
1056+
```
10351057

10361058
**webpack.config.js**
10371059

@@ -1045,21 +1067,7 @@ module.exports = {
10451067
{
10461068
loader: "style-loader",
10471069
options: {
1048-
insert: function insertAtTop(element) {
1049-
var parent = document.querySelector("head");
1050-
var lastInsertedElement =
1051-
window._lastElementInsertedByStyleLoader;
1052-
1053-
if (!lastInsertedElement) {
1054-
parent.insertBefore(element, parent.firstChild);
1055-
} else if (lastInsertedElement.nextSibling) {
1056-
parent.insertBefore(element, lastInsertedElement.nextSibling);
1057-
} else {
1058-
parent.appendChild(element);
1059-
}
1060-
1061-
window._lastElementInsertedByStyleLoader = element;
1062-
},
1070+
insert: require.resolve("./insert-function.js"),
10631071
},
10641072
},
10651073
"css-loader",
@@ -1074,6 +1082,29 @@ module.exports = {
10741082

10751083
Inserts styles before `#id` element.
10761084

1085+
**insert-function.js**
1086+
1087+
```js
1088+
function insertBeforeAt(element) {
1089+
const parent = document.querySelector("head");
1090+
const target = document.querySelector("#id");
1091+
1092+
const lastInsertedElement = window._lastElementInsertedByStyleLoader;
1093+
1094+
if (!lastInsertedElement) {
1095+
parent.insertBefore(element, target);
1096+
} else if (lastInsertedElement.nextSibling) {
1097+
parent.insertBefore(element, lastInsertedElement.nextSibling);
1098+
} else {
1099+
parent.appendChild(element);
1100+
}
1101+
1102+
window._lastElementInsertedByStyleLoader = element;
1103+
}
1104+
1105+
module.exports = insertBeforeAt;
1106+
```
1107+
10771108
**webpack.config.js**
10781109

10791110
```js
@@ -1086,23 +1117,7 @@ module.exports = {
10861117
{
10871118
loader: "style-loader",
10881119
options: {
1089-
insert: function insertBeforeAt(element) {
1090-
const parent = document.querySelector("head");
1091-
const target = document.querySelector("#id");
1092-
1093-
const lastInsertedElement =
1094-
window._lastElementInsertedByStyleLoader;
1095-
1096-
if (!lastInsertedElement) {
1097-
parent.insertBefore(element, target);
1098-
} else if (lastInsertedElement.nextSibling) {
1099-
parent.insertBefore(element, lastInsertedElement.nextSibling);
1100-
} else {
1101-
parent.appendChild(element);
1102-
}
1103-
1104-
window._lastElementInsertedByStyleLoader = element;
1105-
},
1120+
insert: require.resolve("./insert-function.js"),
11061121
},
11071122
},
11081123
"css-loader",
@@ -1117,6 +1132,18 @@ module.exports = {
11171132

11181133
You can define custom target for your styles for the `lazyStyleTag` type.
11191134

1135+
**insert-function.js**
1136+
1137+
```js
1138+
function insertIntoTarget(element, options) {
1139+
var parent = options.target || document.head;
1140+
1141+
parent.appendChild(element);
1142+
}
1143+
1144+
module.exports = insertIntoTarget;
1145+
```
1146+
11201147
**webpack.config.js**
11211148

11221149
```js
@@ -1134,11 +1161,7 @@ module.exports = {
11341161
// not all browsers support latest ECMA features like `let`, `const`, `arrow function expression` and etc,
11351162
// we recommend use only ECMA 5 features,
11361163
// but it is depends what browsers you want to support
1137-
insert: function insertIntoTarget(element, options) {
1138-
var parent = options.target || document.head;
1139-
1140-
parent.appendChild(element);
1141-
},
1164+
insert: require.resolve("./insert-function.js"),
11421165
},
11431166
},
11441167
"css-loader",

src/index.js

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,9 @@ loader.pitch = function pitch(request) {
7474
}
7575

7676
const insertType =
77-
typeof options.insert === "function"
78-
? "function"
79-
: options.insert && path.isAbsolute(options.insert)
80-
? "module-path"
81-
: "selector";
77+
options.insert && path.isAbsolute(options.insert)
78+
? "module-path"
79+
: "selector";
8280

8381
switch (injectType) {
8482
case "linkTag": {

src/options.json

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,7 @@
2323
"insert": {
2424
"description": "Inserts `<style>`/`<link>` at the given position.",
2525
"link": "https://github.com/webpack-contrib/style-loader#insert",
26-
"anyOf": [
27-
{
28-
"type": "string"
29-
},
30-
{
31-
"instanceof": "Function"
32-
}
33-
]
26+
"type": "string"
3427
},
3528
"base": {
3629
"description": "Sets module ID base for DLLPlugin.",
@@ -45,14 +38,7 @@
4538
"styleTagTransform": {
4639
"description": "Transform tag and css when insert 'style' tag into the DOM",
4740
"link": "https://github.com/webpack-contrib/style-loader#styleTagTransform",
48-
"anyOf": [
49-
{
50-
"type": "string"
51-
},
52-
{
53-
"instanceof": "Function"
54-
}
55-
]
41+
"type": "string"
5642
}
5743
},
5844
"additionalProperties": false

src/utils.js

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -80,17 +80,6 @@ function getImportInsertBySelectorCode(
8080
insertType,
8181
options,
8282
) {
83-
if (insertType === "selector") {
84-
const modulePath = stringifyRequest(
85-
loaderContext,
86-
`!${path.join(__dirname, "runtime/insertBySelector.js")}`,
87-
);
88-
89-
return esModule
90-
? `import insertFn from ${modulePath};`
91-
: `var insertFn = require(${modulePath});`;
92-
}
93-
9483
if (insertType === "module-path") {
9584
const modulePath = stringifyRequest(loaderContext, `${options.insert}`);
9685

@@ -101,24 +90,24 @@ function getImportInsertBySelectorCode(
10190
: `var insertFn = require(${modulePath});`;
10291
}
10392

104-
return "";
93+
const modulePath = stringifyRequest(
94+
loaderContext,
95+
`!${path.join(__dirname, "runtime/insertBySelector.js")}`,
96+
);
97+
98+
return esModule
99+
? `import insertFn from ${modulePath};`
100+
: `var insertFn = require(${modulePath});`;
105101
}
106102

107103
function getInsertOptionCode(insertType, options) {
108-
if (insertType === "selector") {
109-
const insert = options.insert ? JSON.stringify(options.insert) : '"head"';
110-
111-
return `
112-
options.insert = insertFn.bind(null, ${insert});
113-
`;
114-
}
115-
116104
if (insertType === "module-path") {
117105
return `options.insert = insertFn;`;
118106
}
119107

120-
// Todo remove "function" type for insert option in next major release, because code duplication occurs. Leave require.resolve()
121-
return `options.insert = ${options.insert.toString()};`;
108+
const insert = options.insert ? JSON.stringify(options.insert) : '"head"';
109+
110+
return `options.insert = insertFn.bind(null, ${insert});`;
122111
}
123112

124113
function getImportInsertStyleElementCode(esModule, loaderContext) {

0 commit comments

Comments
 (0)