Skip to content

Commit 5c6deea

Browse files
authored
feat: support tailwind css (#1605)
1 parent de6da70 commit 5c6deea

File tree

25 files changed

+558
-185
lines changed

25 files changed

+558
-185
lines changed

designer-demo/engine.config.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,7 @@ export default {
33
theme: 'light',
44
material: ['/mock/bundle.json'],
55
scripts: [],
6-
styles: []
6+
styles: [],
7+
// 是否开启 TailWindCSS 特性
8+
enableTailwindCSS: true
79
}

designer-demo/src/preview.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
*
1111
*/
1212
import { defineEntry } from '@opentiny/tiny-engine-meta-register'
13+
import engineConfig from '../engine.config'
1314
import 'virtual:svg-icons-register'
1415

1516
async function startApp() {
@@ -23,9 +24,7 @@ async function startApp() {
2324
const registry = {
2425
[META_SERVICE.Http]: HttpService,
2526
'engine.config': {
26-
id: 'engine.config',
27-
theme: 'light',
28-
material: ['/mock/bundle.json']
27+
...engineConfig
2928
}
3029
}
3130

docs/extension-capabilities-overview/new-registry.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,47 @@ export default {
271271
更多高级特性,请参考 [注册表高级配置](./new-registry-advanced.md)。
272272
273273
274+
## Tailwind CSS 支持
275+
276+
TinyEngine 自 v2.9 起支持在注册表中通过 `engine.config.enableTailwindCSS` 开关启用 Tailwind CSS(默认开启)。
277+
278+
### 开关配置
279+
280+
```javascript
281+
// registry.js
282+
export default {
283+
'engine.config': {
284+
// ...其他配置
285+
enableTailwindCSS: true // 开启(默认即为 true);设为 false 可关闭
286+
}
287+
}
288+
```
289+
290+
### 启用后的行为
291+
292+
- 预览态:自动按需加载 `@tailwindcss/browser`,使画布/预览中可直接使用 Tailwind 原子类。
293+
- 出码生成:生成的应用将自动完成以下配置(基于 Tailwind CSS v4 零配置方案):
294+
- 在依赖中添加 `tailwindcss`,并在开发依赖中添加 `@tailwindcss/vite`
295+
- 在 Vite 配置中注册 `tailwindcss()` 插件;
296+
- 生成 `src/style.css`,内容包含 `@import "tailwindcss";`
297+
- 在 `src/main.js` 自动引入 `./style.css`
298+
299+
以上步骤由引擎/出码器自动完成,无需手动干预。
300+
301+
### 关闭 Tailwind
302+
303+
当配置为 `enableTailwindCSS: false` 时:
304+
305+
- 预览态不会加载 `@tailwindcss/browser`
306+
- 出码时不会注入与 Tailwind 相关的依赖、Vite 插件及样式文件导入。
307+
308+
### 注意事项
309+
310+
- 预览依赖解析:内置 import-map 已包含 `@tailwindcss/browser` 映射;如使用自定义 CDN/离线环境,请确保该映射可用。
311+
- 自定义样式:可在生成的 `src/style.css` 中追加自定义样式,或在项目中新增样式文件后自行引入。
312+
- 运行时渲染:如果您自定义了运行时渲染引擎,请确保在运行时渲染中增加对 Tailwind CSS 的支持。
313+
314+
274315
## Vite 配置要求
275316
276317
**重要说明⚠️**:为了使注册表的 tree-shaking 功能正常工作,您需要在 `vite.config.js` 中配置 `registryPath` 参数,指向您的注册表文件路径。

packages/canvas/DesignCanvas/src/DesignCanvas.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,9 @@ export default {
7676
return
7777
}
7878
79-
const { importMap, importStyles } = getImportMapData(deps)
79+
const { importMap, importStyles, importScripts } = getImportMapData(deps)
8080
81-
canvasSrcDoc.value = initCanvas(importMap, importStyles).html
81+
canvasSrcDoc.value = initCanvas(importMap, importStyles, importScripts).html
8282
}
8383
})
8484

packages/canvas/DesignCanvas/src/importMap.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,13 @@ export function getImportMapData(canvasDeps = { scripts: [], styles: [] }) {
9494
}
9595

9696
const importStyles = [...blockRequire.importStyles, ...canvasDeps.styles]
97+
const customEnableTailWindCSS = getMergeMeta('engine.config')?.enableTailwindCSS
98+
const tailwindURL = getImportUrl('@tailwindcss/browser')
99+
const importScripts = customEnableTailWindCSS && tailwindURL ? [tailwindURL] : []
97100

98101
return {
99102
importMap,
100-
importStyles
103+
importStyles,
104+
importScripts
101105
}
102106
}

packages/canvas/canvas.html

Lines changed: 0 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -78,75 +78,6 @@
7878
animation-delay: 2s;
7979
}
8080
html,
81-
body,
82-
object,
83-
iframe,
84-
p,
85-
blockquote,
86-
pre,
87-
abbr,
88-
address,
89-
cite,
90-
code,
91-
del,
92-
dfn,
93-
em,
94-
img,
95-
ins,
96-
kbd,
97-
q,
98-
samp,
99-
small,
100-
strong,
101-
sub,
102-
sup,
103-
var,
104-
b,
105-
i,
106-
dl,
107-
dt,
108-
dd,
109-
ol,
110-
ul,
111-
li,
112-
fieldset,
113-
form,
114-
label,
115-
legend,
116-
table,
117-
caption,
118-
tbody,
119-
tfoot,
120-
thead,
121-
tr,
122-
th,
123-
td,
124-
article,
125-
aside,
126-
canvas,
127-
details,
128-
figcaption,
129-
figure,
130-
footer,
131-
header,
132-
hgroup,
133-
menu,
134-
nav,
135-
section,
136-
summary,
137-
time,
138-
mark,
139-
audio,
140-
video {
141-
margin: 0;
142-
padding: 0;
143-
border: 0;
144-
outline: 0;
145-
font-size: 100%;
146-
background: transparent;
147-
user-select: none;
148-
}
149-
html,
15081
body {
15182
width: 100%;
15283
height: 100%;

packages/canvas/init-canvas/canvas.html

Lines changed: 1 addition & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
77
<!--%IMPORT_MAP%-->
88
<!--%IMPORT_STYLE%-->
9+
<!--%IMPORT_SCRIPT%-->
910
<style type="text/css">
1011
.loading-warp {
1112
display: flex;
@@ -80,77 +81,6 @@
8081
animation-delay: 2s;
8182
}
8283
html,
83-
body,
84-
div,
85-
span,
86-
object,
87-
iframe,
88-
p,
89-
blockquote,
90-
pre,
91-
abbr,
92-
address,
93-
cite,
94-
code,
95-
del,
96-
dfn,
97-
em,
98-
img,
99-
ins,
100-
kbd,
101-
q,
102-
samp,
103-
small,
104-
strong,
105-
sub,
106-
sup,
107-
var,
108-
b,
109-
i,
110-
dl,
111-
dt,
112-
dd,
113-
ol,
114-
ul,
115-
li,
116-
fieldset,
117-
form,
118-
label,
119-
legend,
120-
table,
121-
caption,
122-
tbody,
123-
tfoot,
124-
thead,
125-
tr,
126-
th,
127-
td,
128-
article,
129-
aside,
130-
canvas,
131-
details,
132-
figcaption,
133-
figure,
134-
footer,
135-
header,
136-
hgroup,
137-
menu,
138-
nav,
139-
section,
140-
summary,
141-
time,
142-
mark,
143-
audio,
144-
video {
145-
margin: 0;
146-
padding: 0;
147-
border: 0;
148-
outline: 0;
149-
font-size: 100%;
150-
background: transparent;
151-
user-select: none;
152-
}
153-
html,
15484
body {
15585
width: 100%;
15686
height: 100%;

packages/canvas/init-canvas/init-canvas.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
import canvasScript from './canvas?url&build=canvas'
22
import canvasHtml from './canvas.html?raw'
33

4-
export function initCanvas(importMap = {}, importStyleUrls = []) {
4+
export function initCanvas(importMap = {}, importStyleUrls = [], importScripts = []) {
55
return {
66
html: canvasHtml
77
.replace('<!--%IMPORT_MAP%-->', `<script type="importmap">${JSON.stringify(importMap, null, 2)}</script>`)
88
.replace(
99
'<!--%IMPORT_STYLE%-->',
1010
importStyleUrls.map((styleUrl) => `<link rel="stylesheet" crossorigin="" href="${styleUrl}">`).join('\n')
1111
)
12+
.replace('<!--%IMPORT_SCRIPT%-->', importScripts.map((script) => `<script src="${script}"></script>`).join('\n'))
1213
.replace('<!--%MAIN_SCRIPT%-->', () => {
1314
if (import.meta.env.MODE === 'development') {
1415
return `<script type="module" src="${canvasScript}"></script>`

packages/common/composable/generateCode/index.ts

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,46 @@
1-
import {
2-
generateApp,
3-
parseRequiredBlocks,
4-
genSFCWithDefaultPlugin,
5-
type IAppSchema
6-
} from '@opentiny/tiny-engine-dsl-vue'
1+
import { generateApp, type IAppSchema } from '@opentiny/tiny-engine-dsl-vue'
2+
import * as dslVue from '@opentiny/tiny-engine-dsl-vue'
3+
import { getMergeMeta } from '@opentiny/tiny-engine-meta-register'
74
import defaultPrettierConfig from '../../js/config-files/prettierrc'
85

96
// 应用出码默认配置
107
const defaultOptions = {
118
pluginConfig: {
9+
template: {},
10+
block: {},
11+
page: {},
12+
dataSource: {},
13+
dependencies: {},
14+
globalState: {},
15+
i18n: {},
16+
router: {},
17+
utils: {},
1218
formatCode: {
1319
// 默认格式化配置
1420
...defaultPrettierConfig
15-
}
21+
},
22+
parseSchema: {}
1623
}
1724
}
1825

1926
// 应用出码
2027
const generateAppCode = async (appSchema: IAppSchema, options = {}) => {
21-
const instance = generateApp({ ...defaultOptions, ...options })
28+
const enableTailwindCSS = getMergeMeta('engine.config')?.enableTailwindCSS
29+
const instance = generateApp({
30+
...defaultOptions,
31+
pluginConfig: {
32+
...defaultOptions.pluginConfig,
33+
template: { ...defaultOptions.pluginConfig.template, enableTailwindCSS }
34+
},
35+
...options
36+
})
2237

2338
return instance.generate(appSchema)
2439
}
2540

2641
// 页面出码
42+
const { parseRequiredBlocks, genSFCWithDefaultPlugin } = dslVue as any
43+
2744
const generatePageCode = (...args: any[]) => {
2845
return genSFCWithDefaultPlugin(...args)
2946
}
@@ -53,10 +70,14 @@ const getAllNestedBlocksSchema = async (pageSchema: any, fetchBlockSchemaApi: an
5370
const schemaList = await Promise.allSettled(promiseList)
5471
const extraList: any[] = []
5572

56-
schemaList.forEach((item: { value: any[]; status: string }) => {
57-
const blockItem = item.value?.[0]
73+
schemaList.forEach((item) => {
74+
if (item.status !== 'fulfilled') {
75+
return
76+
}
77+
78+
const blockItem = (item.value as any[])?.[0]
5879

59-
if (item.status !== 'fulfilled' || !blockItem) {
80+
if (!blockItem) {
6081
return
6182
}
6283

packages/common/js/import-map.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
"@opentiny/vue-common": "${VITE_CDN_DOMAIN}/@opentiny/vue-runtime${versionDelimiter}~3.20${fileDelimiter}/dist3/tiny-vue-common.mjs",
1818
"@opentiny/vue-locale": "${VITE_CDN_DOMAIN}/@opentiny/vue-runtime${versionDelimiter}~3.20${fileDelimiter}/dist3/tiny-vue-locale.mjs",
1919
"@opentiny/vue-renderless/": "${VITE_CDN_DOMAIN}/@opentiny/vue-renderless${versionDelimiter}~3.20${fileDelimiter}/",
20-
"echarts": "${VITE_CDN_DOMAIN}/echarts${versionDelimiter}5.4.1${fileDelimiter}/dist/echarts.esm.js"
20+
"echarts": "${VITE_CDN_DOMAIN}/echarts${versionDelimiter}5.4.1${fileDelimiter}/dist/echarts.esm.js",
21+
"@tailwindcss/browser": "${VITE_CDN_DOMAIN}/@tailwindcss/browser${versionDelimiter}^4${fileDelimiter}/dist/index.global.js"
2122
},
2223
"importStyles": {
2324
"@opentiny/vue-theme": "${VITE_CDN_DOMAIN}/@opentiny/vue-theme${versionDelimiter}~3.20${fileDelimiter}/index.css"

0 commit comments

Comments
 (0)