-
Notifications
You must be signed in to change notification settings - Fork 779
Fix: Next / Remix adaptation #2754
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: release
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -45,6 +45,11 @@ const SemiApp = () => { | |
|
|
||
| ## 3、在 NextJs 中使用 | ||
|
|
||
| <Notice> | ||
| 注意:以下配置适用于 React18及以下版本。Next15默认使用React19,目前Semi尚未实现React19的兼容性适配,如果使用Next15请将React版本降级为18或以下版本。 | ||
| </Notice> | ||
|
|
||
| - Node 版本要求 >= v22.12.0 | ||
| - 如果仅使用默认主题, 在 `transpilePackages` 追加 Semi 相关的 package即可 (Next.js 版本要求 >= v13.1 ) | ||
| ```diff | ||
| // next.config.js | ||
|
|
@@ -55,6 +60,7 @@ const nextConfig = { | |
| module.exports = nextConfig; | ||
| ``` | ||
|
|
||
|
|
||
| - 如果需要使用定制主题包或 Next.js版本低于 v13.1,则需要配合 Semi 提供的编译插件 `@douyinfe/semi-next` 插件使用 | ||
| - 首先安装插件 `npm i @douyinfe/semi-next` (如果你使用 yarn 或 pnpm,请自行更换为对等命令) | ||
| - 在 next.config.js 中进行配置,插件会将组件默认的import CSS 语句移除。更多配置可查阅 `@douyinfe/semi-next`[详细文档](https://www.npmjs.com/package/@douyinfe/semi-next) | ||
|
|
@@ -83,56 +89,77 @@ module.exports = semi({ | |
|
|
||
| ## 4、在 Remix 中使用 | ||
| <Notice> | ||
| 注意:以下配置适用于 Remix v1。Remix v2有多种构建模式,Semi 未进行过完整适配性测试,建议优先参考 <a href="https://github.com/DouyinFE/semi-design/issues/2444" target="_blank">Issue 2444</a> 处理 | ||
| 注意:以下配置适用于 Remix v2 + Vite构建模式。 | ||
| </Notice> | ||
|
|
||
| - @remix相关包版本要求 > 1.11.0,并安装 `@remix-run/css-bundle` | ||
| - 配置 `remix.config.js`,参考 [Remix Css Side-Effect Imports](https://remix.run/docs/en/v1/guides/styling#css-side-effect-imports)。打开 `unstable_cssSideEffectImports` 开关,并将 Semi 相关包配置在 `serverDependenciesToBundle` 中。 | ||
| - 如果使用默认主题,参考如下vite配置 | ||
| ```diff | ||
| // remix.config.js | ||
| module.exports = { | ||
| future: { | ||
| + unstable_cssSideEffectImports: true, | ||
| // vite.config.ts | ||
| import { vitePlugin as remix } from "@remix-run/dev"; | ||
| import { defineConfig } from "vite"; | ||
| import tsconfigPaths from "vite-tsconfig-paths"; | ||
| import path from 'path'; | ||
|
|
||
| export default defineConfig({ | ||
| resolve: { | ||
| alias: { | ||
| + "date-fns-tz": path.resolve( | ||
| + __dirname, | ||
| + "node_modules/date-fns-tz/esm/index.js" | ||
| + ), | ||
| }, | ||
| }, | ||
| ssr: { | ||
| noExternal: [ | ||
| + "@douyinfe/semi-ui", | ||
| + "@douyinfe/semi-foundation", | ||
| + "@douyinfe/semi-illustrations", | ||
| + "@douyinfe/semi-icons", | ||
| + "scroll-into-view-if-needed", | ||
| ], | ||
| }, | ||
| serverDependenciesToBundle: [ | ||
| + /^@douyinfe\/semi-ui/, | ||
| + /^@douyinfe\/semi-icons/, | ||
| + /^@douyinfe\/semi-illustrations/, | ||
| plugins: [ | ||
| remix({ | ||
| + future: { | ||
| + v3_fetcherPersist: true, | ||
| + v3_relativeSplatPath: true, | ||
| + v3_throwAbortReason: true, | ||
| + }, | ||
| }), | ||
| tsconfigPaths(), | ||
| ], | ||
| }; | ||
| ``` | ||
| - 在 `root.tsx` 中进行配置,参考[Remix CSS Bundling](https://remix.run/docs/en/v1/guides/styling#css-bundling)。引入 `cssBundleHref`,并配置 `links` | ||
|
|
||
| ```diff | ||
| // root.tsx | ||
| + import { cssBundleHref } from "@remix-run/css-bundle"; | ||
|
|
||
| export const links = () => { | ||
| return [ | ||
| + ...(cssBundleHref ? [{ rel: "stylesheet", href: cssBundleHref }] : []), | ||
| ]; | ||
| }; | ||
| }); | ||
| ``` | ||
|
|
||
| - 完成配置,可以正常使用 Semi 相关组件 | ||
|
|
||
| **如何在 Remix 中使用主题包** | ||
| 可以直接将 cssBundleHref 这一步替换为引入主题包中已构建好的全量css 产物,代替默认主题css),例如当希望应用抖音创作服务平台的主题包 `@semi-bot/semi-theme-doucreator` 时 | ||
| - 首先安装插件 npm i vite-plugin-semi (如果你使用 yarn 或 pnpm,请自行更换为对等命令) | ||
| - 在 vite.config.js 中进行配置 | ||
|
|
||
| ```diff | ||
| // root.tsx | ||
| + import ThemeStyle from "@semi-bot/semi-theme-doucreator/semi.min.css"; | ||
|
|
||
| export const links = () => { | ||
| return [ | ||
| - ...(cssBundleHref ? [{ rel: "stylesheet", href: cssBundleHref }] : []), | ||
| + { rel: "stylesheet", href: ThemeStyle }, | ||
| ]; | ||
| }; | ||
| /* vite.config.ts */ | ||
| + import semi from "vite-plugin-semi-theme"; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 这里的导入是否需要修改为新增加的vite 插件? |
||
| export default defineConfig({ | ||
|
|
||
| plugins: [ | ||
| + semi({ | ||
| + theme: '@semi-bot/semi-theme-jianying', | ||
| + }), | ||
| ], | ||
| }); | ||
| ``` | ||
| - 在 root.tsx中引入主题包 | ||
| ```diff | ||
| // root.tsx | ||
| + import ThemeStyle from "@semi-bot/semi-theme-jianying/semi.min.css?url"; | ||
|
|
||
|
|
||
|
|
||
| export const links: LinksFunction = () => [ | ||
| { | ||
| + rel: "stylesheet", | ||
| + href: ThemeStyle, | ||
| }, | ||
| ]; | ||
| ``` | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 如果已经通过插件处理了,为啥这里有需要引入全量的 css,semi.min.css ? |
||
| ## 5、UMD 方式使用组件 | ||
|
|
||
| [![BUILD-JS][build-js-badge]][build-js-url] [![BUILD-CSS][build-css-badge]][build-css-url] | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,98 @@ | ||
| module.exports = function (babel) { | ||
| const { types: t } = babel; | ||
|
|
||
| return { | ||
| visitor: { | ||
| ImportDeclaration(path, state) { | ||
| // 只处理 lottie-web 的导入 | ||
| if (path.node.source.value === 'lottie-web') { | ||
| const isESM = state.opts.isESM; | ||
|
|
||
| // 创建变量声明 | ||
| const varDeclaration = t.variableDeclaration('var', [ | ||
| t.variableDeclarator( | ||
| t.identifier('lottie'), | ||
| t.identifier('undefined') | ||
| ) | ||
| ]); | ||
|
|
||
| if (isESM) { | ||
| // 创建 IIFE async 函数 | ||
| const iife = t.expressionStatement( | ||
| t.callExpression( | ||
| t.arrowFunctionExpression( | ||
| [], | ||
| t.blockStatement([ | ||
| t.ifStatement( | ||
| t.binaryExpression( | ||
| '!==', | ||
| t.unaryExpression('typeof', t.identifier('document')), | ||
| t.stringLiteral('undefined') | ||
| ), | ||
| t.blockStatement([ | ||
| t.expressionStatement( | ||
| t.assignmentExpression( | ||
| '=', | ||
| t.identifier('lottie'), | ||
| t.awaitExpression( | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 异步导入,可能会导致使用的时候,lottie 还没有存在
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 用项目测试了下,应为不存在所以导致 Lottie 没有渲染 |
||
| t.callExpression( | ||
| t.import(), | ||
| [t.stringLiteral('lottie-web')] | ||
| ) | ||
| ) | ||
| ) | ||
| ) | ||
| ]) | ||
| ) | ||
| ]), | ||
| true // async | ||
| ), | ||
| [] | ||
| ) | ||
| ); | ||
|
|
||
| path.insertBefore(varDeclaration); | ||
| path.replaceWith(iife); | ||
| } else { | ||
| // 原有的 CommonJS 逻辑 | ||
| const ifStatement = t.ifStatement( | ||
| t.binaryExpression( | ||
| '!==', | ||
| t.unaryExpression('typeof', t.identifier('document')), | ||
| t.stringLiteral('undefined') | ||
| ), | ||
| t.blockStatement([ | ||
| t.expressionStatement( | ||
| t.assignmentExpression( | ||
| '=', | ||
| t.identifier('lottie'), | ||
| t.callExpression(t.identifier('require'), [ | ||
| t.stringLiteral('lottie-web') | ||
| ]) | ||
| ) | ||
| ), | ||
| t.ifStatement( | ||
| t.logicalExpression( | ||
| '&&', | ||
| t.identifier('lottie'), | ||
| t.memberExpression(t.identifier('lottie'), t.identifier('__esModule')) | ||
| ), | ||
| t.expressionStatement( | ||
| t.assignmentExpression( | ||
| '=', | ||
| t.identifier('lottie'), | ||
| t.memberExpression(t.identifier('lottie'), t.identifier('default')) | ||
| ) | ||
| ) | ||
| ) | ||
| ]) | ||
| ); | ||
|
|
||
| path.insertBefore(varDeclaration); | ||
| path.replaceWith(ifStatement); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| }; | ||
| }; | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这里安装的名称和后面示例中的名称对不上