みかづきブログ・カスタム

基本的にはちょちょいのほいです。

Nextプロジェクトにbabel-plugin-inline-react-svgを導入したときに、Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.と表示される時の対策 ✌️

f:id:kimizuka:20210103011013j:plain

ことの発端

以前、Next.jsでSVGをコンポーネントのように扱う方法を調べました。

blog.kimizuka.org

今日もまた、いつものようにbabel-plugin-inline-react-svgを使ってSVGを読み込もうとしたのですが、

Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.

と、エラーが出ました。

調査

importしたSVGをreturnするのを一旦諦め、

import Logo from '../../images/Logo.svg';

console.log(Logo);

という形でimportしたものを確認すると、

{
  height: 80,
  src: "/_next/static/image/src/images/Logo.xxxxxxxxxxxxxxxx.svg",
  width: 80
}

という感じのオブジェクトが返ってきていることがわかりました。
これではコンポーネントのようには扱えません。

一方、表示が成功しているプロジェクトのSVGをconsole.logで表示すると、

Logo(props) {
  return /*#__PURE__*/(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxDEV)("svg", _objectSpread(_objectSpread({}, props), {}, {
    children: /*#__PURE__*/(0,react_jsx_dev_ru…

と、途中で切れてしまっていますが、関数が返ってきていることがわかります。

原因

オブジェクトが返ってくるケースと、関数が返ってくるケースで何が違うのか。
調査を進めると、

yarn create next-app --typescript

で作成するとオブジェクトが、

yarn create next-app

で作成したあと、自力でTypeScriptを導入すると関数が返ってくることがわかりました。

これが一時的なものなのか、そういう仕様なのかはわかりません。
おそらく、内部のwebpackの設定が微妙に違うんだと思われます。

対策 @svgr/webpackに乗り換える

では、

yarn create next-app --typescript

で作成したプロジェクトにbabel-plugin-inline-react-svgを導入するときはどうすれば良いのか。

いろいろ試した結果、

@svgr/webpackを使い、SVGを読み込ませればエラーなく読み込むことができました。

www.npmjs.com

導入手順としては、

❶ @svgr/webpackを導入する

yarn add -D @svgr/webpac

❷ next.config.jsを編集する

module.exports = {
  webpack(config) {
    config.module.rules.push({
      test: /\.svg$/,
      issuer: {
        and: [/\.(js|ts)x?$/]
      },
      use: ['@svgr/webpack']
    });

    return config;
  }
};

で、OKです。
@svgr/webpackを導入すれば、babel-plugin-inline-react-svgは削除してしまって大丈夫でした。