Skip to content

Commit 6505149

Browse files
committed
Add support for the insert option
1 parent c7eda97 commit 6505149

File tree

5 files changed

+84
-8
lines changed

5 files changed

+84
-8
lines changed

README.md

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -343,30 +343,77 @@ module.exports = {
343343
};
344344
```
345345

346-
#### Module Filename Option
346+
### Plugin Options
347+
348+
#### moduleFilename
347349

348350
With the `moduleFilename` option you can use chunk data to customize the filename. This is particularly useful when dealing with multiple entry points and wanting to get more control out of the filename for a given entry point/chunk. In the example below, we'll use `moduleFilename` to output the generated css into a different directory.
349351

350352
```javascript
351-
const miniCssExtractPlugin = new MiniCssExtractPlugin({
353+
new MiniCssExtractPlugin({
352354
moduleFilename: ({ name }) => `${name.replace('/js/', '/css/')}.css`,
353355
});
354356
```
355357

356-
#### Long Term Caching
358+
#### filename
357359

358360
For long term caching use `filename: "[contenthash].css"`. Optionally add `[name]`.
359361

360-
### Remove Order Warnings
362+
#### ignoreOrder
363+
364+
Removes order warnings.
361365

362366
For projects where css ordering has been mitigated through consistent use of scoping or naming conventions, the css order warnings can be disabled by setting the ignoreOrder flag to true for the plugin.
363367

364368
```javascript
365369
new MiniCssExtractPlugin({
366370
ignoreOrder: true,
367-
}),
371+
});
372+
```
373+
374+
### insert
375+
376+
Type: `String|Function`
377+
Default: `head`
378+
379+
By default, the `mini-css-extract-plugin` appends styles (`<link>` elements) to `document.head` of the current `window`.
380+
381+
However in some circumstances it might be necessary to have finer control over the append target or even delay `link` elements instertion. For example this is the case when you asynchronously load styles for an application that runs inside of an iframe. In such cases `insert` can be configured to be a function or a custom selector.
382+
383+
If you target an [iframe](https://developer.mozilla.org/en-US/docs/Web/API/HTMLIFrameElement) make sure that the parent document can has sufficient access rights to reach into the frame document and append elements to it.
384+
385+
#### `String`
386+
387+
Allows to configure a [CSS selector](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector) that will be used to find the element where to append the styles (`link` elements).
388+
389+
```js
390+
new MiniCssExtractPlugin({
391+
insert: '#my-container',
392+
});
393+
```
394+
395+
A new `<link>` element will be appended to the `#my-container` element.
396+
397+
#### `Function`
398+
399+
Allows to override default behavior and insert styles at any position.
400+
401+
> ⚠ Do not forget that this code will run in the browser alongside your application. Since not all browsers support latest ECMA features like `let`, `const`, `arrow function expression` and etc we recommend you to use only ECMA 5 features and syntax.
402+
> ⚠ The `insert` function is serialized to string and passed to the plugin. This means that it won't have access to the scope of the webpack configuration module.
403+
404+
```js
405+
new MiniCssExtractPlugin({
406+
insert: function insert(linkTag) {
407+
const reference = document.querySelector('#some-element');
408+
if (reference) {
409+
reference.parentNode.insertBefore(linkTag, reference);
410+
}
411+
},
412+
});
368413
```
369414

415+
A new `<link>` element will be inserted before the element with id `some-element`.
416+
370417
### Media Query Plugin
371418

372419
If you'd like to extract the media queries from the extracted CSS (so mobile users don't need to load desktop or tablet specific CSS anymore) you should use one of the following plugins:

src/index.js

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,13 +97,23 @@ class CssModuleFactory {
9797

9898
class MiniCssExtractPlugin {
9999
constructor(options = {}) {
100+
const insert =
101+
typeof options.insert === 'undefined'
102+
? '"head"'
103+
: typeof options.insert === 'string'
104+
? JSON.stringify(options.insert)
105+
: options.insert.toString();
106+
100107
this.options = Object.assign(
101108
{
102109
filename: DEFAULT_FILENAME,
103110
moduleFilename: () => this.options.filename || DEFAULT_FILENAME,
104111
ignoreOrder: false,
105112
},
106-
options
113+
options,
114+
{
115+
insert,
116+
}
107117
);
108118

109119
if (!this.options.chunkFilename) {
@@ -316,6 +326,8 @@ class MiniCssExtractPlugin {
316326
}
317327
);
318328

329+
const { insert } = this.options;
330+
319331
return Template.asString([
320332
source,
321333
'',
@@ -371,8 +383,9 @@ class MiniCssExtractPlugin {
371383
'}',
372384
])
373385
: '',
374-
'var head = document.getElementsByTagName("head")[0];',
375-
'head.appendChild(linkTag);',
386+
`var insert = ${insert};`,
387+
`if (typeof insert === 'function') { insert(linkTag); }`,
388+
`else { var target = document.querySelector(${insert}); target && target.appendChild(linkTag); } `,
376389
]),
377390
'}).then(function() {',
378391
Template.indent(['installedCssChunks[chunkId] = 0;']),

src/loader.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ export function pitch(request) {
7575
: typeof options.publicPath === 'function'
7676
? options.publicPath(this.resourcePath, this.rootContext)
7777
: this._compilation.outputOptions.publicPath;
78+
7879
const outputOptions = {
7980
filename: childFilename,
8081
publicPath,

src/options.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,17 @@
1010
"instanceof": "Function"
1111
}
1212
]
13+
},
14+
"insert": {
15+
"description": "Inserts `<link>` at the given position (https://github.com/webpack-contrib/mini-css-extract-plugin#insert).",
16+
"anyOf": [
17+
{
18+
"type": "string"
19+
},
20+
{
21+
"instanceof": "Function"
22+
}
23+
]
1324
}
1425
},
1526
"errorMessages": {

test/manual/webpack.config.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/* globals document */
12
const Self = require('../../');
23

34
module.exports = {
@@ -19,6 +20,9 @@ module.exports = {
1920
new Self({
2021
filename: '[name].css',
2122
chunkFilename: '[contenthash].css',
23+
insert: function insert(linkTag) {
24+
document.head.appendChild(linkTag);
25+
},
2226
}),
2327
],
2428
devServer: {

0 commit comments

Comments
 (0)