このためのPRがあれば幸いです。
依存関係はサーバーサイドレンダリング用に構築されていないため、かなり難しいでしょう。 今のところ、私が行ったことであるlibを使用したい場合は、クライアントがレンダリングしたReactコンポーネントを使用することをお勧めします。 しかし、パフォーマンスを向上させるために、フォークにいくつかの小さな変更を加えました。 また、このフォークはPR用に最適化されていません。 よろしければご用意させていただきます。
私はちょうどこれと同じ問題に遭遇しました。 考えられる解決策の1つは、メインバンドルとは別の方法でブレースを引き込むことです。 とにかくクライアントはJavaScriptを必要としていたので、少なくともページの残りの部分をレンダリングすることができます。
私が見たところ、AceはDOMAPIを直接使用してエディターを作成しています。 jsdomのようなものを使用して、サーバー上のブラウザー環境をシミュレートすることは可能ではないでしょうか。
NextJSは、React.JSサーバーサイドレンダリングアプリケーションを強力にサポートします。 クライアント側のみをインポートできる動的機能があります。
私が使用する実装。
クライアント側コンポーネント
import brace from 'brace';
import 'brace/mode/javascript';
import 'brace/mode/c_cpp';
import 'brace/theme/twilight';
import 'brace/theme/xcode';
import AceEditor from 'react-ace';
const textEditor = (props) => (
<div>
<AceEditor
mode={props.lan}
theme={props.theme}
onChange={props.onChange}
name="UNIQUE_ID_OF_DIV"
editorProps={{
$blockScrolling: true
}}
fontSize={21}
height='80vh'
width='100%'
/>
</div>
)
export default textEditor
`
インポートする方法
import React, { Component } from 'react
import dynamic from 'next/dynamic'
const TextEditor = dynamic(import('../components/textEditor'), {
ssr: false
})
export default class Index extends Component {
...
render() {
return (
<div>
<TextEditor lan='javascript' theme="twilight"/>
</div>
)
}
「next / dynamic」を使用することによる副作用はありますか? またはそれを使用しても問題ありません。
私は問題を見ていませんが、開発方法についてNext、JSフレームワークのガイドラインに従っていることを正しく指摘しました。
とても悲しい(((
これに非常に興味があります。 私たちはエースを使用していて気に入っていますが、ギャツビーで使用する方法はまだ見つかりません。
@ saulflores95は私の場合、モードとテーマも動的にインポートする必要があるという正しい考えを持っています。 しかし、それを行ったとき、デフォルトの反応エースコンポーネントがインポートされる前にそれらがインポートされていたとは思わないので、テーマが表示されませんでした。 エースビルドのテーマとモードをインポートする前に、メインのインポートを待たなければなりませんでした。 これはバージョン8.0.0です。
const Editor = dynamic(
async () => {
const ace = await import('react-ace');
import('ace-builds/src-noconflict/mode-javascript');
import('ace-builds/src-noconflict/theme-textmate');
return ace;
},
{
// eslint-disable-next-line react/display-name
loading: () => (
<NoContent style={{ height: '520px' }}>
<Spinner diameter={100} />
</NoContent>
),
ssr: false,
},
);
参考までに、私のPRでは完全なSSRが有効になっていません。 サーバーで使用したときにreact-ace
が失敗するのを防ぐだけです。 サーバーにレンダリングされるものはすべて空白のdiv
あり、クライアントにロードされるとAceが入力します。
私はSSRのより完全なサポートに取り組んできました。つまり、Aceのロード後にクライアントで見られるものと同様に、サーバー上で実際にマークアップを生成します。 Aceは、jsdomでモックアウトする必要がある負荷に対して、かなり厄介で複雑なレイアウト計算を行うため、これは重要です。 したがって、クライアント側に表示されるもののように見えるものを取得するには、おそらくこれらのレイアウト定数のいくつかを渡す必要があります。
とにかく、これは間違いなく正しい方向への一歩です。 react-ace
がSSRを爆破しないようになったので、ラッパーコンポーネントを使用してより複雑なSSRアプローチを実装できるはずです。
@JohnGrishamに感謝します、あなたの解決策は私のために働きました。 ただし、インポートをrequireに置き換える必要がありました
const Ace = dynamic(
async () => {
const ace = await import('react-ace');
require('ace-builds/src-noconflict/mode-mysql');
require('ace-builds/src-noconflict/theme-xcode');
return ace;
},
{
loading: () => (
<>Loading...</>
),
ssr: false,
})
...
<Ace mode="mysql" theme="xcode" />
@ saulflores95は私の場合、モードとテーマも動的にインポートする必要があるという正しい考えを持っています。 しかし、それを行ったとき、デフォルトの反応エースコンポーネントがインポートされる前にそれらがインポートされていたとは思わないので、テーマが表示されませんでした。 エースビルドのテーマとモードをインポートする前に、メインのインポートを待たなければなりませんでした。 これはバージョン8.0.0です。
const Editor = dynamic( async () => { const ace = await import('react-ace'); import('ace-builds/src-noconflict/mode-javascript'); import('ace-builds/src-noconflict/theme-textmate'); return ace; }, { // eslint-disable-next-line react/display-name loading: () => ( <NoContent style={{ height: '520px' }}> <Spinner diameter={100} /> </NoContent> ), ssr: false, }, );
部分的に協力し、モードと不足しているテーマは、(また、使用してみましたrequire
の代わりにimport
)。
WSL2
搭載したWindows 10[email protected]
(および[email protected]
)[email protected]
[email protected]
[email protected]
npm run dev
( next dev
)から始まります。
Google Chrome87コンソールは次のエラーを出力します。
スクリプトsrcからaceへのパスを推測できない場合は、ace.config.set( 'basePath'、 'path')を使用してモードとテーマの動的ロードを有効にするか、webpackでace / webpack-resolverを使用してください
このリクエストの404ステータスコードにも気づきました:
代わりに、この他のアプローチを使用する場合:
// code-editor.js
import AceEditor from 'react-ace'
import 'ace-builds/src-noconflict/mode-javascript'
import 'ace-builds/src-noconflict/theme-monokai'
const handleOnChange = () => {
console.log('Changed!')
}
export default function CodeEditor() {
return (
<AceEditor
mode="javascript"
theme="monakai"
onChange={handleOnChange}
name="editor01"
/>
)
}
// hello-world.js
import dynamic from 'next/dynamic'
const CodeEditor = dynamic(
() => import('../../components/code-editor'),
{ ssr: false },
)
export default function HelloWorld() {
return <CodeEditor />
}
同じエラーが発生しますが、404エラーがわずかに異なります。
最も参考になるコメント
NextJSは、React.JSサーバーサイドレンダリングアプリケーションを強力にサポートします。 クライアント側のみをインポートできる動的機能があります。
私が使用する実装。
クライアント側コンポーネント
`
インポートする方法