Remix 2.6.0+Vite(Unstable)集成React Bricks遇导入错误求助
Remix 2.6.0 + Vite不稳定版集成React Bricks 4.2.0时ESM导入错误解决方案
问题核心
在使用Remix 2.6.0搭配不稳定版Vite插件时,集成React Bricks 4.2.0遇到导入错误,Node尝试用CJS加载器处理ESM模块,触发SyntaxError: 无法在模块外部使用import语句。
错误信息
[vite] 评估SSR模块virtual:remix/server-build时出错:无法导入"/app/root.tsx" |- /remix-brick-starter/node_modules/react-bricks/frontend/react-bricks-frontend.esm.js:1 import"intersection-observer";export{F as File,f as Image,L as Link,M as Meta,P as PageViewer,k as Preview,l as ReactBricks,h as Repeater,C as RichText,R as RichTextExt,T as Text,e as blockPluginConstructor,n as fetchPage,o as fetchPages,r as fetchTags,m as markPluginConstructor,p as plugins,s as renderJsonLd,t as renderMeta,a as useAdminContext,d as usePage,v as usePagePublic,i as usePageValues,b as usePages,c as usePagesPublic,u as useReactBricksContext,w as useTagsPublic,j as useVisualEdit}from"../react-bricks-8fe38110.esm.js";export{J as JsonLd,P as Plain,c as cleanPage,e as getPagePlainText,f as getSchemaOrgData}from"../react-bricks-510b2066.esm.js";export{t as types}from"../react-bricks-3e09ae2e.esm.js";import"react";import"classnames";import"react-lazy-load-image-component";import"axios";import"react-query";import"ts-md5";import"react-icons/fi";import"../react-bricks-4db2fafe.esm.js"; ^^^^^^ SyntaxError: 无法在模块外部使用import语句 at internalCompileFunction (node:internal/vm:77:18) at wrapSafe (node:internal/modules/cjs/loader:1288:20) at Module._compile (node:internal/modules/cjs/loader:1340:27) at Module._extensions..js (node:internal/modules/cjs/loader:1435:10) at Module.load (node:internal/modules/cjs/loader:1207:32) at Module._load (node:internal/modules/cjs/loader:1023:12) at cjsLoader (node:internal/modules/esm/translators:356:17) at ModuleWrap. (node:internal/modules/esm/translators:305:7) at ModuleJob.run (node:internal/modules/esm/module_job:218:25) at async ModuleLoader.import (node:internal/modules/esm/loader:329:24)
环境配置
Node版本
20.11.0
vite.config.ts
import { unstable_vitePlugin as remix } from "@remix-run/dev"; import { installGlobals } from "@remix-run/node"; import { defineConfig } from "vite"; import tsconfigPaths from "vite-tsconfig-paths"; import { visualizer } from "rollup-plugin-visualizer"; import { cjsInterop } from "vite-plugin-cjs-interop"; import { remixDevTools } from "remix-development-tools/vite"; installGlobals(); export default defineConfig({ server: { port: 3000, }, plugins: [ remixDevTools(), remix({ unstable_ssr: false, appDirectory: "app", ignoredRouteFiles: ["**/.*"], publicPath: "/build/", serverModuleFormat: "esm", }), tsconfigPaths(), cjsInterop({ dependencies: ["react-bricks"], }), visualizer({ emitFile: true }), ], });
tsconfig.json
{ "include": ["env.d.ts", "**/*.ts", "**/*.tsx"], "exclude": ["node_modules", "**/__generated__/*"], "compilerOptions": { "lib": ["DOM", "DOM.Iterable", "ES2022"], "isolatedModules": true, "esModuleInterop": true, "jsx": "react-jsx", "module": "ESNext", "target": "ES2022", "moduleResolution": "Bundler", "resolveJsonModule": true, "strict": true, "baseUrl": ".", "paths": { "~/*": ["./*"] }, "noEmit": true, "allowJs": true, "forceConsistentCasingInFileNames": true, "skipLibCheck": true, "types": ["vitest/globals"], "verbatimModuleSyntax": true }, "ts-node": { "compilerOptions": { "module": "NodeNext" }, "esm": false, "files": true, "require": ["tsconfig-paths/register"] } }
package.json
{ "name": "remix-brick-starter", "private": true, "sideEffects": false, "type": "module", "scripts": { "build": "remix vite:build --profile", "codegen:brick": "tsx scripts/codegen-brick.ts", "codegen:brick-layout": "tsx scripts/codegen-brick-layout.ts", "codegen:component": "tsx scripts/codegen-component.ts", "dev": "node ./server.mjs", "format": "prettier --write .", "lint:css": "stylelint --cache --cache-location ./node_modules/.cache/stylelint \"app/**/*.css\"", "lint:js": "eslint --cache --ignore-path .gitignore --cache-location ./node_modules/.cache/eslint .", "lint": "run-p lint:*", "prepare": "husky install", "release": "ts-node scripts/release.ts", "start": "cross-env NODE_ENV=production node ./server.mjs", "storybook:build": "storybook build", "storybook:chromatic": "chromatic --project-token=chpt_a644d03df3f91da --build-script-name=storybook:build", "storybook": "storybook dev -p 6006 --no-open", "test": "vitest", "test:coverage": "vitest run --coverage", "typecheck": "tsc -b" }, "dependencies": { "@fontsource-variable/roboto-slab": "^5.0.18", "@fontsource/be-vietnam-pro": "^5.0.18", "@headlessui/react": "^1.7.18", "@remix-run/css-bundle": "^2.6.0", "@remix-run/node": "^2.6.0", "@remix-run/react": "^2.6.0", "@remix-run/serve": "^2.6.0", "isbot": "^4.1.0", "react": "^18.2.0", "react-bricks": "^4.2.0", "react-dom": "^18.2.0", "react-icons": "^5.0.1" }, "devDependencies": { "@babel/preset-env": "^7.23.9", "@csstools/postcss-global-data": "^2.1.1", "@graphql-codegen/cli": "^5.0.2", "@graphql-codegen/client-preset": "^4.2.2", "@graphql-codegen/typed-document-node": "^5.0.4", "@graphql-codegen/typescript": "^4.0.4", "@graphql-codegen/typescript-operations": "^4.1.2", "@graphql-codegen/typescript-resolvers": "^4.0.4", "@remix-run/dev": "^2.6.0", "@remix-run/eslint-config": "^2.6.0", "@storybook/addon-essentials": "^7.6.13", "@storybook/addon-interactions": "^7.6.13", "@storybook/addon-links": "^7.6.13", "@storybook/addon-onboarding": "^1.0.11", "@storybook/addon-styling": "^1.3.7", "@storybook/blocks": "^7.6.13", "@storybook/react": "^7.6.13", "@storybook/test": "^7.6.13", "@storybook/testing-library": "^0.2.2", "@testing-library/jest-dom": "^6.4.2", "@testing-library/react": "^14.2.1", "@testing-library/user-event": "^14.5.2", "@types/jsonp": "^0.2.3", "@types/negotiator": "^0.6.3", "@types/node": "^20.11.17", "@types/react": "^18.2.20", "@types/react-dom": "^18.2.7", "@typescript-eslint/eslint-plugin": "^6.21.0", "@typescript-eslint/parser": "^6.21.0", "@vitejs/plugin-react": "^4.2.1", "@vitest/coverage-v8": "^1.2.2", "autoprefixer": "^10.4.17", "calver": "^22.9.1", "chromatic": "^10.9.3", "clsx": "^2.1.0", "dotenv": "^16.4.1", "eslint": "^8.56.0", "eslint-import-resolver-typescript": "^3.6.1", "eslint-plugin-import": "^2.28.1", "eslint-plugin-jsx-a11y": "^6.7.1", "eslint-plugin-react": "^7.33.2", "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-storybook": "^0.6.15", "husky": "^9.0.10", "jsdom": "^24.0.0", "lint-staged": "^15.2.2", "prettier": "^3.2.5", "remix-development-tools": "^3.7.4", "rollup-plugin-visualizer": "^5.12.0", "storybook": "^7.6.13", "stylelint": "^16.2.1", "stylelint-config-recommended": "^14.0.0", "tailwindcss": "^3.4.1", "ts-node": "^10.9.2", "tsx": "^4.7.0", "typescript": "^5.1.6", "vite-plugin-cjs-interop": "^2.0.5", "vite-tsconfig-paths": "^4.3.1", "vitest": "^1.2.2" }, "engines": { "node": "20" }, "lint-staged": { "*.{js,jsx,ts,tsx,json,css}": [ "prettier --write" ], "*.{js,jsx,ts,tsx}": [ "eslint" ], "*.css": [ "stylelint --fix" ] } }
解决方案
方案1:强制Vite转译React Bricks模块
修改vite.config.ts中的Remix插件配置,将react-bricks排除在外部依赖列表外,让Vite处理其ESM模块:
remix({ unstable_ssr: false, appDirectory: "app", ignoredRouteFiles: ["**/.*"], publicPath: "/build/", serverModuleFormat: "esm", // 关键配置:不让Vite将react-bricks标记为外部依赖 serverDependenciesToExternalize: (dep) => !dep.startsWith("react-bricks"), }),
方案2:预构建React Bricks依赖
在Vite配置中添加optimizeDeps,强制预构建react-bricks,确保其被正确识别为ESM:
export default defineConfig({ // ...其他配置 optimizeDeps: { include: ["react-bricks"], }, plugins: [/* ...现有插件 */], });
方案3:升级React Bricks版本
React Bricks 4.2.0可能存在与Remix Vite插件的兼容性问题,尝试升级到最新稳定版:
npm install react-bricks@latest
方案4:调整导入方式(临时 workaround)
在root.tsx中使用动态导入替代静态导入,避免在SSR模块加载阶段触发ESM导入:
// 替换静态导入 // import { ReactBricks } from 'react-bricks' // 改用动态导入(仅在客户端渲染时执行) const { ReactBricks } = await import('react-bricks')
内容的提问来源于stack exchange,提问作者Morgan Segura
相关产品推荐
相关产品推荐

