Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Embed svg inline when using the html webpack plugin

License

NotificationsYou must be signed in to change notification settings

theGC/html-webpack-inline-svg-plugin

Repository files navigation

npm versionBuild status

Converts SVG files referenced by<img> elements into inlined<svg> elements within the output HTML of templates used byhtml-webpack-plugin.

html-webpack-inline-svg-plugin does not support yet webpack v5.

Table of Contents

  1. Overview
  2. Installation
  3. Usage
    1. Paths to SVG files
      1. Relative to OUTPUT
      2. Relative to ROOT
      3. Relative to SOURCE
    2. Incorrect paths or URLs
    3. Duplicated attributes
    4. webpack-dev-server
  4. Configuration
    1. runPreEmit
    2. inlineAll
    3. allowFromUrl
    4. svgoConfig
  5. Versions
  6. Contributors

Overview

When SVGs files are inlined into HTML the embedded SVGs can be customised with CSS and thefill rule, and they can also be combined in sprites. Check the css-tricks.com articleIcon System with SVG Sprites for an extended explanation.

html-webpack-inline-svg-plugin implements the below features:

  • Optimises and minimizes the inlined SVG withSVGO.
  • Supportswebpack aliases for file paths (only when loaders are used).
  • Supports thewebpack-dev-server.
  • Can load image files locally andfrom an online URL with theallowFromUrl config option.
  • Allows fordeep nested SVGs.
  • Ignores broken tags (in case you are outputting templates for various parts of the page).
  • Performs no-HTML decoding (supports language tags, i.e.<?php echo 'foo bar'; ?>).

Installation

Add and install thehtml-webpack-inline-svg-plugin dependency topackage.json. At this point you should already have installed in your project other required dependencies likewebpack andhtml-webpack-plugin:

npm i -D html-webpack-inline-svg-plugin

or withYarn:

yarn add -D html-webpack-inline-svg-plugin

Usage

Given the below reference folder structure:

my-project├─ package.json├─ webpack.config.js├─ node_modules├─ src│  ├─ entry.html│  └─ imagesSource│     ├─ icon1.svg│     └─ image1.png├─ assets│  └─ bar.svg└─ output   ├─ index.html   └─ imagesOutput      ├─ icon2.svg      └─ image2.png

On your webpack config file add:

// webpack.config.jsconstHtmlWebpackInlineSVGPlugin=require('html-webpack-inline-svg-plugin');// ...plugins:[newHtmlWebpackPlugin(),newHtmlWebpackInlineSVGPlugin({/* ... */}// ...Object with config options, if any. Pass nothing otherwise (not even empty object))]

Then, add<img> elements with theinline attribute to the templates that html-webpack-plugin will be processing. CheckPaths to SVG files to know what is the correct path to SVG files in<img> elements.

<!-- ✅ Inlined: SVG file relative to OUTPUT --><imginlinesrc="imagesOutput/icon2.svg"><!-- ✅ Inlined: SVG file relative to SOURCE. webpack alias used. Loaders are required --><imginlinesrc="~a/bar.svg"><!-- ✅ Inlined: online URL. 'allowFromUrl' config option must be set to true --><imginlinesrc="https://someserver.com/images/icon.svg"><!-- ⭕ Ignored: the <img> element does not have the 'inline' attribute --><imgsrc="imagesOutput/icon2.svg"><!-- ✅ Inlined: the 'inlineAll' config option has been set to true --><imgsrc="imagesOutput/icon2.svg"><!-- ⭕ Ignored: it is not a SVG image --><imginlinesrc="imagesOutput/image2.png">

Paths to SVG files

There are three ways of referencing SVG files from<img> elements in your templates:

Relative to OUTPUT

Ifloaders for the entry template are not used SVG file paths must be relative to the HTML template that is referencing the SVG files within the webpackoutput folder:

<!-- src/entry.html --><imginlinesrc="imagesOutput/icon2.svg"><imginlinesrc="../src/imagesSource/icon1.svg"><imginlinesrc="../assets/bar.svg"><imginlinesrc="~a/bar.svg"><!-- Will give an error because aliases are not supported without loaders -->

You have to make sure SVG files have been moved to the output directory by some mean.

In this way SVG files are inlined after all template and image files have been written to theoutput directory, that is it, on html-webpack-plugin'safterEmit event.

Relative to ROOT

Ifloaders for the entry template are still not used, therunPreEmit config option can be used. Then, SVG file paths must be relative to theproject root (wherepackage.json is):

<!-- src/entry.html --><imginlinesrc="src/imagesSource/icon1.svg"><imginlinesrc="output/imagesOutput/icon2.svg"><imginlinesrc="assets/bar.svg"><imginlinesrc="~a/bar.svg"><!-- Will give an error because aliases are not supported without loaders -->

In this way the plugin run prior to the output of templates, that is it, on html-webpack-plugin'sbeforeEmit event. This allows to reference image files from the project root which can help with getting to certain files, like for example within thenode_modules directory.

Relative to SOURCE

Ifloaders are used SVG file paths in<img> elements must be relative to thesource entry template (thetemplate config option in html-webpack-plugin).

The usual loader's combo is thehtml-loader with thefile-loader (html-webpack-inline-svg-plugin does not support yet webpack v5asset modules). By default html-webpack-plugin uses anejs loader if no loader is provided for the entry template. This default loader does not handle file imports. That is why we need thehtml-loader to parse the entry HTML template, loader that will fire an import event every time it parses a JavaScript, CSS or image import. Then, thefile-loader will handle SVG image imports,webpack aliases, and finally copy the SVG files to theoutput folder.

Although SVG file paths are relative to the source template the files still need to be copied/emitted to the output folder (which will be done automatically by thefile-loader):

// webpack.config.jsconstpath=require('path')resolve:{alias:{a:path.join(__dirname,'assets')// With paths relative to SOURCE aliases can be used}},module:{rules:[{test:/\.svg$/,loader:'file-loader',options:{name:'itCanBeWhatever/[name].[ext]'// It does not have to follow same path or file name than files in 'src'},},{test:/\.html$/,loader:'html-loader'}]},
<!-- src/entry.html --><imginlinesrc="imagesSource/icon1.svg"><imginlinesrc="../output/imagesOutput/icon2.svg"><imginlinesrc="../assets/bar.svg"><imginlinesrc="~a/bar.svg">

Incorrect paths or URLs

If for any reason the path to a local SVG file is incorrect, or the file fails to be read, or an image retrieved with an URL fails to download, the webpack build process will fail with anENOENT error.

Duplicated attributes

All the attributes of a<img/> element exceptingsrc andinline will be copied to the inlined<svg/> element. Attributes likeid orclass will be copied to the resulting root of the<svg/> element and if the original SVG file already had these attributes they will be duplicated (and not replaced) on the resulting<svg/> element, though the attributes coming from the<img/> will appear first andany subsequent duplicated attribute from the original SVG will be ignored by the browser.

For example:

<!-- src/entry.html --><imginlinesrc="imagesSource/icon1.svg"id="myImageIMG"class="square">
<!-- src/imagesSource/icon1.svg --><svgid="myImageSVG">...</svg>

will result in:

<!-- output/index.html --><svgid="myImageIMG"class="square"id="myImageSVG">...</svg>

The broswer will useid="myImageIMG" and notid="myImageSVG". It's however a better approach if you avoid having any duplicated attribute at all and only putting the required ones on the<img> element.

webpack-dev-server

Paths relative to SOURCE is the simpler method forwebpack-dev-server to work withhtml-webpack-inline-svg-plugin because source files, files that are not in the output folder, are the ones referenced. Still, thefile-loader'semitFile option cannot ever befalse.

Paths relative to OUTPUT orPaths relative to ROOT can also be used forwebpack-dev-server as long as they point to SVG files that already exist without the need of a webpack run, that is it, files that are outside the output folder. However using long relative paths to point to such files –since aliases are only available with paths relative to SOURCE– could be a bit tedious.

Checkthis issue in case you do not get thewebpack-dev-server working.

Configuration

The plugin accepts the below options:

runPreEmit

Defaults tofalse.

Ifloaders are not used to resolve file locations, and you would prefer to reference SVG file paths relative to the projectroot (wherepackage.json is) then setrunPreEmit config option totrue:

plugins:[newHtmlWebpackPlugin(),newHtmlWebpackInlineSVGPlugin({runPreEmit:true,})]

The plugin will now run prior to html-webpack-plugin saving templates to the output directory. Therefore, inlining SVG files would look like:

<!-- src/entry.html --><imginlinesrc="src/imagesSource/icon1.svg">

inlineAll

Defaults tofalse.

It will inline all SVG images on the template without the need of theinline attribute on every image:

plugins:[newHtmlWebpackPlugin(),newHtmlWebpackInlineSVGPlugin({inlineAll:true})]

IfinlineAll option is enabled you can use theinline-exclude attribute to exclude a particular image from being inlined:

<!-- src/entry.html --><div><imgsrc="src/images/icon1.svg"><!-- it will be inlined --><imginline-excludesrc="src/images/icon2.svg"><!-- it won't be inlined --></div>

allowFromUrl

Defaults tofalse.

It allows to use SVG images coming from an URL in addition to local files:

plugins:[newHtmlWebpackPlugin(),newHtmlWebpackInlineSVGPlugin({allowFromUrl:true})]

For example:

<!-- src/entry.html --><div><imginlinesrc="https://badge.fury.io/js/html-webpack-inline-svg-plugin.svg"><!-- it will be inlined from the online SVG --></div>

svgoConfig

Defaults to[].

SVGO is used to optimise the SVGs inlined. You can configure SVGO by setting thissvgoConfig array with theSVGO plugins you need in the same way it's done in thisSVGO official Node.js example.

NotesvgoConfig is an array ofObjects that will be assigned to the.plugins SVGO config variable byhtml-webpack-inline-svg-plugin. You don't need to pass anObject with aplugins property assigned an array of SVGO plugins, just pass the array:

plugins:[newHtmlWebpackPlugin(),newHtmlWebpackInlineSVGPlugin({svgoConfig:[{removeViewBox:false},{inlineStyles:{onlyMatchedOnce:false}}]})]

html-webpack-inline-svg-plugin modifies one SVGO default:cleanupIDs, fromtrue tofalse, since IDs allow to reference individual symbols. You can still override this or any other SVGO plugin default configuration with thissvgoConfig option.

Versions

The latest version of this package supports webpack 4. All versions marked v2.x.x will target webpack 4 and html-webpack-plugin v4.

For webpack 3 and html-webpack-plugin v3 support use v1.3.0 of this package.

v2.x.x

  • Support webpack v4.
  • Support html-webpack-plugin v4.

v1.3.0

  • Support webpack v3.
  • Support html-webpack-plugin v3.

Contributors

You're free to contribute to this project by submitting issues and/or pull requests. This project is test-driven, so keep in mind that every change and new feature must be covered by tests.

I'm happy for someone to take over the project as I don't find myself using it any longer due to changes in workflow. Therefore others are likely to be in a better position to support this project and roll out the right enhancements.

About

Embed svg inline when using the html webpack plugin

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors3

  •  
  •  
  •  

[8]ページ先頭

©2009-2025 Movatter.jp