• Stars
    star
    317
  • Rank 132,216 (Top 3 %)
  • Language
    JavaScript
  • License
    The Unlicense
  • Created almost 9 years ago
  • Updated almost 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

webpack loader to extract HTML and CSS from the bundle

extract-loader

webpack loader to extract HTML and CSS from the bundle.

Dependency Status Build Status Coverage Status

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 to emit the extract-loader's result as separate file.

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 and the 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- or the css-loader. Thus it might not work in other situations.


Installation

$ npm install extract-loader --save-dev

Examples

Extracting a main.css

Bundling CSS with webpack has some nice advantages like referencing images and fonts with hashed urls or 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 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 in development and as separate file in production.

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

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:

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>
<head>
    <link href="main.css" type="text/css" rel="stylesheet">
</head>
<body>
    <img src="hi.jpg">
</body>
</html>

into

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

Source Maps

If you want source maps in your extracted CSS files, you need to set the sourceMap option of the css-loader:

    {
        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 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 as single argument.

Example with publicPath option as a string:

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:

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)

License

Unlicense

Sponsors

More Repositories

1

updtr

Update outdated npm modules with zero painโ„ข
JavaScript
2,224
star
2

phridge

A bridge between node and PhantomJS
JavaScript
519
star
3

parse-domain

Splits a hostname into subdomains, domain and (effective) top-level domains.
TypeScript
505
star
4

markdown-loader

markdown loader for webpack
JavaScript
376
star
5

modernizr-loader

Get your modernizr build bundled with webpack
JavaScript
163
star
6

scriptlint

an enforceable script naming standard for package.json
TypeScript
132
star
7

angular-expressions

Angular expressions as standalone module
JavaScript
94
star
8

unzip-crx

Unzip chrome extension files
JavaScript
52
star
9

nof5

A tool which runs unit tests (based on mocha) if a file has changed on the server in a browser
JavaScript
52
star
10

inspect-loader

Webpack loader designed for loader testing and debugging. Calls a function with the received input.
JavaScript
50
star
11

wasm-image

an image manipulation wrapper, JS API for Rust `image`
JavaScript
41
star
12

unicons

Cross-platform unicode icon toolkit
JavaScript
37
star
13

xunit-file

Basically the same reporter as mocha's xunit reporter, but writes the output in a file.
JavaScript
37
star
14

talks

Everything @peerigon talks about...
JavaScript
35
star
15

scrapegoat

Fetches calendar/event objects from a CalDav server
JavaScript
31
star
16

alamid

Framework for RESTful JavaScript web applications that run both on the server- and clientside.
JavaScript
23
star
17

clockodo

Unofficial JavaScript/TypeScript SDK for Clockodo
TypeScript
20
star
18

erroz

Streamlined errors with descriptive error messages through metadata and error codes
TypeScript
18
star
19

socket.io-session-middleware

share connect/express sessions with socket.io
JavaScript
18
star
20

JavaScript.js

Compiles JavaScript to JavaScript - and that's itโ„ข
JavaScript
15
star
21

link-package

No more require("./../../../../../../../../some/other/file.js")
JavaScript
15
star
22

alamid-schema

Extendable mongoose-like schemas for node.js and the browser
JavaScript
14
star
23

dynamic-config

Loads configuration files depending on the given env
JavaScript
14
star
24

legacy-loader

Webpack loader that prevents scripts from extending the window object.
JavaScript
12
star
25

eslint-config-peerigon

Peerigon coding rules as eslint config
JavaScript
11
star
26

webpack-universal-dev-server

JavaScript
10
star
27

sevdesk

๐Ÿ’ต Unofficial JavaScript SDK for sevdesk.com
TypeScript
9
star
28

piwik-wrap

A Promise-based wrapper for the Piwik JavaScript Tracking Client providing an enjoyable API
JavaScript
8
star
29

servus.js

Servus as a Service (SaaS)
JavaScript
8
star
30

v8-docs

V8 API Reference Guide generated from the header files
7
star
31

batch-replace

Perform multiple str.replace() with one operation.
JavaScript
7
star
32

value

Convenient high-performance type-checking for JavaScript
JavaScript
6
star
33

github-ssh-keys

Fetch SSH keys from GitHub for given usernames. Optionally save them to `authorized_keys`.
JavaScript
6
star
34

slogan.js

Slogan as a service (SaaS)
JavaScript
6
star
35

svg-spinners

Scalabe loading indicators
JavaScript
6
star
36

alium

Save CLI commands as aliases on a directory basis
TypeScript
5
star
37

mattermost-theme

4
star
38

alamid-class

Easy prototype inheritance.
JavaScript
3
star
39

uberschrift

Magic heading levels for React
TypeScript
3
star
40

alamid-api

Abstracting http/websocket requests
JavaScript
3
star
41

nodeclass

Smart classes for node.js
JavaScript
3
star
42

webpack-demo

This is a small example repo that can be used to demonstrate some webpack features in a "live coding" fashion.
JavaScript
3
star
43

fshelpers

Some helpers for more convenient file system operations in nodeJS.
JavaScript
2
star
44

peerigon-tito-api

_Very simple_ layer to the ti.to api.
JavaScript
2
star
45

metaclass

Provides some basic classes to describe the structure of a software project.
JavaScript
2
star
46

alamid-plugin

Monkey-patch everythingโ„ข
JavaScript
2
star
47

bananabomb

Provides some REST-API-clients for Twitter, Facebook, etc. in node.js
JavaScript
2
star
48

node2browser

DEPRECATED: Use webpack :)
JavaScript
2
star
49

alamid-api-client

Abstracts transports to a remote API
JavaScript
2
star
50

create-package

A template for a TypeScript package
TypeScript
1
star
51

svstat

a node.js wrapper for daemontools svstat
JavaScript
1
star
52

npm-stats

stats of our npm modules
JavaScript
1
star
53

alamid-sorted-array

Turns an array into a sorted array
JavaScript
1
star
54

react-and-caviar

hackathon!
JavaScript
1
star
55

hsa

1
star
56

turbo-pnpm-prune-git-dependency-issue

Dockerfile
1
star
57

email-i18n

DEPRECATED: E-mail precompiler with support for i18n and optimization via premailer
JavaScript
1
star
58

sharelock

Awesome encryption for social networks
JavaScript
1
star
59

alamid-view

Encapsulates dom nodes as a re-usable component
JavaScript
1
star
60

meetup-bridge

Bridging the meetup API to show events on our webpage - https://peerigon.com
JavaScript
1
star
61

telemetrydeck-vue

A library for using TelemetryDeck in your Vue 3 app
TypeScript
1
star