NextJS、Storybook、SVG 和绝对导入路径

Posted

技术标签:

【中文标题】NextJS、Storybook、SVG 和绝对导入路径【英文标题】:NextJS, Storybook, SVG and absolute import paths 【发布时间】:2020-06-26 16:56:49 【问题描述】:

不能将 SVG 用作 NextJS 应用程序和 Storybook 的模块,使用绝对路径导入。通过许多尝试的设置,我可以在 Next 或 Storybook 中导入 SVG,但不能同时在两者中导入。我将此设置用于babel-plugin-inline-react-svg

// .babelrc

  ...
  "plugins": [
    ...
    "inline-react-svg"
  ]

使用这个插件 Storybook 不需要任何配置,这个示例代码可以按预期工作:

import Wrapper from '../../../components/Wrapper';
import IconSVG from '../../../icons/sandwich.svg';

export const WrappedSVG = () => (
  <Wrapper>
    <IconSVG />
  </Wrapper>
);

但以下不是:

import Wrapper from 'components/Wrapper';
import IconSVG from 'icons/sandwich.svg';

export const WrappedSVG = () => (
  <Wrapper>
    <IconSVG />
  </Wrapper>
);

正在处理包装器,但图标未处理:Cannot find module

这里是svgr 设置:

// next.config.js
module.exports = 
  webpack(config, options) 
    ...
    config.module.rules.push(
      test: /\.svg$/,
      use: ['@svgr/webpack'],
    );

    return config;
  ,
;
// .storybook/main.js
module.exports = 
  ...
  webpackFinal: async config => 
    ...
    config.module.rules.unshift(
      test: /\.svg$/,
      use: ['@svgr/webpack'],
    );

    return config;
  ,

此配置在应用程序端运行良好,但在 Storybook 中我得到 DOMException: "String contains an invalid character"

我的npm run dev 脚本是这样的:ts-node --project tsconfig.server.json src/server.ts(通过nodemon)。

我希望有人能给我一个提示,如何让 SVG 组件的绝对导入同时适用于 NextJS 和 Storybook。

【问题讨论】:

【参考方案1】:

an answer 解决了一个对我有用的不同问题。

这可能是因为与 Storybook 的默认 SVG 加载器冲突。这对我有用:

module.exports = 
  webpackFinal: async (config,  configType ) => 
    const rules = config.module.rules;
    const fileLoaderRule = rules.find(rule => rule.test.test('.svg'));
    fileLoaderRule.exclude = /\.svg$/;

    rules.push(
      test: /\.svg$/,
      use: ["@svgr/webpack"],
    );

    return config;
  
;

【讨论】:

这样的工作,但是import ts错误依然存在【参考方案2】:

关于绝对路径,Next.js 现在支持文件导入中的别名,只需在 tsconfig.json/jsconfig.json 文件中进行最少的自定义配置(无需 webpack 配置(*实验阶段))。

要配置,请看here!

【讨论】:

【参考方案3】:

可以通过配置webpack来完成。在项目根目录下创建 next.config.js 文件,它不存在,然后添加:

//next.config.js

const path = require('path');
const webpack = require('webpack');

module.exports = 
  webpack: config => 
    config.resolve.alias['~'] = path.resolve(__dirname);
    return config;
  
;

使用方法:

import myimage from '~/somepath/myimage.svg'

更多详情请查看tutorial。

查看 Weppack 文档here。

对于 next.config.js 中的多个插件配置,请查看this。

【讨论】:

以上是关于NextJS、Storybook、SVG 和绝对导入路径的主要内容,如果未能解决你的问题,请参考以下文章

无法在 NextJs + Storybook 中提供静态文件

使用 Nextjs 在 Netlify 上部署 Storybook

React Storybook SVG 无法在“文档”上执行“createElement”

有没有办法将本地 svg 文件包含到我与自定义 Angular 库一起使用的 Storybook 中?

Storybook 不会在 Vue 项目的组件中加载 SVG

在 NextJS 中导入 SVG