以下のサイトの通りに新規プロジェクトを立ち上げて、ReactのSSRをセットアップしました。
こちらの環境は、以下の通りにすれば再現できると思います。
https://www.digitalocean.com/community/tutorials/react-server-side-rendering-ja
試したこと
エラーが出るがデバッグ自体はできる
npm run dev:build-server
は、以下のエラーが発生するもののサーバー自体は正常に動作します。
ただしHTMLを確認すると、うまくSSRによる静的レンダリングができていませんでした。
ERROR in ./server/index.js Module not found: Error: Can't resolve '../src/App.js' in '/Users/kmy/Develop/react/server' @ ./server/index.js 6:0-32
webpackの「-w」を外したらビルドできない
将来的にこのアプリをサーバーにデプロイすることを考えており、そのためにはExpressサーバーのソースコード(server/index.js
)をproduction
でビルドして成果物をserver-build
フォルダに生成する必要があります。
webpackの-wオプションはファイルの変更をリアルタイムで監視しますが、これは開発用のオプションであり、製品用ビルドでは必要ありません。なのでこれを外してビルドを試みました。
"scripts": { ... "build-server": "NODE_ENV=production webpack --config webpack.server.js --mode=production", },
しかしnpm run build-server
でビルドしようとするとこのようなエラーが発生し、server-build
フォルダは生成されませんでした。
ERROR in ./server/index.js Module not found: Error: Can't resolve '../src/App.js' in '/Users/kmy/Develop/react/server' @ ./server/index.js 6:0-32
対処:jsxのインポートに対応する
エラーが起きたのはserver/index.js
の以下の行であると考えられます。
js
1import App from '../src/App';
この行は、src/App.jsx
をインポートします。しかしExpressサーバーのビルドにあたって、拡張子jsx
をもつファイルが認識されないのではないかと考えました。
そこで、webpack.server.js
に以下の記述を追加しました。
resolve: { extensions: ['.js', '.jsx'], }
対処:JSX記法のビルドに対応する
しかし、これでビルドしようとすると以下のエラーが発生しました。
ERROR in ./src/App.jsx 7:4 Module parse failed: Unexpected token (7:4) You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders | function App() { | return ( > <div className="App"> | <header className="App-header"> | <img src={logo} className="App-logo" alt="logo" /> @ ./server/index.js 6:0-29
これはJSX記法のロードに対応できていないと考え、webpack.server.js
の設定を以下のように変更しました。
module: { rules: [ { test: /.(js|jsx)$/, exclude: /node_modules/, loader: 'babel-loader', options: { presets: ["@babel/preset-env", "@babel/preset-react"] } }
対処:SVGとCSSのビルドに対応する
しかし上記でビルドしようとすると、また以下のエラーが発生しました。
ERROR in ./src/App.css 1:0 Module parse failed: Unexpected token (1:0) You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders > .App { | text-align: center; | } @ ./src/App.jsx 3:0-19 @ ./server/index.js ERROR in ./src/logo.svg 1:0 Module parse failed: Unexpected token (1:0) 以下略
これは、App.jsx
ファイル内にある以下のimport
文が引き起こしたエラーであると思われます。
js
1import logo from './logo.svg'; 2import './App.css';
そこで、これらのファイルのローダーをwebpack.server.js
に追加しました。
js
1 module: [ 2 rules: [ 3 // ... 4 { 5 test: [/.bmp$/, /.gif$/, /.jpe?g$/, /.png$/, /.svg$/], 6 loader: require.resolve('url-loader'), 7 options: { 8 limit: 0, 9 name: 'static/media/[name].[hash:8].[ext]', 10 }, 11 }, 12 { 13 test: /.(css)$/, 14 exclude: /node_modules/, 15 loader: ['style-loader', 'css-loader'] 16 }
結果として、ビルドは成功し、server-build/index.js
ファイルが生成されました。
問題:サーバーを起動しようとするとエラーが起きる
実際の環境に配置した場合を考慮して、ビルドしたserver-build/index.js
の起動をnode server-build/index.js
で試みます。
しかし、以下のエラーが発生し、サーバーの起動に失敗しました。
ReferenceError: document is not defined
ビルドによって生成されたserver-build/index.js
を確認すると、どうやら本来ブラウザ上で実行すべきReactのコードが、サーバーサイドのプログラムの中に混じってしまったようなのです。
私の対処がどの段階から間違っていたのか調べようにも、どのサイトやStackoverflowの質問も、そもそもimport '../src/App'
が正常におこなえることを前提にことを進めているのです。したがってどのように対処すればいいのか分かりません。
ReactのSSRで正常にビルドできるようにするためには、どのようにすればいいのでしょうか?
今回インストールしたパッケージのバージョン
"dependencies": { "@babel/plugin-transform-react-jsx": "^7.14.9", "@testing-library/jest-dom": "^5.14.1", "@testing-library/react": "^11.2.7", "@testing-library/user-event": "^12.8.3", "express": "^4.17.1", "react": "^17.0.2", "react-dom": "^17.0.2", "react-scripts": "^4.0.3", "type-fest": "^0.21.3", "web-vitals": "^1.1.2" }, "devDependencies": { "@babel/core": "^7.15.0", "@babel/preset-env": "^7.15.0", "@babel/preset-react": "^7.14.5", "babel-loader": "^8.1.0", "babel-preset-env": "^1.7.0", "babel-preset-react": "^6.24.1", "nodemon": "^2.0.12", "npm-run-all": "^4.1.5", "webpack": "^4.44.2", "webpack-cli": "^4.7.2", "webpack-node-externals": "^3.0.0" }
環境
macOS Catalina
VSCode
kmy@KMYnoMac-mini react % node --version v12.18.0 kmy@KMYnoMac-mini react % npm --version 7.19.1
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。