npm package: @skpm/extract-loader
Description: webpack loader to extract HTML and CSS from the bundle
Author: peerigon
Latest version: 2.0.3

extract-loader
==============
**webpack loader to extract HTML and CSS from the bundle.**

[![](https://img.shields.io/npm/v/extract-loader.svg)](https://www.npmjs.com/package/extract-loader)
[![](https://img.shields.io/npm/dm/extract-loader.svg)](https://www.npmjs.com/package/extract-loader)
[![Dependency Status](https://david-dm.org/peerigon/extract-loader.svg)](https://david-dm.org/peerigon/extract-loader)
[![Build Status](https://travis-ci.org/peerigon/extract-loader.svg?branch=master)](https://travis-ci.org/peerigon/extract-loader)
[![Coverage Status](https://img.shields.io/coveralls/peerigon/extract-loader.svg)](https://coveralls.io/r/peerigon/extract-loader?branch=master)

The extract-loader evaluates the given source code on the fly and returns the result as string. Its main use-case is to resolve urls within HTML and CSS coming from their respective loaders. Use the [file-loader](https://github.com/webpack/file-loader) to emit the extract-loader's result as separate file.

```javascript
import stylesheetUrl from "file-loader!extract-loader!css-loader!main.css";
// stylesheetUrl will now be the hashed url to the final stylesheet
```

The extract-loader works similar to the [extract-text-webpack-plugin](https://github.com/webpack/extract-text-webpack-plugin) and is meant as a lean alternative to it. When evaluating the source code, it provides a fake context which was especially designed to cope with the code generated by the [html-](https://github.com/webpack/html-loader) or the [css-loader](https://github.com/webpack/css-loader). Thus it might not work in other situations.

<br>

Installation
------------------------------------------------------------------------

`npm install extract-loader`

<br>

Examples
------------------------------------------------------------------------

### [Extracting a main.css](https://github.com/peerigon/extract-loader/tree/master/examples/main-css)

Bundling CSS with webpack has some nice advantages like referencing images and fonts with hashed urls or [hot module replacement](https://webpack.js.org/concepts/hot-module-replacement) in development. In production, on the other hand, it's not a good idea to apply your stylesheets depending on JS execution. Rendering may be delayed or even a [FOUC](https://en.wikipedia.org/wiki/Flash_of_unstyled_content) might be visible. Thus it's still better to have them as separate files in your final production build.

With the extract-loader, you are able to reference your `main.css` as regular `entry`. The following `webpack.config.js` shows how to load your styles with the [style-loader](https://github.com/webpack/style-loader) in development and as separate file in production.

```js
const live = process.env.NODE_ENV === "production";
const mainCss = ["css-loader", path.join(__dirname, "app", "main.css")];

if (live) {
    mainCss.unshift("file-loader?name=[name].[ext]", "extract-loader");
} else {
    mainCss.unshift("style-loader");
}

module.exports = {
    entry: [
        path.join(__dirname, "app", "main.js"),
        mainCss.join("!")
    ],
    ...
};
```

### [Extracting the index.html](https://github.com/peerigon/extract-loader/tree/master/examples/index-html)

You can even add your `index.html` as `entry` and just reference your stylesheets from there. You just need to tell the html-loader to also pick up `link:href`:

```js
const indexHtml = path.join(__dirname, "app", "index.html");

module.exports = {
    entry: [
        path.join(__dirname, "app", "main.js"),
        indexHtml
    ],
    ...
    module: {
        rules: [
            {
                test: indexHtml,
                use: [
                    {
                        loader: "file-loader",
                        options: {
                            name: "[name]-dist.[ext]",
                        },
                    },
                    {
                        loader: "extract-loader",
                    },
                    {
                        loader: "html-loader",
                        options: {
                            attrs: ["img:src", "link:href"],
                            interpolate: true,
                        },
                    },
                ],
            },
            {
                test: /\.css$/,
                loaders: [
                    {
                        loader: "file-loader",
                    },
                    {
                        loader: "extract-loader",
                    },
                    {
                        loader: "css-loader",
                    },
                ],
            },
            {
                test: /\.jpg$/,
                loaders: [
                    {
                        loader: "file-loader"
                    },
                ],
            },
        ]
    }
};
```

turns

```html
<html>
<head>
    <link href="main.css" type="text/css" rel="stylesheet">
</head>
<body>
    <img src="hi.jpg">
</body>
</html>
```

into


```html
<html>
<head>
    <link href="7c57758b88216530ef48069c2a4c685a.css" type="text/css" rel="stylesheet">
</head>
<body>
    <img src="6ac05174ae9b62257ff3aa8be43cf828.jpg">
</body>
</html>
```

<br>

Options
------------------------------------------------------------------------

There is currently exactly one option: `publicPath`.
If you are using a relative `publicPath` in webpack's [output options](https://webpack.js.org/configuration/output/#output-publicpath) and extracting to a file with the `file-loader`, you might need this to account for the location of your extracted file.

Example:

```js
module.exports = {
    output: {
        path: path.resolve("./dist"),
        publicPath: "dist/"
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [
                    {
                        loader: "file-loader",
                        options: {
                            name: "assets/[name].[ext]",
                        },
                    },
                    {
                        loader: "extract-loader",
                        options: {
                            publicPath: "../",
                        }
                    },
                    {
                        loader: "css-loader",
                    },
                ],
            }
        ]
    }
};
```

You need another option? Then you should think about:

<br>

Contributing
------------------------------------------------------------------------

From opening a bug report to creating a pull request: **every contribution is appreciated and welcome**. If you're planing to implement a new feature or change the api please create an issue first. This way we can ensure that your precious work is not in vain.

All pull requests should have 100% test coverage (with notable exceptions) and need to pass all tests.

- Call `npm test` to run the unit tests
- Call `npm run coverage` to check the test coverage (using [istanbul](https://github.com/gotwarlost/istanbul))

<br>

License
------------------------------------------------------------------------

Unlicense

Sponsors
------------------------------------------------------------------------

[<img src="https://assets.peerigon.com/peerigon/logo/peerigon-logo-flat-spinat.png" width="150" />](https://peerigon.com)