webpack loader to extract HTML and CSS from the bundle.
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.
importstylesheetUrlfrom"file-loader!extract-loader!css-loader!main.css";// stylesheetUrl will now be the hashed url to the final stylesheetThe 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.
$ npm install extract-loader --save-devBundling 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 })=>{constpathToMainCss=require.resolve("./app/main.css");constloaders=[{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 })=>{constpathToMainJs=require.resolve("./app/main.js");constpathToIndexHtml=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><linkhref="main.css" type="text/css" rel="stylesheet"></head><body><imgsrc="hi.jpg"></body></html>into
<html><head><linkhref="7c57758b88216530ef48069c2a4c685a.css" type="text/css" rel="stylesheet"></head><body><imgsrc="6ac05174ae9b62257ff3aa8be43cf828.jpg"></body></html>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}}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/ directorypublicPath: (context)=>'../'.repeat(path.relative(path.resolve('src'),context.context).split('/').length),}},{loader: "css-loader",},],}]}};You need another option? Then you should think about:
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 testto run the unit tests - Call
npm run coverageto check the test coverage (using istanbul)
Unlicense
