tatsumiyamamoto.com

typescriptで特定のファイルからのauto importをしないようにしたい

2023-04-05

# はじめに

server components(sc)と client components(cc)という機能が nextjs のappディレクトリ内で使用できるようになりました。先日試していたときに、vscode の import のめんどくささがあったのでメモしておきます。より良い方法などあれば教えてください。

# 結論

vscode 前提です。 typescript のバージョンが 4.8 以上である必要があります

.vscode/settings.json
{
  "typescript.tsdk": "node_modules/typescript/lib",
  "typescript.preferences.autoImportFileExcludePatterns": [
    // 除外したいものを書く
  ]
}

# 使用例的なもの

app ディレクトリと UI フレームワーク、例えばchakra uiを組み合わせたいとします。 とりあえず、ChakraProviderでルートコンポーネントを囲みたいんですが、以下のような感じだと動きません。

layout.tsx(動かない)
import { ChakraProvider } from '@chakra-ui/react';

export const metadata = {
  title: 'Tatsumi Yamamoto',
  description: 'yamamoto tatsumi dayo',
};

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang='ja'>
      <head />
      <ChakraProvider>
        <body>{children}</body>
      </ChakraProvider>
    </html>
  );
}

理由は layout.tsx に'use client';がなく、sc では state などが使えないからです。ChakraProvider は内部で state とかを使っているのでエラーになります。

そこで、'use client';を足して cc にしてみますが、これは良くないみたいです。

root layout はデフォルトで Server component であり、Client Component にすることはできません。 (The root layout is a Server Component by default and can not be set to a Client Component.)

Routing: Pages | Next.js
Create your first page in Next.js
Routing: Pages | Next.js favicon https://beta.nextjs.org/docs/routing/pages-and-layouts#root-layout-required
Routing: Pages | Next.js
layout.tsx(ダメ)
'use client';
import { ChakraProvider } from '@chakra-ui/react';

export const metadata = {
  title: 'Tatsumi Yamamoto',
  description: 'yamamoto tatsumi',
};

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang='ja'>
      <head />
      <ChakraProvider>
        <body>{children}</body>
      </ChakraProvider>
    </html>
  );
}

そのため、以下のように一旦 cc から全てを export します。

chakraComponents.tsx
'use client';

export * from '@chakra-ui/react';

そして、chakra ui のコンポーネントを使うときはここから import するようにします。

layout.tsx
import { ChakraProvider } from './chakraComponents';

export const metadata = {
  title: 'Tatsumi Yamamoto',
  description: 'yamamoto tatsumi',
};

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang='ja'>
      <head />
      <ChakraProvider>
        <body>{children}</body>
      </ChakraProvider>
    </html>
  );
}

このときに、@chakra-ui/reactからは import したくないのですが、vscode では import の候補に出てしまうので、一旦以下のような記述で黙らせることができます。

.vscode/settings.json
{
  "typescript.tsdk": "node_modules/typescript/lib",
  "typescript.preferences.autoImportFileExcludePatterns": [
    "node_modules/@chakra-ui"
  ]
}

appディレクトリを本格的に使ったことがないので、もしかしたらこの設定で問題が出るかもしれませんし、ui フレームワーク側の何かしらの対応で解決するかもしれませんが、とりあえずメモです。

# 参考

Chakra-ui dose not support next js 13 app directory yet ? · Issue #7209 · chakra-ui/chakra-ui
Description My demo repo https://github.com/anhdd-kuro/next13-strapi-chakraui-demo/tree/main/client I have the same code in pages/test.tsx and app/page.tsx + app/layout.tsx There is no problem with...
Chakra-ui dose not support next js 13 app directory yet ? · Issue #7209 · chakra-ui/chakra-ui favicon https://github.com/chakra-ui/chakra-ui/issues/7209
Chakra-ui dose not support next js 13 app directory yet ? · Issue #7209 · chakra-ui/chakra-ui
Next.js 13のappディレクトリの基礎(Layout, Suspense, Data Fetching...)
Next.js 13で新たに追加されたappディレクトリについて簡単なコードを利用しながら動作確認を行なっています。本文書を読み終えるとSuspense, Data Fetchig, Server Component, Client Component, Nested Layoutsなどの理解を深めることができます。
Next.js 13のappディレクトリの基礎(Layout, Suspense, Data Fetching...) favicon https://reffect.co.jp/react/next-js-13-app#i
Next.js 13のappディレクトリの基礎(Layout, Suspense, Data Fetching...)
Next.js 13 app directory で記事投稿サイトを作ってみよう
Next.js 13 app directory で記事投稿サイトを作ってみよう favicon https://zenn.dev/azukiazusa/articles/next-js-app-dir-tutorial
Next.js 13 app directory で記事投稿サイトを作ってみよう