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



不能使用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。

这里有一个对我有用的不同问题的答案。

这可能是因为与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;
}
};

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

要进行配置,请查看此处!

可以通过配置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'

更多细节在这个不错的教程。

请在此处查看Weppack文档。

对于next.config.js上的多插件配置,请检查此项。

这就是我所做的,使它能够在类似的设置中工作。

您想要像这样将babel插件模块解析器安装并添加到.babelrc中,其中root是您想要启动的绝对路径的根。

{
"presets": [
"next/babel"
],
"plugins": [
["module-resolver", {
"root": ["."]
}],
...
]
}

问题是Babel在Webpack之前运行,所以即使你设置了规则,它也不会起作用,因为svg是由Babel处理的。

然后我安装了这个tsconfig-paths-webpack插件,它从tsconfig.json引入了baseUrlpaths

module.exports = {
webpack: config => {
config.resolve.plugins = [new TsconfigPathsPlugin()]

return config;
}
};

现在你应该能够导入svg如下:

// components/myComponent/myDeepComponent.tsx
import Icon from "assets/icons/icon.svg"

诀窍是你必须明白,Babel早在Webpack之前就已经运行了。你可以在这个github线程中阅读更多内容,这让我意识到了这个问题。

最新更新