Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 64 additions & 37 deletions content/start/getting-started/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand Down Expand Up @@ -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,请自行更换为对等命令)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里安装的名称和后面示例中的名称对不上

- 在 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";
Copy link
Collaborator

Choose a reason for hiding this comment

The 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,
},
];
```
Copy link
Collaborator

Choose a reason for hiding this comment

The 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]
Expand Down
1 change: 1 addition & 0 deletions packages/semi-foundation/getBabelConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ module.exports = ({ isESM }) => {
],
plugins: [
'lodash',
['./scripts/babel-plugin-lottie.js', { isESM }]
]
};
};
7 changes: 5 additions & 2 deletions packages/semi-foundation/lottie/foundation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,25 +30,28 @@ class LottieFoundation <P = Record<string, any>, S = Record<string, any>> extend
}


static getLottie = ()=>{
static getLottie = () => {
return lottie;
}

init(lifecycle?: any) {
super.init(lifecycle);
if (!lottie) return;
this.animation = lottie.loadAnimation(this._adapter.getLoadParams());
this.getProp("getAnimationInstance")?.(this.animation);
this.getProp("getLottie")?.(LottieFoundation.getLottie());
}

handleParamsUpdate = ()=>{
handleParamsUpdate = () => {
if (!this.animation) return;
this.animation.destroy();
this.animation = lottie.loadAnimation(this._adapter.getLoadParams());
this.getProp("getAnimationInstance")?.(this.animation);
}

destroy() {
super.destroy();
if (!this.animation) return;
this.animation.destroy();
}

Expand Down
98 changes: 98 additions & 0 deletions packages/semi-foundation/scripts/babel-plugin-lottie.js
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(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

异步导入,可能会导致使用的时候,lottie 还没有存在

Copy link
Collaborator

Choose a reason for hiding this comment

The 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);
}
}
}
}
};
};
Loading
Loading