Demand analysis

  • The project references a large number of SVG-icon diagrams.
<img src="/xxx/yyy/zzz/icon.svg" />
Copy the code
  • Now like Element, it is introduced in a component line like this:
<Icon name="icon-file-name"></Icon>
Copy the code
  • Two Loaders are used in this process: SVG-Sprite-loader and SvGo-loader

Let’s start with Sprite

Zhang Xinxu’s blog

1. symbol

  • SVG Sprite best practice is to use the Symbol element
  • The code structure for an SVG element with a collection of three SVG ICONS would look like this:
<svg> <symbol> <! </symbol> <symbol> <! </symbol> <symbol> <! </symbol> </ SVG >Copy the code
  • Each symbol is an iconic symbol

2. use

  • Just put the icon, if you do not use, it is invisible
  • Such use
<use xlink:href="#symbolId"></use>
Copy the code

svg-sprite-loader

A tool to generate Sprite graphics, it is a Webpack loader, can package multiple SVG into SVG-Sprite.

The principle of

  • Svg-sprite-loader will stuff your icon into each symbol,
  • The SYMBOL ID is your filename unless specified.
  • It will eventually embed a large SVG in your HTML,
<body> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="__SVG_SPRITE_NODE__"> The < symbol XMLNS = "http://www.w3.org/2000/svg" class = "icon" viewBox = "0 0 1024 1024" id = "XXX" > / / id is the icon of the <! - this is the path -- -- > < / symbol > < symbol XMLNS = "http://www.w3.org/2000/svg" class = "icon" viewBox = "0 0 1024 1024" id = "XXX" > / / id Is the icon name <! Path --> </symbol> </ SVG > </body>Copy the code
  • And then you can go up hereuseUsed as well
< SVG > <use xlink:href="# XXX "/>Copy the code
  • To sum up:symbol + use= >SVG Sprite

Use and Configuration

  1. The installation
yarn add --dev svg-sprite-loader
Copy the code
  1. Configuration webpack
{
  test: /\.svg$/,
  loader: 'svg-sprite-loader',
}
Copy the code
  1. use

Icon in the component

<svg>
  <use xlink:href="#svgName"/> 
</svg>
Copy the code

svgo-loader

introduce

SVG files, especially exported from various editors, usually contain a lot of redundant and useless information such as editor metadata, comments, hidden elements, default or non-optimal values and other stuff that can be safely removed or converted without affecting SVG rendering result.

  • Refer to zhang Xinxu’s blog
  • github
  • Now to change the style and color of the SVG-icon element, you can use svGo-Loader
  • SVGO is an SVG optimizer that includes many plug-ins.
  • It can delete and modify SVG elements, collapse content, move attributes, and much more.

The principle of

  • SVGO transforms SVG-AS-XML data into an SVG-AS-JS AST representation.

  • It then runs and performs some operations on all AST data items, and finally SVGO converts the AST back to the SVG-AS-XML data string.

Use and Configuration

  1. The installation
yarn add --dev svgo-loader
Copy the code
  1. In the webpack configuration
 {
      test: /\.svg$/,
      use: [
        {loader: 'svg-sprite-loader', options: {}},
        {
          loader: 'svgo-loader', options: {
            // plugins: [
            //   {removeAttrs: {attrs: 'fill'}}
            // ]
          }
        }
      ]
},
Copy the code
  • Note: First svgo-loader, then SVG-sprite-loader. First process the SVG image and then generate Sprite
  1. Changing the color is done with the Fill property

Based on the above, encapsulate the Icon component

import React from "react";
 require('icons/money.svg')
 require('icons/tag.svg')
 require('icons/chart.svg')

type Props = {
    name:string
}
const Icon =(props:Props) = >{
    return (
        <svg fill='red' className="icon">
            <use xlinkHref={The '#' +props.name} ></use>
        </svg>)};export default Icon
Copy the code

1. Why use require to introduce icon?

  • Avoid tree – shaking
  • If you use import, it will cause tree-shaking and not use it

2. If I introduce many ICONS, do I have to write them one by one? Can you import folders all at once?

  • can
  • code
//require a directory/folder
let importAll = (requireContext: __WebpackModuleApi.RequireContext) = >
    requireContext.keys().forEach(requireContext);
try {
    importAll(require.context('icons'.true./\.svg$/));
} 
catch (error) 
    {console.log(error);
        
    }
Copy the code
  • Reference: require.context for webpack
  • The require. The context:
    • Webpack provides an API for creating your own Context Module and dynamically importing ICONS
    • Three parameters are supported:
      • The folder directory to search for
      • Should I also search its subdirectories,
      • And a regular expression that matches the file.
    • So this is: search the ICONS folder for all SVG files containing their subdirectories
  • A context Module exports a (require) function that takes a single argument: request.
    • This export function has three attributes: resolve, keys, and ID.
    • Resolve is a function that returns the module ID of the resolved request.
    • Keys is also a function that returns an array of all the requests that could be handled by this Context Module.
  • This can be helpful if you want to import all files under a folder, or all files that match a regular expression, for example:
function importAll(r) { r.keys().forEach(r); } importAll(require.context('.. /components/', true, /\.js$/));Copy the code
  • In general, require. Context helps us create a context.

    • In this case our context is./ SRC /assets/ ICONS.

    • We can then import files in that context via require.resolve.

3. How to package the vUE version