{"id":13671345,"url":"https://github.com/peerigon/extract-loader","last_synced_at":"2025-04-08T02:41:59.312Z","repository":{"id":3604874,"uuid":"50246328","full_name":"peerigon/extract-loader","owner":"peerigon","description":"webpack loader to extract HTML and CSS from the bundle","archived":false,"fork":false,"pushed_at":"2022-12-02T10:34:54.000Z","size":778,"stargazers_count":319,"open_issues_count":58,"forks_count":75,"subscribers_count":13,"default_branch":"master","last_synced_at":"2025-03-29T10:35:24.962Z","etag":null,"topics":["extract","extract-text-webpack-plugin","mini-css-extract-plugin","webpack","webpack-loader"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/peerigon.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-01-23T16:16:49.000Z","updated_at":"2025-02-21T12:27:58.000Z","dependencies_parsed_at":"2023-01-13T12:38:41.981Z","dependency_job_id":null,"html_url":"https://github.com/peerigon/extract-loader","commit_stats":null,"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peerigon%2Fextract-loader","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peerigon%2Fextract-loader/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peerigon%2Fextract-loader/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peerigon%2Fextract-loader/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/peerigon","download_url":"https://codeload.github.com/peerigon/extract-loader/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247767232,"owners_count":20992538,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["extract","extract-text-webpack-plugin","mini-css-extract-plugin","webpack","webpack-loader"],"created_at":"2024-08-02T09:01:06.840Z","updated_at":"2025-04-08T02:41:59.290Z","avatar_url":"https://github.com/peerigon.png","language":"JavaScript","readme":"extract-loader\n==============\n**webpack loader to extract HTML and CSS from the bundle.**\n\n[![](https://img.shields.io/npm/v/extract-loader.svg)](https://www.npmjs.com/package/extract-loader)\n[![](https://img.shields.io/npm/dm/extract-loader.svg)](https://www.npmjs.com/package/extract-loader)\n[![Dependency Status](https://david-dm.org/peerigon/extract-loader.svg)](https://david-dm.org/peerigon/extract-loader)\n[![Build Status](https://travis-ci.org/peerigon/extract-loader.svg?branch=master)](https://travis-ci.org/peerigon/extract-loader)\n[![Coverage Status](https://img.shields.io/coveralls/peerigon/extract-loader.svg)](https://coveralls.io/r/peerigon/extract-loader?branch=master)\n\nThe 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.\n\n```javascript\nimport stylesheetUrl from \"file-loader!extract-loader!css-loader!main.css\";\n// stylesheetUrl will now be the hashed url to the final stylesheet\n```\n\nThe 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.\n\n\u003cbr\u003e\n\nInstallation\n------------------------------------------------------------------------\n\n```bash\n$ npm install extract-loader --save-dev\n```\n\n\u003cbr\u003e\n\nExamples\n------------------------------------------------------------------------\n\n### [Extracting a main.css](https://github.com/peerigon/extract-loader/tree/master/examples/main-css)\n\nBundling 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.\n\nWith 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.\n\n```js\nmodule.exports = ({ mode }) =\u003e {\n    const pathToMainCss = require.resolve(\"./app/main.css\");\n    const loaders = [{\n        loader: \"css-loader\",\n        options: {\n            sourceMap: true\n        }\n    }];\n\n    if (mode === \"production\") {\n        loaders.unshift(\n            \"file-loader\",\n            \"extract-loader\"\n        );\n    } else {\n        loaders.unshift(\"style-loader\");\n    }\n\n    return {\n        mode,\n        entry: pathToMainCss,\n        module: {\n            rules: [\n                {\n                    test: pathToMainCss,\n                    loaders: loaders\n                },\n            ]\n        }\n    };\n};\n```\n\n### [Extracting the index.html](https://github.com/peerigon/extract-loader/tree/master/examples/index-html)\n\nYou 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`:\n\n```js\nmodule.exports = ({ mode }) =\u003e {\n    const pathToMainJs = require.resolve(\"./app/main.js\");\n    const pathToIndexHtml = require.resolve(\"./app/index.html\");\n\n    return {\n        mode,\n        entry: [\n            pathToMainJs,\n            pathToIndexHtml\n        ],\n        module: {\n            rules: [\n                {\n                    test: pathToIndexHtml,\n                    use: [\n                        \"file-loader\",\n                        \"extract-loader\",\n                        {\n                            loader: \"html-loader\",\n                            options: {\n                                attrs: [\"img:src\", \"link:href\"]\n                            }\n                        }\n                    ]\n                },\n                {\n                    test: /\\.css$/,\n                    use: [\n                        \"file-loader\",\n                        \"extract-loader\",\n                        {\n                            loader: \"css-loader\",\n                            options: {\n                                sourceMap: true\n                            }\n                        }\n                    ]\n                },\n                {\n                    test: /\\.jpg$/,\n                    use: \"file-loader\"\n                }\n            ]\n        }\n    };\n}\n```\n\nturns\n\n```html\n\u003chtml\u003e\n\u003chead\u003e\n    \u003clink href=\"main.css\" type=\"text/css\" rel=\"stylesheet\"\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n    \u003cimg src=\"hi.jpg\"\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\ninto\n\n\n```html\n\u003chtml\u003e\n\u003chead\u003e\n    \u003clink href=\"7c57758b88216530ef48069c2a4c685a.css\" type=\"text/css\" rel=\"stylesheet\"\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n    \u003cimg src=\"6ac05174ae9b62257ff3aa8be43cf828.jpg\"\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\n\u003cbr\u003e\n\nSource Maps\n------------------------------------------------------------------------\n\nIf 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**:\n\n```js\n    {\n        loader: \"css-loader\",\n        options: {\n            sourceMap: true\n        }\n    }\n```\n\n\u003cbr\u003e\n\nOptions\n------------------------------------------------------------------------\n\nThere is currently exactly one option: `publicPath`.\nIf 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.\n\nExample with publicPath option as a string:\n\n```js\nmodule.exports = {\n    output: {\n        path: path.resolve(\"./dist\"),\n        publicPath: \"dist/\"\n    },\n    module: {\n        rules: [\n            {\n                test: /\\.css$/,\n                use: [\n                    {\n                        loader: \"file-loader\",\n                        options: {\n                            name: \"assets/[name].[ext]\",\n                        },\n                    },\n                    {\n                        loader: \"extract-loader\",\n                        options: {\n                            publicPath: \"../\",\n                        }\n                    },\n                    {\n                        loader: \"css-loader\",\n                    },\n                ],\n            }\n        ]\n    }\n};\n```\n\nExample with publicPath option as a function:\n\n```js\nmodule.exports = {\n    output: {\n        path: path.resolve(\"./dist\"),\n        publicPath: \"dist/\"\n    },\n    module: {\n        rules: [\n            {\n                test: /\\.css$/,\n                use: [\n                    {\n                        loader: \"file-loader\",\n                        options: {\n                            name: \"assets/[name].[ext]\",\n                        },\n                    },\n                    {\n                        loader: \"extract-loader\",\n                        options: {\n                            // dynamically return a relative publicPath based on how deep in directory structure the loaded file is in /src/ directory\n                            publicPath: (context) =\u003e '../'.repeat(path.relative(path.resolve('src'), context.context).split('/').length),\n                        }\n                    },\n                    {\n                        loader: \"css-loader\",\n                    },\n                ],\n            }\n        ]\n    }\n};\n```\n\nYou need another option? Then you should think about:\n\n\u003cbr\u003e\n\nContributing\n------------------------------------------------------------------------\n\nFrom 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.\n\nAll pull requests should have 100% test coverage (with notable exceptions) and need to pass all tests.\n\n- Call `npm test` to run the unit tests\n- Call `npm run coverage` to check the test coverage (using [istanbul](https://github.com/gotwarlost/istanbul))\n\n\u003cbr\u003e\n\nLicense\n------------------------------------------------------------------------\n\nUnlicense\n\nSponsors\n------------------------------------------------------------------------\n\n[\u003cimg src=\"https://assets.peerigon.com/peerigon/logo/peerigon-logo-flat-spinat.png\" width=\"150\" /\u003e](https://peerigon.com)\n","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpeerigon%2Fextract-loader","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpeerigon%2Fextract-loader","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpeerigon%2Fextract-loader/lists"}