@dcasia/mini-program-tailwind-webpack-plugin
Advanced tools
Comparing version 1.3.2 to 1.3.3-beta.1
@@ -1,2 +0,2 @@ | ||
import { FrameworkUsedInTaro } from '../enum'; | ||
import { TaroFramework } from '../enum'; | ||
import { PluginItem } from '@babel/core'; | ||
@@ -9,2 +9,2 @@ export declare function replaceStringLiteralPlugin({ types: t }: { | ||
}): PluginItem; | ||
export declare function collectRawAndModified(rawContent: string, framework: FrameworkUsedInTaro): [string, string][]; | ||
export declare function collectRawAndModified(rawContent: string, framework: TaroFramework): [string, string][]; |
@@ -5,3 +5,3 @@ export declare enum FileType { | ||
} | ||
export declare enum FrameworkUsedInTaro { | ||
export declare enum TaroFramework { | ||
React = "react", | ||
@@ -11,1 +11,11 @@ Vue2 = "vue", | ||
} | ||
export declare enum TaroPlatform { | ||
Wechat = "weapp", | ||
Swan = "swan", | ||
Alipay = "alipay", | ||
TT = "tt", | ||
QQ = "qq", | ||
JD = "jd", | ||
Quick = "quickapp", | ||
H5 = "h5" | ||
} |
import { WindiCssOptions } from '@windicss/config'; | ||
import { FrameworkUsedInTaro } from './enum'; | ||
import { TaroFramework } from './enum'; | ||
export interface Options { | ||
@@ -8,3 +8,3 @@ enableRpx: boolean; | ||
export interface TaroWebpackPluginOptions { | ||
framework: FrameworkUsedInTaro; | ||
framework: TaroFramework; | ||
enableDebugLog: boolean; | ||
@@ -11,0 +11,0 @@ } |
@@ -37,8 +37,19 @@ 'use strict'; | ||
})(FileType || (FileType = {})); | ||
var FrameworkUsedInTaro; | ||
(function (FrameworkUsedInTaro) { | ||
FrameworkUsedInTaro["React"] = "react"; | ||
FrameworkUsedInTaro["Vue2"] = "vue"; | ||
FrameworkUsedInTaro["Vue3"] = "vue3"; | ||
})(FrameworkUsedInTaro || (FrameworkUsedInTaro = {})); | ||
var TaroFramework; | ||
(function (TaroFramework) { | ||
TaroFramework["React"] = "react"; | ||
TaroFramework["Vue2"] = "vue"; | ||
TaroFramework["Vue3"] = "vue3"; | ||
})(TaroFramework || (TaroFramework = {})); | ||
var TaroPlatform; | ||
(function (TaroPlatform) { | ||
TaroPlatform["Wechat"] = "weapp"; | ||
TaroPlatform["Swan"] = "swan"; | ||
TaroPlatform["Alipay"] = "alipay"; | ||
TaroPlatform["TT"] = "tt"; | ||
TaroPlatform["QQ"] = "qq"; | ||
TaroPlatform["JD"] = "jd"; | ||
TaroPlatform["Quick"] = "quickapp"; | ||
TaroPlatform["H5"] = "h5"; | ||
})(TaroPlatform || (TaroPlatform = {})); | ||
@@ -45,0 +56,0 @@ var _a; |
113
dist/taro.js
@@ -65,8 +65,19 @@ 'use strict'; | ||
})(FileType || (FileType = {})); | ||
var FrameworkUsedInTaro; | ||
(function (FrameworkUsedInTaro) { | ||
FrameworkUsedInTaro["React"] = "react"; | ||
FrameworkUsedInTaro["Vue2"] = "vue"; | ||
FrameworkUsedInTaro["Vue3"] = "vue3"; | ||
})(FrameworkUsedInTaro || (FrameworkUsedInTaro = {})); | ||
var TaroFramework; | ||
(function (TaroFramework) { | ||
TaroFramework["React"] = "react"; | ||
TaroFramework["Vue2"] = "vue"; | ||
TaroFramework["Vue3"] = "vue3"; | ||
})(TaroFramework || (TaroFramework = {})); | ||
var TaroPlatform; | ||
(function (TaroPlatform) { | ||
TaroPlatform["Wechat"] = "weapp"; | ||
TaroPlatform["Swan"] = "swan"; | ||
TaroPlatform["Alipay"] = "alipay"; | ||
TaroPlatform["TT"] = "tt"; | ||
TaroPlatform["QQ"] = "qq"; | ||
TaroPlatform["JD"] = "jd"; | ||
TaroPlatform["Quick"] = "quickapp"; | ||
TaroPlatform["H5"] = "h5"; | ||
})(TaroPlatform || (TaroPlatform = {})); | ||
@@ -201,5 +212,5 @@ var _a$2; | ||
var classFieldName = (_a$1 = {}, | ||
_a$1[FrameworkUsedInTaro.React] = ['className'], | ||
_a$1[FrameworkUsedInTaro.Vue2] = ['class', 'staticClass'], | ||
_a$1[FrameworkUsedInTaro.Vue3] = ['class', 'staticClass'], | ||
_a$1[TaroFramework.React] = ['className'], | ||
_a$1[TaroFramework.Vue2] = ['class', 'staticClass'], | ||
_a$1[TaroFramework.Vue3] = ['class', 'staticClass'], | ||
_a$1); | ||
@@ -385,5 +396,5 @@ function logClassFieldsChange(rawContent, newContent) { | ||
var frameworkModuleCharacteristics = (_a = {}, | ||
_a[FrameworkUsedInTaro.React] = ['.jsx', '.tsx'], | ||
_a[FrameworkUsedInTaro.Vue2] = ['type=template'], | ||
_a[FrameworkUsedInTaro.Vue3] = ['type=template'], | ||
_a[TaroFramework.React] = ['.jsx', '.tsx'], | ||
_a[TaroFramework.Vue2] = ['type=template'], | ||
_a[TaroFramework.Vue3] = ['type=template'], | ||
_a); | ||
@@ -393,3 +404,3 @@ var TaroVNodeTailwindWebpackPlugin = /** @class */ (function () { | ||
this.defaultOptions = { | ||
framework: FrameworkUsedInTaro.React, | ||
framework: TaroFramework.React, | ||
enableDebugLog: false | ||
@@ -478,4 +489,9 @@ }; | ||
/** | ||
* Command option from Taro | ||
*/ | ||
var platform = ctx.runOpts.options.platform; | ||
/** | ||
* User configuration from Taro | ||
*/ | ||
// eslint-disable-next-line @typescript-eslint/padding-line-between-statements | ||
var taroConfig = ctx.initialConfig; | ||
@@ -485,3 +501,5 @@ var framework = taroConfig.framework; | ||
var designWidth = taroConfig.designWidth; | ||
// Default configuration | ||
/** | ||
* Default configuration | ||
*/ | ||
var defaultOptions = { | ||
@@ -492,5 +510,7 @@ enableRpx: false, | ||
designWidth: 375, | ||
framework: FrameworkUsedInTaro.React | ||
framework: TaroFramework.React | ||
}; | ||
// Final configuration | ||
/** | ||
* Final configuration | ||
*/ | ||
var finalOptions = __assign(__assign(__assign({}, defaultOptions), { | ||
@@ -507,2 +527,20 @@ designWidth: designWidth, | ||
*/ | ||
var options_1 = { | ||
config: finalOptions.windiCSSConfigFile, | ||
scan: { | ||
dirs: ["./".concat(srcPath)], | ||
fileExtensions: ['vue', 'jsx', 'tsx', 'wxml', 'axml', 'jxml', 'ksml', 'ttml', 'qml'] | ||
}, | ||
onGenerated: function (ctx) { | ||
if (finalOptions.enableDebugLog) { | ||
console.log('\n[Windi CSS]:', 'Detected classes', ctx.classes); | ||
} | ||
} | ||
}; | ||
/** | ||
* Disable preflight when the target compilation platform isn't h5 | ||
*/ | ||
if (platform !== TaroPlatform.H5) { | ||
options_1.preflight = false; | ||
} | ||
chain.merge({ | ||
@@ -512,17 +550,3 @@ plugin: { | ||
plugin: WindiCSSWebpackPlugin__default["default"], | ||
args: [ | ||
{ | ||
config: finalOptions.windiCSSConfigFile, | ||
preflight: false, | ||
scan: { | ||
dirs: ["./".concat(srcPath)], | ||
fileExtensions: ['vue', 'jsx', 'tsx', 'wxml', 'axml', 'jxml', 'ksml', 'ttml', 'qml'] | ||
}, | ||
onGenerated: function (ctx) { | ||
if (finalOptions.enableDebugLog) { | ||
console.log('Windi CSS:', 'Detected classes', ctx.classes); | ||
} | ||
} | ||
}, | ||
] | ||
args: [options_1] | ||
} | ||
@@ -532,14 +556,19 @@ } | ||
} | ||
chain.merge({ | ||
plugin: { | ||
'dc-mini-program-tailwind-webpack-plugin': { | ||
plugin: MiniProgramTailwindWebpackPlugin, | ||
args: [finalOptions] | ||
}, | ||
'dc-taro-v-node-tailwind-webpack-plugin': { | ||
plugin: TaroVNodeTailwindWebpackPlugin, | ||
args: [finalOptions] | ||
/** | ||
* Do not install plugins when the target compilation platform is h5 | ||
*/ | ||
if (platform !== TaroPlatform.H5) { | ||
chain.merge({ | ||
plugin: { | ||
'dc-mini-program-tailwind-webpack-plugin': { | ||
plugin: MiniProgramTailwindWebpackPlugin, | ||
args: [finalOptions] | ||
}, | ||
'dc-taro-v-node-tailwind-webpack-plugin': { | ||
plugin: TaroVNodeTailwindWebpackPlugin, | ||
args: [finalOptions] | ||
} | ||
} | ||
} | ||
}); | ||
}); | ||
} | ||
}); | ||
@@ -546,0 +575,0 @@ }); |
@@ -38,8 +38,19 @@ 'use strict'; | ||
})(FileType || (FileType = {})); | ||
var FrameworkUsedInTaro; | ||
(function (FrameworkUsedInTaro) { | ||
FrameworkUsedInTaro["React"] = "react"; | ||
FrameworkUsedInTaro["Vue2"] = "vue"; | ||
FrameworkUsedInTaro["Vue3"] = "vue3"; | ||
})(FrameworkUsedInTaro || (FrameworkUsedInTaro = {})); | ||
var TaroFramework; | ||
(function (TaroFramework) { | ||
TaroFramework["React"] = "react"; | ||
TaroFramework["Vue2"] = "vue"; | ||
TaroFramework["Vue3"] = "vue3"; | ||
})(TaroFramework || (TaroFramework = {})); | ||
var TaroPlatform; | ||
(function (TaroPlatform) { | ||
TaroPlatform["Wechat"] = "weapp"; | ||
TaroPlatform["Swan"] = "swan"; | ||
TaroPlatform["Alipay"] = "alipay"; | ||
TaroPlatform["TT"] = "tt"; | ||
TaroPlatform["QQ"] = "qq"; | ||
TaroPlatform["JD"] = "jd"; | ||
TaroPlatform["Quick"] = "quickapp"; | ||
TaroPlatform["H5"] = "h5"; | ||
})(TaroPlatform || (TaroPlatform = {})); | ||
@@ -164,5 +175,5 @@ var _a$1; | ||
(_a = {}, | ||
_a[FrameworkUsedInTaro.React] = ['className'], | ||
_a[FrameworkUsedInTaro.Vue2] = ['class', 'staticClass'], | ||
_a[FrameworkUsedInTaro.Vue3] = ['class', 'staticClass'], | ||
_a[TaroFramework.React] = ['className'], | ||
_a[TaroFramework.Vue2] = ['class', 'staticClass'], | ||
_a[TaroFramework.Vue3] = ['class', 'staticClass'], | ||
_a); | ||
@@ -169,0 +180,0 @@ function replaceStringLiteralPlugin(_a) { |
{ | ||
"name": "@dcasia/mini-program-tailwind-webpack-plugin", | ||
"version": "1.3.2", | ||
"version": "1.3.3-beta.1", | ||
"description": "让你的小程序用上原汁原味的 Tailwind/Windi CSS", | ||
@@ -5,0 +5,0 @@ "keywords": ["miniprogram", "mini-program", "tailwindcss", "windicss", "wechat", "taro", "css", "postcss"], |
297
README.md
![wechat-mp-plugin](https://user-images.githubusercontent.com/3030587/158826917-30c79222-b79d-4857-88f9-7e4184d1e771.jpg) | ||
# WeChat Mini program Tailwind/Windi CSS Webpack plugin | ||
# Mini Program Tailwind Webpack Plugin | ||
Build WeChat mini programs using Tailwind & Windi CSS frameworks with this webpack plugin. | ||
让你的小程序用上原汁原味的 Tailwind/Windi CSS | ||
一个可以让你用 Tailwind 或 Windi CSS 开发微信小程序的 Webpack 插件。 | ||
> 来自 [Digital Creative](https://digitalcreative.cn/), 一家位于上海的数字产品调研、设计与开发公司。 | ||
> <details> | ||
> <summary>了解我们</summary> | ||
> | ||
> - [What we do](https://en.digitalcreative.cn/what-we-do/) | ||
> - [About us](https://en.digitalcreative.cn/about) | ||
> - [Contact us](https://en.digitalcreative.cn/contact) | ||
> </details> | ||
Made by [Digital Creative](https://en.digitalcreative.cn/) - Digital product agency, Shanghai. | ||
*推荐阅读 [独立文档](https://www.craft.do/s/Wx2f9cjGwyZYOx) 以获得更好的阅读体验 ♥️* | ||
来自 [Digital Creative](https://digitalcreative.cn/), 一家位于上海的数字产品调研、设计与开发公司。 | ||
--- | ||
- [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 应用时就可以使用的很实用且灵活的语法,如 `w-[30px]`, `translate-x-1/2`, `!bg-[#ff0000]`。 | ||
由于小程序本身不支持由 Tailwind/Windi CSS 产生的选择器名称中包含的一些特殊转义字符(如 `\[` `\!` `\.` 等),这使得你在开发小程序时无法使用一些本该在开发 Web 应用时使用的得心应手的灵活语法与 JIT/Value auto-infer 功能,如 `w-[30px]` `translate-x-1/2` `!bg-[#ff0000]` 等。这无疑对我们的开发效率与心智负担带来了不小的影响。 | ||
为了突破这一限制,我们开发了这一款插件来帮助你在开发小程序时依然保持着与使用 Tailwind/Windi 开发 Web 应用时高度一致的开发体验,你不再需要关注哪些字符串不被支持而不得不换一种写法,而是继续按照 Tailwind/Windi 的官方语法继续编写你的小程序样式,其他工作则由这款插件静默处理。 | ||
为了突破这一限制,我们开发了这一款插件来帮助你在使用 Tailwind/Windi CSS 开发小程序时仍然保持着与开发 Web 应用高度一致的开发体验,你不再需要关注因为哪些字符串不被支持而不得不换一种写法的问题,而是继续**按照 Tailwind/Windi CSS 的官方语法继续编写你的小程序样式**,背后的兼容工作则由这款插件静默处理。 | ||
此外,该插件还集成了 rpx 值自动转换的功能。该功能可以将 Tailwind/Windi 配置文件中以及源码中我们书写的 rem 与 px 单位的值在生成结果中自动转换为 rpx 单位的值。这既可以让开发者重复使用在 Web 项目中同一份团队制定的主题配置文件又可以让小程序享受到 responsive pixel 特性带来的便利。 | ||
此外,本插件还集成了 `rpx` 值自动转换的功能。该功能可以将 Tailwind/Windi CSS 配置文件中以及源码中我们书写的 `rem` 与 `px` 单位的值在最终生成的样式文件中自动转换为 `rpx` 单位的值。这既可以让开发者复用在 Web 项目中使用的同一份主题配置又可以让小程序继续使用 responsive pixel 带来的特性。 | ||
相关文章:[让你的小程序用上原汁原味的 Tailwind/Windi CSS](https://juejin.cn/post/7093809282272985119/) | ||
> <details> | ||
> <summary>进一步了解本插件的工作原理</summary> | ||
> | ||
> [让你的小程序用上原汁原味的 Tailwind/Windi CSS](https://juejin.cn/post/7093809282272985119/) | ||
> </details> | ||
@@ -31,14 +37,36 @@ - - - | ||
**以下示范操作步骤以集成 Windi CSS 为例* | ||
选择其中一个适合你的小程序类型进行插件安装 | ||
### 基于 MPX 框架 | ||
<details> | ||
[MPX](https://mpxjs.cn/), 一款具有优秀开发体验和深度性能优化的增强型跨端小程序框架。 | ||
<summary>⚙️ 针对以 Webpack 为构建工具的小程序</summary> | ||
#### 安装 Windi CSS 与 windicss-webpack-plugin | ||
### Webpack 类小程序(MPX) | ||
依照 Windi CSS [官方文档](https://windicss.org/integrations/webpack.html) 中陈述的步骤进行 | ||
> [MPX](https://mpxjs.cn/), 一款具有优秀开发体验和深度性能优化的增强型跨端小程序框架。 | ||
#### 更新 Windi CSS 配置文件 | ||
MPX 框架为典型的以 Webpack 为构建工具的小程序框架,因此本篇安装示范以 MPX 项目为例。其余 Webpack 类小程序项目参考相同步骤进行安装即可。 | ||
#### 安装 windicss-webpack-plugin | ||
```sh | ||
npm i windicss-webpack-plugin -D | ||
``` | ||
> <details> | ||
> <summary>参考 Windi CSS 官方文档了解更多细节</summary> | ||
> | ||
> [Windi CSS Webpack 集成文档](https://windicss.org/integrations/webpack.html) | ||
> </details> | ||
#### 安装 @dcasia/mini-program-tailwind-webpack-plugin | ||
```sh | ||
npm i @dcasia/mini-program-tailwind-webpack-plugin -D | ||
``` | ||
#### 新建 Windi CSS 配置文件 | ||
在项目根目录新建 Windi CSS 配置文件 | ||
```javascript | ||
@@ -50,3 +78,3 @@ //windi.config.js | ||
extract: { | ||
// 将 .mpx 文件纳入范围 | ||
// 将 .mpx 文件纳入范围(其余 Webpack 类小程序根据项目本身的文件后缀酌情设置) | ||
include: ['src/**/*.{css,html,mpx}'], | ||
@@ -64,9 +92,12 @@ // 忽略部分文件夹 | ||
#### 安装 @dcasia/mini-program-tailwind-webpack-plugin | ||
> 此处 Tailwind CSS 配置文件同样适用 | ||
> <details> | ||
> <summary>参考 Windi CSS 官方文档了解更多细节</summary> | ||
> | ||
> [Windi CSS 配置文件兼容规则](https://windicss.org/guide/configuration.html) | ||
> </details> | ||
```sh | ||
npm i @dcasia/mini-program-tailwind-webpack-plugin --save-dev | ||
``` | ||
#### 更新 webpack 配置文件 | ||
#### 更新 MPX 项目中的 webpack 配置文件 | ||
使用 Webpack 插件 | ||
@@ -83,4 +114,3 @@ ```javascript | ||
new MiniProgramTailwindWebpackPlugin({ | ||
enableRpx: true, | ||
designWidth: 350 | ||
// options | ||
}) | ||
@@ -96,2 +126,4 @@ ] | ||
``` | ||
> 对于其余 Webpack 类小程序,可参考类似的方式在入口的样式文件中引入 `windi-utilities.wxss` 即可 | ||
@@ -101,27 +133,131 @@ #### 完成 | ||
#### 可配置参数 | ||
| **名称** | **类型** | **默认** | **描述** | | ||
| ----------- | ------- | ------ | ------------------------------- | | ||
| enableRpx | Boolean | true | 是否开启自动转换至 rpx 单位值的功能 | | ||
| designWidth | Number | 350 | 设计稿的像素宽度值,该尺寸会影响 rpx 转换过程中的计算比率 | | ||
#### 案例 | ||
[MPX 集成案例](./examples/mpx) | ||
> [集成案例:MPX 项目](./examples/mpx) | ||
</details> | ||
### 基于原生小程序 | ||
<details> | ||
基于原生小程序的开发模式来集成这款插件,过程通常因每个团队的工作流不同而异。有的团队会有内部定制的一套 Webpack 或 Gulp 工作流,而有的团队甚至不会借助任何文件打包或处理的工作流去编写小程序。 | ||
<summary>👽 针对 Taro 小程序</summary> | ||
但这里需要明确的一点是,若要想在以原生开发模式的基础之上去增加文件处理的功能,我们必须去额外的启动一套文件监听处理服务,这个服务通常由自定义配置好的 Webpack, Gulp 等第三方工具完成。 | ||
### Taro 小程序 | ||
为了使这款插件具备超出 Webpack 适配范围之外尽可能大的兼容性,我们将核心功能分离并打包进了 `dist/universal-handler.js` 文件中,若你想在自己的工作流中使用该插件的核心功能,可以先在工作流逻辑中引入 `universal-handler`: | ||
> [Taro](https://taro.jd.com/), 多端统一开发解决方案 | ||
本插件包含 Taro 插件,通过“一键安装”的方式来适配 Taro 小程序 | ||
> Taro 插件已兼容以下前端框架 | ||
> - React | ||
> - Vue 2 | ||
> - Vue 3 | ||
#### 安装 @dcasia/mini-program-tailwind-webpack-plugin | ||
```other | ||
npm i @dcasia/mini-program-tailwind-webpack-plugin -D | ||
``` | ||
#### 使用 Taro 插件 | ||
```javascript | ||
const { handleSource } = require('@dcasia/mini-program-tailwind-webpack-plugin/dist/universal-handler') | ||
// config/index.js | ||
const config = { | ||
plugins: [ | ||
['@dcasia/mini-program-tailwind-webpack-plugin/dist/taro', { | ||
// ...options | ||
}] | ||
] | ||
} | ||
``` | ||
随后处理 template: | ||
#### 新建 Windi CSS 配置文件 | ||
在项目根目录新建 Windi CSS 配置文件 | ||
```javascript | ||
const template = '<view class="w-10 h-[0.5px] text-[#ffffff]"></view>' | ||
const handledTemplate = handleSource('template', template, options) | ||
// windi.config.js | ||
export default { | ||
prefixer: false, | ||
extract: { | ||
// 忽略部分文件夹 | ||
exclude: ['node_modules', '.git', 'dist'] | ||
}, | ||
corePlugins: { | ||
// 禁用掉在小程序环境中不可能用到的 plugins | ||
container: false | ||
} | ||
} | ||
``` | ||
> 此处 Tailwind CSS 配置文件同样适用 | ||
> <details> | ||
> <summary>参考 Windi CSS 官方文档了解更多细节</summary> | ||
> | ||
> [Windi CSS 配置文件兼容规则](https://windicss.org/guide/configuration.html) | ||
> </details> | ||
#### 在 app.js/app.ts 中引入 Windi CSS 的产物 | ||
```javascript | ||
// app.js/app.ts | ||
import 'windi.css'; | ||
``` | ||
#### 完成 | ||
开始享受在 Taro 中由 Windi CSS 带来的高效开发体验 🎉 | ||
#### 可配置参数 | ||
| **名称** | **类型** | **默认** | **描述** | | ||
| ------------------ | ------- | ------------ | ---------------------------------------- | | ||
| enableWindiCSS | Boolean | true | 是否开启插件自带的 Windi CSS | | ||
| windiCSSConfigFile | String | 读取项目根目录的配置文件 | 必要时手动设置 Windi CSS 配置文件的路径 | | ||
| enableRpx | Boolean | false | 是否开启自动转换至 rpx 单位值的功能(由于 Taro 自带该功能,默认关闭) | | ||
| designWidth | Number | 375 | 设计稿的像素宽度值,该尺寸会影响 rpx 转换过程中的计算比率 | | ||
| enableDebugLog | Boolean | false | 是否开启打印本插件的内部运行日志 | | ||
#### 案例 | ||
> 待更新... | ||
</details> | ||
<details> | ||
<summary>🛠 针对原生开发或自定义构建的小程序</summary> | ||
### 原生开发或自定义构建工具的小程序 | ||
无论你的项目基于什么 bundler 或 workflow 工具进行开发,只要有一个可编程的文件监听与处理服务便可以进行自定义实现。但这里需要明确的一点是,**若想在以原生开发模式的基础之上去集成本插件的功能,则一定需要我们去启动一套可编程的文件监听处理服务作为插件的运行基础**,这个服务通常由配置好的 Webpack, Gulp 等第三方工具完成。 | ||
> <details> | ||
> <summary>使用 Tailwind/Windi CSS CLI 的开发者请看</summary> | ||
> | ||
> 如果你是通过 Tailwind/Windi CSS 官方的 CLI 进行小程序 UI 开发,遗憾的是由于该 CLI 不支持插件机制而且不可能支持对于模板文件的修改,所以我们无法在此基础之上以自定义的方式集成本插件。 | ||
> </details> | ||
我们将本插件的核心功能解耦并打包进了 `universal-handler.js` 文件中,若你想在自定义的构建工具中集成本插件的核心功能,可以在工作流逻辑中引入 `universal-handler`: | ||
```javascript | ||
const { handleSource } = require('@dcasia/mini-program-tailwind-webpack-plugin/universal-handler') | ||
``` | ||
处理 template: | ||
```javascript | ||
const rawContent = '<view class="w-10 h-[0.5px] text-[#ffffff]"></view>' | ||
const handledTemplate = handleSource('template', rawContent, options) // 'template' 为常量,设置文件类型为模板文件 | ||
``` | ||
处理 style: | ||
```javascript | ||
const style = '.h-\\[0\\.5px\\] {height: 0.5px;}' | ||
const handledStyle = handleSource('style', style, options) | ||
const rawContent = '.h-\\[0\\.5px\\] {height: 0.5px;}' | ||
const handledStyle = handleSource('style', rawContent, options) // 'style' 为常量,设置文件类型为样式文件 | ||
``` | ||
@@ -131,15 +267,27 @@ | ||
> 对于集成过程中涉及到其他方面的细节可参考[小程序集成 Windi CSS 的自定义实现](https://juejin.cn/post/7093809282272985119#heading-5) | ||
> <details> | ||
> <summary>进一步了解自定义实现过程中的实践细节</summary> | ||
> | ||
> [小程序集成 Windi CSS 的自定义实现](https://juejin.cn/post/7093809282272985119#heading-5) | ||
> </details> | ||
#### 可配置参数 | ||
| **名称** | **类型** | **默认** | **描述** | | ||
| ----------- | ------- | ------ | ------------------------------- | | ||
| enableRpx | Boolean | false | 是否开启自动转换至 rpx 单位值的功能 | | ||
| designWidth | Number | 350 | 设计稿的像素宽度值,该尺寸会影响 rpx 转换过程中的计算比率 | | ||
#### 案例 | ||
[原生小程序集成案例(基于 Gulp)](./examples/native) | ||
> [集成案例:基于 Gulp 进行自定义实现](./examples/native) | ||
- - - | ||
## 可配置参数 | ||
</details> | ||
| Name | Type | Default | Description | | ||
| ----------- | ------- | ------- | --------------------------------------------------------- | | ||
| enableRpx | Boolean | true | 是否开启自动转换至 rpx 单位值的功能 | | ||
| designWidth | Number | 350 | 设计稿的像素宽度值,该尺寸会影响 rpx 转换过程中的计算比率 | | ||
> 示范操作步骤均以集成 Windi CSS 为例(Windi CSS 的体验更佳且兼容 Tailwind CSS) | ||
> <details> | ||
> <summary>进一步了解 Windi CSS</summary> | ||
> | ||
> [Windi CSS](https://windicss.org/) | ||
> </details> | ||
@@ -149,3 +297,3 @@ - - - | ||
## 陷阱 | ||
- 在小程序中为了使组件样式可以被 Tailwind/Windi 的 CSS 产物作用到,我们需要在每一个组件的 JSON 配置文件中设置其[样式的作用域](https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/wxml-wxss.html#%E7%BB%84%E4%BB%B6%E6%A0%B7%E5%BC%8F%E9%9A%94%E7%A6%BB) `styleIsolation`,否则即使 Tailwind/Windi CSS 工作正常也无法用来开发组件 UI。([Issue#1](https://github.com/dcasia/wechat-mini-program-tailwind/issues/1)) | ||
- 在小程序中为了使组件样式可以被 Tailwind/Windi 的 CSS 产物作用到,我们需要在每一个组件的 JSON 配置文件中设置其[样式的作用域](https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/wxml-wxss.html#%E7%BB%84%E4%BB%B6%E6%A0%B7%E5%BC%8F%E9%9A%94%E7%A6%BB) `styleIsolation`,否则即使 Tailwind/Windi CSS 工作正常也无法用来开发组件 UI。 | ||
```json | ||
@@ -157,34 +305,30 @@ { | ||
``` | ||
- 由于目前微信开发者工具的热重载功能无法监听到样式文件内由 `@import` 导入的 wxss 文件内容的变动,所以当启用热重载功能开发时,模拟器不会随着你对 Tailwind/Windi CSS 的更改而更新 UI。目前微信官方已知晓该 bug 的存在,在该 bug 修复之前,我们建议你在开发时关闭热重载,用传统的页面自动刷新来预览每一次的 UI 更新。([Issue#3](https://github.com/dcasia/wechat-mini-program-tailwind/issues/3)) | ||
> <details> | ||
> <summary>相关 issue</summary> | ||
> | ||
> [Issue #1](https://github.com/dcasia/wechat-mini-program-tailwind/issues/1) | ||
> </details> | ||
- - - | ||
- 由于目前微信开发者工具的热重载功能无法监听到样式文件内由 `@import` 导入的 wxss 文件内容的变动,所以当启用热重载功能开发时,模拟器不会随着你对 Tailwind/Windi CSS 的更改而更新 UI。目前微信官方已知晓该 bug 的存在,在该 bug 修复之前,我们建议你在开发时关闭热重载,用传统的页面自动刷新来预览每一次的 UI 更新。 | ||
> <details> | ||
> <summary>相关 issue</summary> | ||
> | ||
> [Issue #3](https://github.com/dcasia/wechat-mini-program-tailwind/issues/3) | ||
> </details> | ||
## FAQ | ||
1. Can't tailwind/windi be compatible with WeChat mini programs? What are the restrictions there? | ||
Naturally it can only be compatible in certain degree, for instance it can still analyze all class names you used in template and style files and pick up what has been used and pack them into a singe style file, which is nice as always. However, the restrictions are that you can't use much flexible and advanced feature, such as value auto-infer `mt-[5px]` , fractions value `translate-x-1/2`, `h-1.5` and color value `bg-[#ffffff]` etc, so your productivity would be drastically decreased. | ||
2. Why are WeChat mini programs so special when it comes to tailwind/windi? | ||
Well in terms of the business, there is no doubt that WeChat mini programs creates incredible influence in the China market but technically speaking the way it provides for developers to build is conservative and restrictive and out of sync with international technical community. For instance the CSS selector in mini program couldn't support `*` `:hover` etc and also any escaped selector names `\[` `\]` `\!` `\.` etc which are the critical elements that tailwind/windi uses to generate class names. | ||
3. How does this plugin make tailwind/windi compatible with mini program? | ||
Behind the scene it silently replace all unsupported selector names in mini program when you are developing or building your project by leveraging the ability of Webpack, Postcss, WXML parser and Babel etc. | ||
- - - | ||
## Comparison | ||
## 功能对比 | ||
| Features | Naturally | With the plugin | | ||
|-------------------------------------------------------|:---------:|:---------------:| | ||
| Regular: h-10, text-white | ✅ | ✅ | | ||
| Responsive: md:p-2 | ❌ | ✅ | | ||
| Important: !p-1 | ❌ | ✅ | | ||
| Variants: dark:bg-gray-800 | ❌ | ✅ | | ||
| Variants groups: hover:(bg-gray-400 font-medium) | ❌ | ✅ | | ||
| Fraction: translate-x-1/2, w-8.5 | ❌ | ✅ | | ||
| Value infer: t-[25px], bg-[#ffffff] | ❌ | ✅ | | ||
| RGB value infer: text-[rgb(25,25,25)] | ❌ | ✅ | | ||
| Responsive pixel auto conversion from rem and px unit | ❌ | ✅ | | ||
| **语法** | **不使用本插件** | **使用本插件** | | ||
| ------------------------------------------------------ | ---------- | --------- | | ||
| **Regular**: `h-10` `text-white` | ✅ | ✅ | | ||
| **JIT/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)]` | ❌ | ✅ | | ||
| **Variants**: `dark:bg-gray-800` | ❌ | ✅ | | ||
| **Variants groups**: `hover:(bg-gray-400 font-medium)` | ❌ | ✅ | | ||
| **Responsive**: `md:p-2` | ❌ | ✅ | | ||
| `rpx` value transformed from `rem` and `px` value | ❌ | ✅ | | ||
@@ -194,5 +338,6 @@ - - - | ||
- Webpack >= 5.0.0 | ||
- Webpack >= 4.0.0 | ||
- Taro >= 3.0 | ||
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
55775
1008
334
1