VIXプラグインSSRを使用して、ESMのみのライブラリの問題を解決する


vite-plugin-ssr VITEプラグインは、サーバー側のレンダリング、クライアント側のレンダリング、単一のページのアプリケーションと静的サイトの生成のすべてのWebサイトを構築することができますです.このプラグインは次のようです.しかし、各ページ以上のコントロールを提供し、お好みのフロントエンドのフレームワークのいずれか.このプラグインを使用する方法を学ぶためにウェブサイトをご覧ください.
このチュートリアルでは、私たちはどのようにセットアップをMDX JSライブラリを構築するためのマークダウンベースのウェブサイトを構築するためには、それらを使用してpriteのウェブサイトのプラグインSSRを使用して静的なウェブサイトを生成する.

The vite-plugin-ssr github repo contains example projects which you can clone and start with. For example react-full example already provides a setup for working with mdx-js library. The intention of this tutorial is to show how to solve some of the problems I encountered while using the mdx-js library and vite-plugin-ssr prerender feature.


プロジェクト設定


まず最初に、Vite + ViteプラグインSSRベースのプロジェクトを設定する必要があります.VITEプラグインSSRプロジェクトを足場にするには
npm init vite-plugin-ssr
プロジェクトを名前(NNブログという名前)に与え、フロントエンドフレームワーク(この例では反応します)を選択します.コマンドが実行されると、単にプロジェクトフォルダに移動し、すべての依存関係をインストールします.
cd nn-blog
npm install
次に、npm run dev . おめでとう、ちょうどVite + ViteプラグインSSRベースのプロジェクトを設定しました.セットアップはgit - repoで初期化されますので、コードを変更し始めることができます.そして、あなたはどのように燃えるように高速VTEのdevのサーバーが通知されます.
一度理解するfilesystem routing ViteプラグインSSRの概念は、いくつかのページと実験を作成します.準備が整ったら、MDX jsを追加してみましょう.

VITEプロジェクトへのMDX JSの追加


MDXのJSは、あなたがJSXベースのライブラリで使用することができますJSX互換性のコンテンツにMarkdownコンテンツを変換するライブラリです.

MDX allows you to use JSX in your markdown content. You can import components, such as interactive charts or alerts, and embed them within your content.
vite uses rollup under the hood to build bundles for production. So for installing mdx-js to a vite project, we should use @mdx-js/rollup and for handling custom MDX components we can use @mdx-js/react for react based projects.


npm install @mdx-js/rollup @mdx-js/react
ライブラリがインストールされると、vite.config.js ファイルと設定MDXプラグインを使用して@ mdx js/をproiderimportソースとして使用します.
import react from '@vitejs/plugin-react'
import ssr from 'vite-plugin-ssr/plugin'
+import mdx from "@mdx-js/rollup"

export default {
- plugins: [react(), ssr()]
+ plugins: [react(), mdx({
+   providerImportSource: "@mdx-js/react"
+ }), ssr()],
}

問題の解決1


更新後vite.config.js 我々が走ろうとするならばnpm run dev 我々は、この混乱したエラーを与えられます
failed to load config from /workspace/example/nn-blog/vite.config.js
/workspace/example/nn-blog/vite.config.js:61509
undefined
            ^

Error [ERR_REQUIRE_ESM]: require() of ES Module /workspace/example/nn-blog/node_modules/@mdx-js/rollup/index.js from /workspace/example/nn-blog/vite.config.js not supported.
この問題は次の順序で行われる.
  • npm run dev ランnode ./server/index.js CommonJSファイルのファイル
  • スクリプトを使用してvite devサーバーを作成しますvite.createServer
  • VITE devサーバの変換vite.config.js 最初にCJSモジュールにこのファイルから設定を読み込みます.
  • としてrequire("@mdx-js/rollup") ESMオンリーモジュールであるプラグインはエラーが発生します.
  • この問題を解決するために、私たちはVTEにCJSへの設定ファイルをスキップするよう通知しなければなりません.これは、
    + "type": "module",
    }
    
    to package.json ファイル.

    問題2 - require ()はESモジュールスコープで定義されません


    ノードにESモジュールを有効にすると、使用できませんrequire 構文.js ファイル.これは、あなたが走るとき、あなたが得るものですnpm run dev
    file:///workspace/example/nn-blog/server/index.js:1
    const express = require('express')
                    ^
    
    ReferenceError: require is not defined in ES module scope, you can use import instead
    This file is being treated as an ES module because it has a '.js' file extension and '/workspace/example/nn-blog/package.json' contains "type": "module". To treat it as a CommonJS script, rename it to use the '.cjs' file extension.
    
    幸いにも、エラー自体が解決策をくれました.しかし、最初にあなたの頭の傷を停止し、解決策を識別するためにこれらの行を読むことを学ぶ必要があります.あなたが慎重に我々が必要とするものを見るならばindex.js ファイルindex.cjs and 💣

    問題3を解決する


    node:internal/modules/cjs/loader:936
      throw err;
      ^
    
    Error: Cannot find module '/workspace/example/nn-blog/server'
        at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
        at Function.Module._load (node:internal/modules/cjs/loader:778:27)
        at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
        at node:internal/main/run_main_module:17:47 {
      code: 'MODULE_NOT_FOUND',
      requireStack: []
    }
    
    待って、私たちのファイルはどこですか?ノードはそれを見つけることができませんが、サーバーフォルダーの右側にあると言います.
    あなたが十分な患者や十分に才能のあるオタク十分な場合は、ノードがロードしようとしていることを理解するでしょうserver モジュールではなくserver/index.js . The /index.js ファイルは、CJS module loading sequence of node . それで、我々はAを加える必要がありますpackage.json 以下の値を持つファイル
    {
      "main": "index.cjs"
    }
    
    And ✨ おめでとう、あなたは今行く準備ができています.

    ページの追加


    ページディレクトリと任意のマークダウンコンテンツに移動します.md or .mdx エクステンション.例えば、/naveennamani ルートを追加pages/naveennamani.page.mdx or pages/naveennamani/index.page.mdx or pages/index/naveennamani.page.mdx ファイル.(この例の最後のファイル名を好みます).
    ファイルを作成すると、任意のマークダウンコンテンツを追加し、[ localhost : 3000/naveennamani ] URLをHTMLに変換してマークダウンコンテンツを参照してください.あなたのMDXファイル内の反応コンポーネントを使用するには、単にそれらをインポートし、使用します.
    # Hello world
    
    import { Counter } from './Counter'
    
    <Counter />
    
    これは、ホームページにも表示されているインタラクティブなカウンターで見出しが表示されます.

    新しい問題の解決と発明


    ときに、devのサーバーを停止し、スタティックコンテンツとして素晴らしいウェブサイトを構築するには、ViteプラグインSSR prerender機能を使用することができます.次のスクリプトをpackage.json
    "scripts": {
       ...
       "prerender": "npm run build && vite-plugin-ssr prerender"
    }
    
    現在、あなたが走るときnpm run prerender , そうでしょうdist\client and dist\server フォルダが作成され、ビルドファイルがそこに配置されます.しかし、prerenderingは失敗しています
    /workspace/example/nn-blog/dist/server/assets/naveennamani.page.04918628.js:4
    var react = require("@mdx-js/react");
                ^
    
    Error [ERR_REQUIRE_ESM]: require() of ES Module /workspace/example/nn-blog/node_modules/@mdx-js/react/index.js from /workspace/example/nn-blog/dist/server/assets/naveennamani.page.04918628.js not supported.
    
    それは我々が以前に解決したのと同じ問題ではないか.はい.しかし、なぜ再び?😢
    今回は問題は次の順序で作成されます.
  • あなたが走るときnpm run build 走るvite build and vite build --ssr のための最初のコマンドビルディング資産dist\client と2番目のコマンドdist\server .
  • dist\client 資産すべてesm モジュールdist\client ビルド出力はcjs モジュール
  • それで、再び@mdx-js/react ESMのみのモジュールはrequire .
  • 今回は、ビルドオプションを設定することで、CJSモジュールの代わりにESモジュールを生成できますvite.config.js 次の通り
      import react from '@vitejs/plugin-react'
      import ssr from 'vite-plugin-ssr/plugin'
      import mdx from "@mdx-js/rollup"
    + import { defineConfig } from 'vite'
    
    + export default defineConfig({
        plugins: [react(), mdx({
          providerImportSource: "@mdx-js/react"
        }), ssr()],
    +   build: {
    +     rollupOptions: {
    +       output: {
    +         format: "es"
    +       }
    +     }
    +   }
    + })
    
    
    あなたが走るときnpm run prerender 再び、あなたはそれを見ることができますdist\server フォルダにはESモジュールです.しかし、あなたはまだこの複雑なエラーを得る.
    Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/workspace/example/nn-blog/node_modules/react/jsx-runtime' imported from /workspace/example/nn-blog/dist/server/assets/index.page.0262694b.js
    Did you mean to import react/jsx-runtime.js?
    

    問題を解決するためのVITEプラグインの作成


    一見したところ、エラーはスペルミスのようです.しかし、あなたがGoogleならば、あるlong list of comments 公式にはrepo(発行no 2020235)に反応する.問題は単に追加することで解決できます.インポートにJSの拡張子が、どのように自動的に行うには?
    私たちのためにそれをするためにViteプラグインを書きましょう.あなたが続くならば、VITEプラグインを書くことは非常に単純ですVite plugin API .
    これが私の来たものです.
    export default function fix_ssr_esm_modules(replacements) {
      function transform(code, id, ssr) {
        if (ssr) // ssr is true when `vite build --ssr` is run
          return replacements.reduce((prevCode, { find, replacement }) => {
            return prevCode.replaceAll(find, replacement);
          }, code);
      }
    
      return { // configuration of our plugin used by vite
        name: "vite-plugin-fix-ssr-esm-modules",
        apply: "build", // execute only for build tasks
        enforce: "post", // execute after build finished
        transform: transform, // transformation function that returns transformed code
      };
    }
    
    ここでFixRange SsrChorse ESMUNNモジュールでコードを配置します.JSファイルをインポートし、このプラグインを使用しますvite.config.js ファイルを以下のようにします.
    + import fix_ssr_esm_modules from "./fix_ssr_esm_imports.js";
    
    export default defineConfig({
      plugins: [
        react(),
        mdx({
          providerImportSource: "@mdx-js/react",
        }),
        ssr(),
    +   fix_ssr_esm_modules([
    +     { find: "react/jsx-runtime", replacement: "react/jsx-runtime.js" },
    +     { find: "react-dom/server", replacement: "react-dom/server.js" },
    +   ]),
      ],
      build: {
        rollupOptions: {
          output: {
            format: "es",
          },
        },
      },
    });
    
    プラグインは、ビルドファイルを変換し、プラグインとして指定されたようにインポートを置き換えます.
    今すぐ実行することができますnpm run prerender ファイルをdist\client 静的使用npx serve . 祝辞🌟, あなたは、VITEプラグインSSRを使用して静的なサイトを構築しました.

    ファイナルタッチ


    プロジェクトのソースコードの最終バージョンはGithubnaveennamani/vite-ssr-mdx .

    There is a small inconsistency with server/index.js file, but that's an alternative I found while I'm writing this article.


    長いポストを残念に思う、あなたが結局ここに来るならば、ここにあなたのためのジャガイモがあります.