Giter Club home page Giter Club logo

extract-loader's Introduction

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

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
                },
            ]
        }
    };
};

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

extract-loader's People

Contributors

jhnns avatar benurb avatar jannikkeye avatar semantic-release-bot avatar jpommerening avatar gpoitch avatar heptahedron avatar bogas04 avatar ipsips avatar meaku avatar munter avatar goto-bus-stop avatar siakaramalegos avatar sime avatar alqh avatar fabianonunes avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.