📜  nextjs svg npm - Javascript (1)

📅  最后修改于: 2023-12-03 14:44:34.891000             🧑  作者: Mango

使用 Next.js 和 npm 来处理 SVG

Next.js 作为一个 React 框架,提供了一个灵活的、可扩展的服务器端渲染环境。即使你不在意服务器端渲染,Next.js 也提供了许多有用的功能,如预渲染、自动代码拆分和热模块替换。

SVG 是一种基于 XML 的矢量图形格式。它是一个非常通用的格式,在 Web 开发中广泛使用。我们通常使用 SVG 来绘制图标、图标集、动画和其他数据可视化。虽然 SVG 语法很简单,但处理 SVG 仍然需要一些技巧。

我们可以使用 npm 包管理工具来管理和安装我们需要使用的依赖库。这样做可以使项目的开发过程更加容易,也可以更好地管理依赖关系,并使我们的应用程序更加安全。

安装依赖项

我们可以通过 npm 来安装 react-svg 库来处理 SVG 文件并将其渲染成 React 组件。安装的方法很简单,只需要运行以下命令即可:

npm install react-svg --save

此外,我们也需要安装 @svgr/webpack,它是一个 Webpack 插件,可以将 SVG 文件转换为 React 组件。执行以下命令安装:

npm install --save-dev @svgr/webpack
使用 react-svg

我们假设你已经有了一个 SVG 文件夹,并且你有一个名为 something.svg 的 SVG 文件。我们可以通过 react-svg-loader 导入和渲染它,然后可以像任何其他 React 组件一样使用它。以下是一个示例代码:

import React from 'react';
import SVG from 'react-svg';
import something from './something.svg';

const App = () => (
  <SVG src={something} />
);

export default App;

请注意,我们没有使用传统的 import 语法,而是使用了 require,因为我们需要使用 Webpack 的 require

此外,我们还可以使用一些其他属性来自定义 SVG。例如,我们可以定义一个回调函数,在 SVG 加载完成时执行一些操作:

// ...
const onSVGReady = (error, svg) => {
  console.log(`SVG component's width: ${svg.width}`);
};

const App = () => (
  <SVG src={something} onSVGReady={onSVGReady} />
);
// ...
使用 @svgr/webpack

我们已经安装了 @svgr/webpack,接下来我们将介绍如何使用它转换 SVG 文件为 React 组件。在 React 组件中使用 SVG 有一些附加的好处:

  1. 可以轻松实现动态属性,例如修改 SVG 颜色或大小。
  2. 可以轻松实现事件处理程序,例如点击、悬停和拖动事件。

我们可以使用以下方式将 .svg 文件转换为可导入的 .jsx 文件:

// svg-to-component.js
const fs = require('fs');
const path = require('path');
const SVGO = require('svgo');
const svgr = require('@svgr/core').default;

const svgo = new SVGO();

const readFile = filename => fs.readFileSync(filename, 'utf-8');
const writeFile = (filename, data) => fs.writeFileSync(filename, data);

const options = {
  icon: true,
  jsx: true,
  native: true,
  template: (code, config, state) => {
    const { template } = config;
    const { imports } = state;

    const tpl = template.smart({ plugins: ['jsx'] });
    const jsx = tpl(
      {
        ...config,
        imports: [
          "...",
          ...imports,
        ],
      },
      api,
      state,
    );

    return jsx;
  }
};

const inputFolder = 'svgs';
const outputFolder = 'svg-components';

if (!fs.existsSync(outputFolder)) {
  fs.mkdirSync(outputFolder);
}

const files = fs.readdirSync(inputFolder);

files.forEach(file => {
  const inputPath = path.join(inputFolder, file);
  const outputPath = path.join(outputFolder, `${file}.jsx`);

  svgo.optimize(readFile(inputPath), { path: inputPath })
    .then(({ data }) => {
      const jsx = svgr(data, options, { filePath: inputPath });

      const code = jsx.replace(';', ''); // Remove the semicolon at the end of the generated code
      const formattedCode = [code.slice(0, -1), '\n);'].join(''); // Add the closing tag
      const filename = path.basename(outputPath, '.svg');
      const fullCode = `import React from 'react';\n\nexport const ${filename} = ${formattedCode}`;

      writeFile(outputPath, fullCode);
    })
});

这个脚本将遍历 svgs 目录下的所有 .svg 文件,并将它们转换为 React 组件。我们可以执行以下命令来运行脚本:

node svg-to-component.js

此时,我们将在 svg-components 文件夹中找到与每个 SVG 文件名相同的 .jsx 文件。例如,如果你有一个名为 something.svg 的文件,你将会找到一个名为 something.jsx 的文件。你可以在 React 组件中像这样导入它:

import { something } from './svg-components/something';

现在,我们已经学会了如何使用 Next.js 和 npm 处理 SVG 文件,并将它们渲染成 React 组件。这个过程虽然有点复杂,但它可以让我们更方便地管理和维护我们的应用程序。