Skip to content

Commit

Permalink
feat: new injectType option
Browse files Browse the repository at this point in the history
BREAKING CHANGE: the `style-loader/url` and the `style-loader/useable` were removed in favor `injectType` option (look documentation). The `singleton` option was removed (look documentation about `injectType`).
  • Loading branch information
evilebottnawi authored Jul 31, 2019
1 parent c5992e4 commit e2664e9
Show file tree
Hide file tree
Showing 32 changed files with 1,199 additions and 569 deletions.
270 changes: 221 additions & 49 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,42 @@ import style from './file.css';
style.className === 'z849f98ca812';
```

### `Useable`
## Options

| Name | Type | Default | Description |
| :--------------: | :------------------: | :--------: | :------------------------------------------------- |
| **`injectType`** | `{String}` | `styleTag` | Allows to setup how styles will be injected in DOM |
| **`attributes`** | `{Object}` | `{}` | Add custom attributes to tag |
| **`insertAt`** | `{String\|Object}` | `bottom` | Inserts tag at the given position |
| **`insertInto`** | `{String\|Function}` | `<head>` | Inserts tag into the given position |
| **`base`** | `{Number}` | `true` | Set module ID base (DLLPlugin) |

### `injectType`

Type: `String`
Default: `styleTag`

Allows to setup how styles will be injected in DOM.

The `style-loader` injects the styles lazily making them useable on-demand via `style.use()` / `style.unuse()`
Possible values:

- `styleTag`
- `singletonStyleTag`
- `lazyStyleTag`
- `lazySingletonStyleTag`
- `linkTag`

When you `lazyStyleTag` or `lazySingletonStyleTag` value the `style-loader` injects the styles lazily making them useable on-demand via `style.use()` / `style.unuse()`.
It is named `Reference Counter API`.

**component.js**

```js
import style from './file.css';

style.use(); // = style.ref();
style.unuse(); // = style.unref();
```

By convention the `Reference Counter API` should be bound to `.useable.css` and the `.css` should be loaded with basic `style-loader` usage.(similar to other file types, i.e. `.useable.less` and `.less`).

Expand All @@ -84,15 +117,19 @@ module.exports = {
module: {
rules: [
{
test: /\.css$/,
exclude: /\.useable\.css$/,
test: /\.css$/i,
exclude: /\.useable\.css$/i,
use: [{ loader: 'style-loader' }, { loader: 'css-loader' }],
},
{
test: /\.useable\.css$/,
test: /\.useable\.css$/i,
use: [
{
loader: 'style-loader/useable',
loader: 'style-loader',
options: {
// Can be `'lazyStyleTag'` or `'lazySingletonStyleTag'`
injectType: 'lazyStyleTag',
},
},
{ loader: 'css-loader' },
],
Expand All @@ -102,27 +139,57 @@ module.exports = {
};
```

#### `Reference Counter API`
Styles are not added on `import/require()`, but instead on call to `use`/`ref`. Styles are removed from page if `unuse`/`unref` is called exactly as often as `use`/`ref`.

**component.js**
> ⚠️ Behavior is undefined when `unuse`/`unref` is called more often than `use`/`ref`. Don't do that.
#### `styleTag`

Injects styles in multiple `<style></style>`. It is **default** behaviour.

```js
import style from './file.css';
import './styles.css';
```

style.use(); // = style.ref();
style.unuse(); // = style.unref();
**webpack.config.js**

```js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
use: [
{ loader: 'style-loader', options: { injectType: 'styleTag' } },
'css-loader',
],
},
],
},
};
```

Styles are not added on `import/require()`, but instead on call to `use`/`ref`. Styles are removed from page if `unuse`/`unref` is called exactly as often as `use`/`ref`.
The loader inject styles like:

> ⚠️ Behavior is undefined when `unuse`/`unref` is called more often than `use`/`ref`. Don't do that.
```html
<style>
.foo {
color: red;
}
</style>
<style>
.bar {
color: blue;
}
</style>
```

### `Url`
#### `singletonStyleTag`

It's also possible to add a URL `<link href="path/to/file.css" rel="stylesheet">` instead of inlining the CSS `{String}` with `<style></style>` tag.
Injects styles in one `<style></style>`.

```js
import url from 'file.css';
import './styles.css';
```

**webpack.config.js**
Expand All @@ -132,90 +199,159 @@ module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [{ loader: 'style-loader/url' }, { loader: 'file-loader' }],
test: /\.css$/i,
use: [
{
loader: 'style-loader',
options: { injectType: 'singletonStyleTag' },
},
'css-loader',
],
},
],
},
};
```

The loader inject styles like:

```html
<link rel="stylesheet" href="path/to/file.css" />
<style>
.foo {
color: red;
}
.bar {
color: blue;
}
</style>
```

## Options
#### `lazyStyleTag`

| Name | Type | Default | Description |
| :--------------: | :------------------: | :---------: | :------------------------------------------------------------------------------------------------------------------ |
| **`base`** | `{Number}` | `true` | Set module ID base (DLLPlugin) |
| **`attributes`** | `{Object}` | `{}` | Add custom attributes to `<style></style>` |
| **`insertAt`** | `{String\|Object}` | `bottom` | Inserts `<style></style>` at the given position |
| **`insertInto`** | `{String\|Function}` | `<head>` | Inserts `<style></style>` into the given position |
| **`singleton`** | `{Boolean}` | `undefined` | Reuses a single `<style></style>` element, instead of adding/removing individual elements for each required module. |
Injects styles in multiple `<style></style>` on demand (documentation above).

### `base`
```js
import styles from './styles.css';

This setting is primarily used as a workaround for [css clashes](https://github.com/webpack-contrib/style-loader/issues/163) when using one or more [DllPlugin](https://robertknight.github.io/posts/webpack-dll-plugins/)'s. `base` allows you to prevent either the _app_'s css (or _DllPlugin2_'s css) from overwriting _DllPlugin1_'s css by specifying a css module id base which is greater than the range used by _DllPlugin1_ e.g.:
styles.use();
```

**webpack.dll1.config.js**
**webpack.config.js**

```js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
test: /\.useable\.css$/i,
use: [
{
loader: 'style-loader',
},
{ loader: 'css-loader' },
{ loader: 'style-loader', options: { injectType: 'lazyStyleTag' } },
'css-loader',
],
},
],
},
};
```

**webpack.dll2.config.js**
The loader inject styles like:

```html
<style>
.foo {
color: red;
}
</style>
<style>
.bar {
color: blue;
}
</style>
```

#### `lazySingletonStyleTag`

Injects styles in one `<style></style>` on demand (documentation above).

```js
import styles from './styles.css';

styles.use();
```

**webpack.config.js**

```js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
test: /\.useable\.css$/i,
use: [
{ loader: 'style-loader', options: { base: 1000 } },
{ loader: 'css-loader' },
{
loader: 'style-loader',
options: { injectType: 'lazySingletonStyleTag' },
},
'css-loader',
],
},
],
},
};
```

**webpack.app.config.js**
The loader generate this:

```html
<style>
.foo {
color: red;
}
.bar {
color: blue;
}
</style>
```

#### `linkTag`

Injects styles in multiple `<link rel="stylesheet" href="path/to/file.css">` .

```js
import './styles.css';
import './other-styles.css';
```

**webpack.config.js**

```js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
test: /\.css$/i,
use: [
{ loader: 'style-loader', options: { base: 2000 } },
{ loader: 'css-loader' },
{ loader: 'style-loader', options: { injectType: 'linkTag' } },
{ loader: 'file-loader' },
],
},
],
},
};
```

The loader generate this:

```html
<link rel="stylesheet" href="path/to/style.css" />
<link rel="stylesheet" href="path/to/other-styles.css" />
```

### `attributes`

Type: `Object`
Default: `{}`

If defined, style-loader will attach given attributes with their values on `<style>` / `<link>` element.

**component.js**
Expand All @@ -231,7 +367,7 @@ module.exports = {
module: {
rules: [
{
test: /\.css$/,
test: /\.css$/i,
use: [
{ loader: 'style-loader', options: { attributes: { id: 'id' } } },
{ loader: 'css-loader' },
Expand Down Expand Up @@ -354,13 +490,49 @@ module.exports = {
};
```

### `singleton`
### `base`

If defined, the style-loader will reuse a single `<style></style>` element, instead of adding/removing individual elements for each required module.
This setting is primarily used as a workaround for [css clashes](https://github.com/webpack-contrib/style-loader/issues/163) when using one or more [DllPlugin](https://robertknight.github.io/posts/webpack-dll-plugins/)'s. `base` allows you to prevent either the _app_'s css (or _DllPlugin2_'s css) from overwriting _DllPlugin1_'s css by specifying a css module id base which is greater than the range used by _DllPlugin1_ e.g.:

> ℹ️ This option is on by default in IE9, which has strict limitations on the number of style tags allowed on a page. You can enable or disable it with the singleton option.
**webpack.dll1.config.js**

**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
use: [
{
loader: 'style-loader',
},
{ loader: 'css-loader' },
],
},
],
},
};
```

**webpack.dll2.config.js**

```js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
use: [
{ loader: 'style-loader', options: { base: 1000 } },
{ loader: 'css-loader' },
],
},
],
},
};
```

**webpack.app.config.js**

```js
module.exports = {
Expand All @@ -369,7 +541,7 @@ module.exports = {
{
test: /\.css$/i,
use: [
{ loader: 'style-loader', options: { singleton: true } },
{ loader: 'style-loader', options: { base: 2000 } },
{ loader: 'css-loader' },
],
},
Expand Down
Loading

0 comments on commit e2664e9

Please sign in to comment.