Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 93 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,37 +1,45 @@
# html-inline-css-webpack-plugin

[![MIT Licence](https://badges.frapsoft.com/os/mit/mit.svg?v=103)](https://opensource.org/licenses/mit-license.php)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/Runjuu/html-inline-css-webpack-plugin/pulls)
[![Total downloads](https://img.shields.io/npm/dm/html-inline-css-webpack-plugin.svg)](https://www.npmjs.com/package/html-inline-css-webpack-plugin)
[![npm version](https://badge.fury.io/js/html-inline-css-webpack-plugin.svg)](https://www.npmjs.com/package/html-inline-css-webpack-plugin)

Convert external stylesheet to embedded stylesheet, aka document stylesheet.

```
<link rel="stylesheet" /> => <style>...<style/>
```

Require [mini-css-extract-plugin](https://github.com/webpack-contrib/mini-css-extract-plugin) and [html-webpack-plugin](https://github.com/jantimon/html-webpack-plugin)

## Install

#### NPM

```bash
npm i html-inline-css-webpack-plugin -D
```

#### Yarn

```bash
yarn add html-inline-css-webpack-plugin -D
```

## Minimal example

```js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const HtmlWebpackPlugin = require('html-webpack-plugin');
const HTMLInlineCSSWebpackPlugin = require("html-inline-css-webpack-plugin").default;
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const HTMLInlineCSSWebpackPlugin = require('html-inline-css-webpack-plugin')
.default

module.exports = {
plugins: [
new MiniCssExtractPlugin({
filename: "[name].css",
chunkFilename: "[id].css"
filename: '[name].css',
chunkFilename: '[id].css',
}),
new HtmlWebpackPlugin(),
new HTMLInlineCSSWebpackPlugin(),
Expand All @@ -40,17 +48,15 @@ module.exports = {
rules: [
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
"css-loader"
]
}
]
}
use: [MiniCssExtractPlugin.loader, 'css-loader'],
},
],
},
}
```

## Config

```typescript
interface Config {
filter?(fileName: string): boolean
Expand All @@ -60,15 +66,20 @@ interface Config {
position?: 'before' | 'after'
removeTarget?: boolean
}
attributes?: { [name: string]: string }
}
```

### filter(optional)

```typescript
filter?(fileName: string): boolean
```

Return `true` to make current file internal, otherwise ignore current file. Include both css file and html file name.

##### example

```typescript
...
new HTMLInlineCSSWebpackPlugin({
Expand All @@ -80,31 +91,89 @@ Return `true` to make current file internal, otherwise ignore current file. Incl
```

### leaveCSSFile(optional)

if `true`, it will leave CSS files where they are when inlining

### replace(optional)

```typescript
replace?: {
target: string
position?: 'before' | 'after' // default is 'before'
removeTarget?: boolean // default is false
}
```

A config for customizing the location of injection, default will add internal style sheet before the `</head>`

### attributes(optional)

Allows the adding of attributes to the style tag

##### example 1

```typescript
...
new HTMLInlineCSSWebpackPlugin({
replace: {
attributes: {
'type': "text/css"
},
},
}),
...
```

```html
<style type="text/css">
/* inlined css */
</style>
```

##### example 2

```typescript
...
new HTMLInlineCSSWebpackPlugin({
replace: {
attributes: {
'amp-custom': ""
},
},
}),
...
```

```html
<style amp-custom="">
/* inlined css */
</style>
```

Useful for amp pages

#### target

A target for adding the internal style sheet

#### position(optional)

Add internal style sheet `before`/`after` the `target`

#### removeTarget(optional)

if `true`, it will remove the `target` from the output HTML

> Please note that HTML comment is removed by default by the `html-webpack-plugin` in production mode. [#16](https://github.com/Runjuu/html-inline-css-webpack-plugin/issues/16#issuecomment-527884514)

##### example

```html
<head>
<!-- inline_css_plugin -->
<style>
/* some hard code style */
</style>
<!-- inline_css_plugin -->
<style>
/* some hard code style */
</style>
</head>
```

Expand All @@ -118,14 +187,16 @@ if `true`, it will remove the `target` from the output HTML
}),
...
```

###### output:

```html
<head>
<style>
/* style from *.css files */
</style>
<style>
/* some hard code style */
</style>
<style>
/* style from *.css files */
</style>
<style>
/* some hard code style */
</style>
</head>
```
26 changes: 25 additions & 1 deletion src/core/base-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,27 @@ export class BasePlugin {
}
}

protected getAttributesString(config: Config): string {
if (config.attributes && typeof config.attributes === 'object') {
return (
' ' +
Object.keys(config.attributes)
.map((key) => `${key}="${config.attributes![key] || ''}"`)
.join(' ')
)
}

if (config.attributes === undefined && config.attributes === null) {
throw new Error(
`Please provide a key/value object if intending to use the attributes option, not ${
config.attributes
}`,
)
}

return ''
}

protected addStyle({
html,
htmlFileName,
Expand All @@ -75,7 +96,10 @@ export class BasePlugin {
htmlFileName: string
style: string
}) {
const styleString = `<style type="text/css">${style}</style>`
const styleString = `<style${this.getAttributesString(
this.config,
)}>${style}</style>`

const replaceValues = [styleString, this.replaceConfig.target]

if (this.replaceConfig.position === 'after') {
Expand Down
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export interface Config {
filter?(fileName: string): boolean
leaveCSSFile?: boolean
replace?: ReplaceConfig
attributes?: { [name: string]: string }
}

export interface FileCache {
Expand Down