create-react-app した React アプリでは何もしなくても SVG ファイルを import { ReactComponent as MySVGImage } from './svg/my-image.svg';
で読み込みコンポーネントとして扱うことができました。
Next.js でも同じことができると思ったのですが、create-next-app しただけの状態では SVG ファイルをそのまま import することができませんでした。(エラーになる)
create-next-app した Next アプリで SVG ファイルを React component として import できるようにする!
1. babel-plugin-inline-react-svg を導入する
$ npm -i D babel-plugin-inline-react-svg
1-2. .babelrc にプラグインの設定をする
root に .babelrc
ファイルを作成して inlne-react-svg
を使えるようにする
.babelrc
{ "presets": ["next/babel"], "plugins": ["inline-react-svg"] }
これで import MySVGImage from './svg/my-image.svg';
のように SVG ファイルを React Component として読み込めるようになりました! (Named import ではないですが)
2. SVG の import にも path.alias が使いたい!
コンポーネントから SVG を読み込ませる時に ../../../../svg/my.svg
のようにインポートするのはちょい辛いです。
Next で path.alias を使う
tsconfig.json
に下記設定を加えると @/
で ./src/
フォルダに、 ~/public/
で public
フォルダに直接アクセス可能となります。
{ "baseUrl": "src", "paths": { "@/*": ["./*"], "~/public/*": ["../*"] }, }
上記のNext.js 側で path.alias を指定していたので SVG でもそのまま @/svg/my.svg
のように import できるものだと思っていたのですが、パスが解決できずエラーになってしまいました。
2-1. SVG ファイルにパスエイリアスを適応するには別途 babel-plugin-module-resolver で設定が必要
SVG は babel を通じて import できるようになっているので、パスの解決も babel での設定が必要なようです
$ npm i -D babel-plugin-module-resolver
2-2. .babelrc にエイリアスの設定を追加する
.babelrc
{ "presets": ["next/babel"], "plugins": [ "inline-react-svg", + [ + "module-resolver", + { + "alias": { + "@": "./src/" + } + } + ] ] }
"module-resolver" の設定で baseUrl
も指定可能だったのですが、baseUrl: "./src"
とすると tsconfig での設定とバッティングしてしまうようで SVG 以外の エイリアスを使ったインポートの箇所でエラーが出てしまいました。
上記の例のように baseUrl
指定なしで、alias
に直接 .babelrc
のある階層からのパスを指定してあげればバッティングすることなく同じパスエイリアスが使えるようになりました!
所感
Next.js でも create-react-app と同じ様に使えるんだと思っていたら別途設定が必要だったのですが、公式に例が合ったおかげでサクッと実現することができました。(named import
にする方法は調べなかった) パスエイリアスの方は少しハマってしまいましたが、一度設定の作り方解ってしまえば次に活かせるのでヨシ!(๑•̀ㅂ•́)و✧
環境作り王に俺はなる…!!
[参考]
かげきしょうじょ!! 見てください