让你的小程序用上原汁原味的 Tailwind/Windi CSS
来自 Digital Creative, 一家位于上海的数字产品调研、设计与开发公司。
了解我们
- [What we do](https://en.digitalcreative.cn/what-we-do/) - [About us](https://en.digitalcreative.cn/about) - [Contact us](https://en.digitalcreative.cn/contact)
推荐阅读 独立文档 以获得更好的阅读体验 ♥️
由于小程序本身不支持由 Tailwind/Windi CSS 产生的选择器名称中包含的一些特殊转义字符(如 \[
\!
\.
等),这使得你在开发小程序时无法使用一些本该在开发 Web 应用时使用的得心应手的灵活语法与 Arbitrary values/Value auto-infer 功能,如 w-[30px]
translate-x-1/2
!bg-[#ff0000]
等。这无疑对我们的开发效率与心智负担带来了不小的影响。
为了突破这一限制,我们开发了这一款插件来帮助你在使用 Tailwind/Windi CSS 开发小程序时仍然保持着与开发 Web 应用高度一致的开发体验,你不再需要关注因为哪些字符串不被支持而不得不换一种写法的问题,而是继续按照 Tailwind/Windi CSS 的官方语法继续编写你的小程序样式,背后的兼容工作则由这款插件静默处理。
此外,本插件还集成了 rpx
值自动转换的功能。该功能可以将 Tailwind/Windi CSS 配置文件中以及源码中我们书写的 rem
与 px
单位的值在最终生成的样式文件中自动转换为 rpx
单位的值。这既可以让开发者复用在 Web 项目中使用的同一份主题配置又可以让小程序继续使用 responsive pixel 带来的特性。
进一步了解本插件的工作原理
[让你的小程序用上原汁原味的 Tailwind/Windi CSS](https://juejin.cn/post/7093809282272985119/)
选择其中一个适合你的小程序类型进行插件安装
npm i @dcasia/mini-program-tailwind-webpack-plugin -D
使用 Webpack 插件
//webpack.base.conf.js
const WindiCSSWebpackPlugin = require("windicss-webpack-plugin");
const MiniProgramTailwindWebpackPlugin = require("@dcasia/mini-program-tailwind-webpack-plugin")
module.exports = {
plugins: [
new WindiCSSWebpackPlugin(),
new MiniProgramTailwindWebpackPlugin({
// options
})
]
}
在项目根目录新建 windi.config.js
配置文件
//windi.config.js
export default {
preflight: false,
prefixer: false,
extract: {
// 将 .mpx 文件纳入范围(其余 Webpack 类小程序根据项目本身的文件后缀酌情设置)
include: ['src/**/*.{css,html,mpx}'],
// 忽略部分文件夹
exclude: ['node_modules', '.git', 'dist']
},
corePlugins: {
// 禁用掉在小程序环境中不可能用到的 plugins
container: false
}
}
此处 Tailwind CSS 配置文件同样适用
参考 Windi CSS 官方文档了解更多细节
[Windi CSS 配置文件兼容规则](https://windicss.org/guide/configuration.html)
// app.mpx
<style src="https://github.com/dcasia/mini-program-tailwind/raw/development/windi.css"></style>
对于其余非 MPX 项目的 Webpack 类小程序,可参考类似的方式在入口文件中引入
windi.css
即可,如:// main.js import 'windi.css'
参考 Windi CSS 官方文档了解更多细节
[引入 Windi CSS 样式文件](https://windicss.org/integrations/webpack.html#include-the-virtual-module)
开始享受在小程序项目中由 Windi CSS 带来的高效开发体验 🎉
名称 | 类型 | 默认 | 描述 |
---|---|---|---|
enableRpx | Boolean | true |
是否开启自动转换至 rpx 单位值的功能 |
designWidth | Number | 350 |
设计稿的像素宽度值,该尺寸会影响 rpx 转换过程中的计算比率 |
utilitiesSettings.spaceBetweenItems | Array<string> |
[] |
使用了 Space Between utilities 的容器中的子组件的名称。默认已包含 view, button, text, image 四个常用组件,所以大部分情况下开发者不需要配置该项。如需新增则可以在数组中添加新的组件名称。 |
utilitiesSettings.divideItems | Array<string> |
[] |
使用了 Divide width utilities 的容器中的子组件的名称。默认已包含 view, button, text, image 四个常用组件,所以大部分情况下开发者不需要配置该项。如需新增则可以在数组中添加新的组件名称。 |
// app.js
import 'windi.css';
开始享受在 Taro 中由 Windi CSS 带来的高效开发体验 🎉
名称 | 类型 | 默认 | 描述 |
---|---|---|---|
enableWindiCSS | Boolean | true |
是否开启插件自带的 Windi CSS |
windiCSSConfigFile | String | 读取项目根目录的配置文件 | 必要时手动设置 Windi CSS 配置文件的路径 |
enableRpx | Boolean | false |
是否开启自动转换至 rpx 单位值的功能(由于 Taro 自带该功能,默认关闭) |
designWidth | Number | 375 |
设计稿的像素宽度值,该尺寸会影响 rpx 转换过程中的计算比率 |
utilitiesSettings.spaceBetweenItems | Array<string> |
[] |
使用了 Space Between utilities 的容器中的子组件的名称。默认已包含 view, button, text, image 四个常用组件,所以大部分情况下开发者不需要配置该项。如需新增则可以在数组中添加新的组件名称。 |
utilitiesSettings.divideItems | Array<string> |
[] |
使用了 Divide width utilities 的容器中的子组件的名称。默认已包含 view, button, text, image 四个常用组件,所以大部分情况下开发者不需要配置该项。如需新增则可以在数组中添加新的组件名称。 |
utilitiesSettings.customComponents | Array<string> |
[] |
对于使用 Uno CSS 作为 Atomic CSS 引擎的开发者需要根据项目情况配置。默认已包含所有小程序自带的组件名称,所以大部分情况下开发者不需要配置该项。如需新增则可以在数组中添加新的组件名称。 |
enableDebugLog | Boolean | false |
是否开启打印本插件的内部运行日志 |
npm i @dcasia/mini-program-tailwind-webpack-plugin -D
在项目根目录新建 vue.config.js
配置文件并使用 Webpack 插件
// vue.config.js
const WindiCSSWebpackPlugin = require("windicss-webpack-plugin");
const MiniProgramTailwindWebpackPlugin = require("@dcasia/mini-program-tailwind-webpack-plugin")
module.exports = {
configureWebpack: {
plugins: [
new WindiCSSWebpackPlugin(),
new MiniProgramTailwindWebpackPlugin({
// options
})
]
}
}
在项目根目录新建 windi.config.js
配置文件
//windi.config.js
export default {
preflight: false,
prefixer: false,
extract: {
// 忽略部分文件夹
exclude: ['node_modules', '.git', 'dist']
},
corePlugins: {
// 禁用掉在小程序环境中不可能用到的 plugins
container: false
}
}
此处 Tailwind CSS 配置文件同样适用
参考 Windi CSS 官方文档了解更多细节
[Windi CSS 配置文件兼容规则](https://windicss.org/guide/configuration.html)
// main.js
import 'windi.css'
开始享受在小程序项目中由 Windi CSS 带来的高效开发体验 🎉
名称 | 类型 | 默认 | 描述 |
---|---|---|---|
enableRpx | Boolean | true |
是否开启自动转换至 rpx 单位值的功能 |
designWidth | Number | 350 |
设计稿的像素宽度值,该尺寸会影响 rpx 转换过程中的计算比率 |
utilitiesSettings.spaceBetweenItems | Array<string> |
[] |
使用了 Space Between utilities 的容器中的子组件的名称。默认已包含 view, button, text, image 四个常用组件,所以大部分情况下开发者不需要配置该项。如需新增则可以在数组中添加新的组件名称。 |
utilitiesSettings.divideItems | Array<string> |
[] |
使用了 Divide width utilities 的容器中的子组件的名称。默认已包含 view, button, text, image 四个常用组件,所以大部分情况下开发者不需要配置该项。如需新增则可以在数组中添加新的组件名称。 |
utilitiesSettings.customComponents | Array<string> |
[] |
对于使用 Uno CSS 作为 Atomic CSS 引擎的开发者需要根据项目情况配置。默认已包含所有小程序自带的组件名称,所以大部分情况下开发者不需要配置该项。如需新增则可以在数组中添加新的组件名称。 |
npm i @dcasia/mini-program-tailwind-webpack-plugin -D
在 vite.config.js
配置文件中使用插件
// vite.config.js
import WindiCSS from 'vite-plugin-windicss';
import MiniProgramTailwind from '@dcasia/mini-program-tailwind-webpack-plugin/rollup';
export default {
plugins: [
WindiCSS(),
MiniProgramTailwind()
]
}
在项目根目录新建 windi.config.js
配置文件
//windi.config.js
export default {
preflight: false,
prefixer: false,
extract: {
// 忽略部分文件夹
exclude: ['node_modules', '.git', 'dist']
},
corePlugins: {
// 禁用掉在小程序环境中不可能用到的 plugins
container: false
}
}
此处 Tailwind CSS 配置文件同样适用
参考 Windi CSS 官方文档了解更多细节
[Windi CSS 配置文件兼容规则](https://windicss.org/guide/configuration.html)
// main.js
import 'virtual:windi.css'
开始享受在小程序项目中由 Windi CSS 带来的高效开发体验 🎉
名称 | 类型 | 默认 | 描述 |
---|---|---|---|
enableRpx | Boolean | true |
是否开启自动转换至 rpx 单位值的功能 |
designWidth | Number | 350 |
设计稿的像素宽度值,该尺寸会影响 rpx 转换过程中的计算比率 |
utilitiesSettings.spaceBetweenItems | Array<string> |
[] |
使用了 Space Between utilities 的容器中的子组件的名称。默认已包含 view, button, text, image 四个常用组件,所以大部分情况下开发者不需要配置该项。如需新增则可以在数组中添加新的组件名称。 |
utilitiesSettings.divideItems | Array<string> |
[] |
使用了 Divide width utilities 的容器中的子组件的名称。默认已包含 view, button, text, image 四个常用组件,所以大部分情况下开发者不需要配置该项。如需新增则可以在数组中添加新的组件名称。 |
utilitiesSettings.customComponents | Array<string> |
[] |
对于使用 Uno CSS 作为 Atomic CSS 引擎的开发者需要根据项目情况配置。默认已包含所有小程序自带的组件名称,所以大部分情况下开发者不需要配置该项。如需新增则可以在数组中添加新的组件名称。 |
我们将本插件的核心功能解耦并打包进了 universal-handler.js
文件中,若你想在自定义的构建工具中集成本插件的核心功能,可以在工作流逻辑中引入 universal-handler
:
const { handleTemplate, handleStyle } = require('@dcasia/mini-program-tailwind-webpack-plugin/universal-handler')
处理 template:
const rawContent = '<view class="w-10 h-[0.5px] text-[#ffffff]"></view>'
const handledTemplate = handleTemplate(rawContent)
处理 style:
const rawContent = '.h-\\[0\\.5px\\] {height: 0.5px;}'
const handledStyle = handleStyle(rawContent, options)
此后你便可以将处理过的字符串返回至工作流原本的流程中来生成最终的文件。
进一步了解自定义实现过程中的实践细节
[小程序集成 Windi CSS 的自定义实现](https://juejin.cn/post/7093809282272985119#heading-5)
名称 | 类型 | 默认 | 描述 |
---|---|---|---|
enableRpx | Boolean | false |
是否开启自动转换至 rpx 单位值的功能 |
designWidth | Number | 350 |
设计稿的像素宽度值,该尺寸会影响 rpx 转换过程中的计算比率 |
utilitiesSettings.spaceBetweenItems | Array<string> |
[] |
使用了 Space Between utilities 的容器中的子组件的名称。默认已包含 view, button, text, image 四个常用组件,所以大部分情况下开发者不需要配置该项。如需新增则可以在数组中添加新的组件名称。 |
utilitiesSettings.divideItems | Array<string> |
[] |
使用了 Divide width utilities 的容器中的子组件的名称。默认已包含 view, button, text, image 四个常用组件,所以大部分情况下开发者不需要配置该项。如需新增则可以在数组中添加新的组件名称。 |
utilitiesSettings.customComponents | Array<string> |
[] |
对于使用 Uno CSS 作为 Atomic CSS 引擎的开发者需要根据项目情况配置。默认已包含所有小程序自带的组件名称,所以大部分情况下开发者不需要配置该项。如需新增则可以在数组中添加新的组件名称。 |
示范操作步骤均以集成 Windi CSS 为例(Windi CSS 的体验更佳且兼容 Tailwind CSS)
进一步了解 Windi CSS
[Windi CSS](https://windicss.org/)
在小程序中为了使组件样式可以被 Tailwind/Windi 的 CSS 产物作用到,我们需要在每一个组件的 JSON 配置文件中设置其样式的作用域 styleIsolation
,否则即使 Tailwind/Windi CSS 工作正常也无法用来开发组件 UI。
Taro 小程序不受该限制影响
{ "component": true, "styleIsolation": "apply-shared" }
相关 issue
[Issue #1](https://github.com/dcasia/wechat-mini-program-tailwind/issues/1)
由于目前微信开发者工具的热重载功能无法监听到样式文件内由 @import
导入的 wxss 文件内容的变动,所以当启用热重载功能开发时,模拟器不会随着你对 Tailwind/Windi CSS 的更改而更新 UI。目前微信官方已知晓该 bug 的存在,在该 bug 修复之前,我们建议你在开发时关闭热重载,用传统的页面自动刷新来预览每一次的 UI 更新。
目前,该问题已在微信开发者工具 1.06.2205231 RC 中被修复。
相关 issue
[Issue #3](https://github.com/dcasia/wechat-mini-program-tailwind/issues/3)
对于原生小程序中外部样式类 externalClasses
的声明,插件仅支持将该 externalClasses
名称声明为 'class'
的做法,不支持其他名称。
Component({
externalClasses: [ 'class' ]
})
相关 issue
[Issue #44](https://github.com/dcasia/mini-program-tailwind/issues/44)
语法 | 不使用本插件 | 使用本插件 |
---|---|---|
Regular: h-10 text-white |
✅ | ✅ |
Arbitrary values/Value infer: t-[25px] bg-[#ffffff] |
❌ | ✅ |
Fraction: translate-x-1/2 w-8.5 |
❌ | ✅ |
Important: !p-1 |
❌ | ✅ |
RGB value infer: text-[rgb(25,25,25)] |
❌ | ✅ |
Space between: space-y-2 space-y-reverse |
❌ | ✅ |
Divide width: divide-x-2 divide-y-reverse |
❌ | ✅ |
Variants: dark:bg-gray-800 |
❌ | ✅ |
Variants groups: hover:(bg-gray-400 font-medium) |
❌ | ✅ |
Responsive: md:p-2 |
❌ | ✅ |
Universal selector: * |
❌ | ✅ |
rpx value transformed from rem and px value |
❌ | ✅ |
>= 4.0.0
>= 3.4.0
>= 2.7.5