Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/peerigon/extract-loader
webpack loader to extract HTML and CSS from the bundle
https://github.com/peerigon/extract-loader
extract extract-text-webpack-plugin mini-css-extract-plugin webpack webpack-loader
Last synced: about 1 hour ago
JSON representation
webpack loader to extract HTML and CSS from the bundle
- Host: GitHub
- URL: https://github.com/peerigon/extract-loader
- Owner: peerigon
- License: unlicense
- Created: 2016-01-23T16:16:49.000Z (almost 9 years ago)
- Default Branch: master
- Last Pushed: 2022-12-02T10:34:54.000Z (about 2 years ago)
- Last Synced: 2025-01-02T05:04:55.558Z (9 days ago)
- Topics: extract, extract-text-webpack-plugin, mini-css-extract-plugin, webpack, webpack-loader
- Language: JavaScript
- Size: 760 KB
- Stars: 317
- Watchers: 14
- Forks: 74
- Open Issues: 58
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
- awesome-github-star - extract-loader
README
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 the [mini-css-extract-plugin](https://github.com/webpack-contrib/mini-css-extract-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.
Installation
------------------------------------------------------------------------```bash
$ npm install extract-loader --save-dev
```
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
module.exports = ({ mode }) => {
const pathToMainCss = require.resolve("./app/main.css");
const loaders = [{
loader: "css-loader",
options: {
sourceMap: true
}
}];if (mode === "production") {
loaders.unshift(
"file-loader",
"extract-loader"
);
} else {
loaders.unshift("style-loader");
}return {
mode,
entry: pathToMainCss,
module: {
rules: [
{
test: pathToMainCss,
loaders: loaders
},
]
}
};
};
```### [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 reference your stylesheets from there. In that case, tell the html-loader to also pick up `link:href`:
```js
module.exports = ({ mode }) => {
const pathToMainJs = require.resolve("./app/main.js");
const pathToIndexHtml = require.resolve("./app/index.html");return {
mode,
entry: [
pathToMainJs,
pathToIndexHtml
],
module: {
rules: [
{
test: pathToIndexHtml,
use: [
"file-loader",
"extract-loader",
{
loader: "html-loader",
options: {
attrs: ["img:src", "link:href"]
}
}
]
},
{
test: /\.css$/,
use: [
"file-loader",
"extract-loader",
{
loader: "css-loader",
options: {
sourceMap: true
}
}
]
},
{
test: /\.jpg$/,
use: "file-loader"
}
]
}
};
}
```turns
```html
```
into
```html
```
Source Maps
------------------------------------------------------------------------If you want source maps in your extracted CSS files, you need to set the [`sourceMap` option](https://github.com/webpack-contrib/css-loader#sourcemap) of the **css-loader**:
```js
{
loader: "css-loader",
options: {
sourceMap: true
}
}
```
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. `publicPath` may be defined as a string or a function that accepts current [loader context](https://webpack.js.org/api/loaders/#the-loader-context) as single argument.Example with publicPath option as a string:
```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",
},
],
}
]
}
};
```Example with publicPath option as a function:
```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: {
// dynamically return a relative publicPath based on how deep in directory structure the loaded file is in /src/ directory
publicPath: (context) => '../'.repeat(path.relative(path.resolve('src'), context.context).split('/').length),
}
},
{
loader: "css-loader",
},
],
}
]
}
};
```You need another option? Then you should think about:
Contributing
------------------------------------------------------------------------From opening a bug report to creating a pull request: **every contribution is appreciated and welcome**. If you're planning 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))
License
------------------------------------------------------------------------Unlicense
Sponsors
------------------------------------------------------------------------[](https://peerigon.com)