如何修复“ReferenceError:在”构建期间未定义导航器

问题描述 投票:0回答:2

我有一个使用 TypeScript 的 Next.js 项目。我参考了官方文档,结果如下。

BundledEditor.jsx:

// ** https://www.tiny.cloud/docs/tinymce/6/react-pm-bundle/ **//
import { Editor } from '@tinymce/tinymce-react'

// remove ssr, otherwise will cause ReferenceError: navigator is not defined

// TinyMCE so the global var exists
// eslint-disable-next-line no-unused-vars
import tinymce from 'tinymce/tinymce'

// DOM model
import 'tinymce/models/dom/model'

// Theme
import 'tinymce/themes/silver'

// Toolbar icons
import 'tinymce/icons/default'

// Editor styles
import 'tinymce/skins/ui/oxide/skin.min.css'

// importing the plugin js.
// if you use a plugin that is not listed here the editor will fail to load
import 'tinymce/plugins/advlist'
import 'tinymce/plugins/anchor'
import 'tinymce/plugins/autolink'
import 'tinymce/plugins/autoresize'
import 'tinymce/plugins/autosave'
import 'tinymce/plugins/charmap'
import 'tinymce/plugins/code'
import 'tinymce/plugins/codesample'
import 'tinymce/plugins/directionality'
import 'tinymce/plugins/emoticons'
import 'tinymce/plugins/fullscreen'
import 'tinymce/plugins/help'
import 'tinymce/plugins/image'
import 'tinymce/plugins/importcss'
import 'tinymce/plugins/insertdatetime'
import 'tinymce/plugins/link'
import 'tinymce/plugins/lists'
import 'tinymce/plugins/media'
import 'tinymce/plugins/nonbreaking'
import 'tinymce/plugins/pagebreak'
import 'tinymce/plugins/preview'
import 'tinymce/plugins/quickbars'
import 'tinymce/plugins/save'
import 'tinymce/plugins/searchreplace'
import 'tinymce/plugins/table'
import 'tinymce/plugins/template'
import 'tinymce/plugins/visualblocks'
import 'tinymce/plugins/visualchars'
import 'tinymce/plugins/wordcount'

// importing plugin resources
import 'tinymce/plugins/emoticons/js/emojis'

// Content styles, including inline UI like fake cursors
/* eslint import/no-webpack-loader-syntax: off */
// import contentCss from 'tinymce/skins/content/dark/content.css'

import contentCss from '!!raw-loader!tinymce/skins/content/default/content.min.css'
import contentUiCss from '!!raw-loader!tinymce/skins/ui/oxide/content.min.css'

export default function BundledEditor(props) {
  const { init, ...rest } = props

  // note that skin and content_css is disabled to avoid the normal
  // loading process and is instead loaded as a string via content_style
  return (
    <Editor
      init={{
        ...init,
        skin: false,
        content_css: false,
        content_style: [contentCss, contentUiCss, init.content_style || ''].join('\n')
      }}
      {...rest}
    />
  )
}

我只是将其导入到其他文件中,如下所示:

import BundledEditor from './BundledEditor';

可以,但是如果刷新,页面会显示这个错误:

ReferenceError:导航器未定义

所以我像这样改变导入方式:

// remove ssr, otherwise will cause ReferenceError: navigator is not defined

const BundledEditor = dynamic(() => import('../BundledEditor'), {
  ssr: false
})

然后解决问题。

但是当我尝试输入

yarn build
来检查项目时。

显示错误:

info  - Collecting page data ...ReferenceError: navigator is not defined
    at /Users/motogod19/4iDPS/Sphere/sphere-brand-dev/node_modules/tinymce/tinymce.js:961:23
    at Object.<anonymous> (/Users/motogod19/4iDPS/Sphere/sphere-brand-dev/node_modules/tinymce/tinymce.js:31525:3)
    at Module._compile (node:internal/modules/cjs/loader:1254:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1308:10)
    at Module.load (node:internal/modules/cjs/loader:1117:32)
    at Module._load (node:internal/modules/cjs/loader:958:12)
    at Module.require (node:internal/modules/cjs/loader:1141:19)
    at require (node:internal/modules/cjs/helpers:110:18)
    at 3868 (/Users/motogod19/4iDPS/Sphere/sphere-brand-dev/.next/server/pages/apps/campaign/BundledEditor.js:28:33)
    at __webpack_require__ (/Users/motogod19/4iDPS/Sphere/sphere-brand-dev/.next/server/webpack-runtime.js:25:42)

> Build error occurred
Error: Failed to collect page data for /apps/campaign/BundledEditor

我不熟悉 Next.js,我应该做任何动态导入吗?

reactjs next.js tinymce
2个回答
1
投票

navigator is not defined
表示您正在捆绑服务器端的代码,服务器端没有与浏览器相关的 API。您需要为客户端(即浏览器)捆绑它。

问题是因为

tinymce
不支持ssr(从https://github.com/tinymce/tinymce/issues/3709可以明显看出)


由于您使用的是 Next.js 13 和

pages
路由器,请将您的
BundleEditor.jsx
更改为以下内容:

// ** https://www.tiny.cloud/docs/tinymce/6/react-pm-bundle/ **//
import React from 'react';

import { Editor } from '@tinymce/tinymce-react';

if (typeof window !== 'undefined') {
    require('tinymce/tinymce');
    require('tinymce/models/dom/model');
    require('tinymce/themes/silver');
    require('tinymce/icons/default');
    require('tinymce/plugins/advlist');
    require('tinymce/plugins/anchor');
    require('tinymce/plugins/autolink');
    require('tinymce/plugins/autoresize');
    require('tinymce/plugins/autosave');
    require('tinymce/plugins/charmap');
    require('tinymce/plugins/code');
    require('tinymce/plugins/codesample');
    require('tinymce/plugins/directionality');
    require('tinymce/plugins/emoticons');
    require('tinymce/plugins/fullscreen');
    require('tinymce/plugins/help');
    require('tinymce/plugins/image');
    require('tinymce/plugins/importcss');
    require('tinymce/plugins/insertdatetime');
    require('tinymce/plugins/link');
    require('tinymce/plugins/lists');
    require('tinymce/plugins/media');
    require('tinymce/plugins/nonbreaking');
    require('tinymce/plugins/pagebreak');
    require('tinymce/plugins/preview');
    require('tinymce/plugins/quickbars');
    require('tinymce/plugins/save');
    require('tinymce/plugins/searchreplace');
    require('tinymce/plugins/table');
    require('tinymce/plugins/template');
    require('tinymce/plugins/visualblocks');
    require('tinymce/plugins/visualchars');
    require('tinymce/plugins/wordcount');
    require('tinymce/plugins/emoticons/js/emojis')
}

// Editor styles
import 'tinymce/skins/ui/oxide/skin.min.css';

// Content styles, including inline UI like fake cursors
/* eslint import/no-webpack-loader-syntax: off */
// import contentCss from 'tinymce/skins/content/dark/content.css'

import contentCss from '!!raw-loader!tinymce/skins/content/default/content.min.css';
import contentUiCss from '!!raw-loader!tinymce/skins/ui/oxide/content.min.css';

export default function BundledEditor(props) {
    const { init, ...rest } = props;

    // note that skin and content_css is disabled to avoid the normal
    // loading process and is instead loaded as a string via content_style
    return (
        <Editor
            init={{
                ...init,
                skin: false,
                content_css: false,
                content_style: [contentCss, contentUiCss, init?.content_style || ''].join('\n'),
            }}
            {...rest}
        />
    );
}

npm run dev
npm run build
都可以正常工作。

$ npm run build

> [email protected] build
> next build

- info Linting and checking validity of types  
- info Creating an optimized production build  
- info Compiled successfully
- info Collecting page data  
- info Generating static pages (4/4)
- info Finalizing page optimization  

Route (pages)                              Size     First Load JS
┌ ○ /                                      3.39 kB        80.3 kB
├   └ css/00a586533d958f8e.css             1.73 kB
├   /_app                                  0 B            76.9 kB
├ ○ /404                                   182 B          77.1 kB
├ λ /api/hello                             0 B            76.9 kB
└ ○ /BundledEditor                         473 kB          550 kB
    └ css/3191dae2698bb014.css             11.8 kB
+ First Load JS shared by all              77.6 kB
  ├ chunks/framework-63157d71ad419e09.js   45.2 kB
  ├ chunks/main-c6c319de9f7d0316.js        29.4 kB
  ├ chunks/pages/_app-5fbdfbcdfb555d2f.js  296 B
  ├ chunks/webpack-1f3c29ac3f0dceed.js     2.06 kB
  └ css/876d048b5dab7c28.css               706 B

λ  (Server)  server-side renders at runtime (uses getInitialProps or getServerSideProps)
○  (Static)  automatically rendered as static HTML (uses no initial props)

0
投票

您收到该错误是因为

tinymce
似乎对服务器端渲染不友好,因为在组件主体或导入时执行浏览器特定代码。也就是说,根本不建议使用其他答案中建议的
typeof window !== 'undefined'
,因为它很可能会导致水合错误

使用

dynamic
导入和
ssr:false
应该可以。在您的情况下,它没有,因为您在
BundledEditor
目录中有
pages
,所以它被视为
/BundledEditor
的页面,导致另一个错误。

只需将

BundledEditor
移到
pages
之外,例如在
components
文件夹中,与
pages
处于同一级别,然后像这样导入它:

// pages/index.tsx

import dynamic from "next/dynamic";

const DynamicBundledEditor = dynamic(() => import("../../components/BundledEditor"), {
  ssr: false,
});
© www.soinside.com 2019 - 2024. All rights reserved.