vite-plugin-uni-tailwind-processor 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,57 @@
1
+ import { Plugin } from 'vite';
2
+ import { WatchOptions } from 'chokidar';
3
+
4
+ /**
5
+ * 调用插件传入的配置
6
+ */
7
+ interface IUniTailwind extends IWatcherOptions {
8
+ projectPath: string;
9
+ inputPath: string;
10
+ outputPath: string;
11
+ }
12
+ /**
13
+ * 生成tailwindcss参数
14
+ */
15
+ interface IGenerateTailwindOptions {
16
+ tailwindCssPath: string;
17
+ }
18
+ /**
19
+ * 清理css配置项
20
+ */
21
+ interface ICleanCSSOptions {
22
+ disposeCssPath: string;
23
+ scriptPath: string;
24
+ }
25
+ /**
26
+ * 监听配置项
27
+ */
28
+ interface IWatcherOptions extends WatchOptions {
29
+ watcherPaths: string[];
30
+ }
31
+ /**
32
+ * 适配策略
33
+ */
34
+ interface IUniTailwindStrategy {
35
+ options: IUniTailwind;
36
+ /**
37
+ * 生成 tailwindcss 的规则类名,
38
+ * @param options
39
+ * @returns 成功或失败
40
+ */
41
+ generateTailwindCss: (options: IGenerateTailwindOptions) => Promise<boolean>;
42
+ /**
43
+ * 清除小程序不识别的 css 样式
44
+ * @param options
45
+ * @returns 成功或失败
46
+ */
47
+ cleanCss: (options: ICleanCSSOptions) => Promise<boolean>;
48
+ /**
49
+ * 判断一个路径是否为输入路径
50
+ * @param path
51
+ */
52
+ isInputPath(path: string): boolean;
53
+ }
54
+
55
+ declare function viteUniTailwindProcessor(options: IUniTailwind, strategy?: new (options: IUniTailwind) => IUniTailwindStrategy): Plugin;
56
+
57
+ export { viteUniTailwindProcessor as default };
@@ -0,0 +1,57 @@
1
+ import { Plugin } from 'vite';
2
+ import { WatchOptions } from 'chokidar';
3
+
4
+ /**
5
+ * 调用插件传入的配置
6
+ */
7
+ interface IUniTailwind extends IWatcherOptions {
8
+ projectPath: string;
9
+ inputPath: string;
10
+ outputPath: string;
11
+ }
12
+ /**
13
+ * 生成tailwindcss参数
14
+ */
15
+ interface IGenerateTailwindOptions {
16
+ tailwindCssPath: string;
17
+ }
18
+ /**
19
+ * 清理css配置项
20
+ */
21
+ interface ICleanCSSOptions {
22
+ disposeCssPath: string;
23
+ scriptPath: string;
24
+ }
25
+ /**
26
+ * 监听配置项
27
+ */
28
+ interface IWatcherOptions extends WatchOptions {
29
+ watcherPaths: string[];
30
+ }
31
+ /**
32
+ * 适配策略
33
+ */
34
+ interface IUniTailwindStrategy {
35
+ options: IUniTailwind;
36
+ /**
37
+ * 生成 tailwindcss 的规则类名,
38
+ * @param options
39
+ * @returns 成功或失败
40
+ */
41
+ generateTailwindCss: (options: IGenerateTailwindOptions) => Promise<boolean>;
42
+ /**
43
+ * 清除小程序不识别的 css 样式
44
+ * @param options
45
+ * @returns 成功或失败
46
+ */
47
+ cleanCss: (options: ICleanCSSOptions) => Promise<boolean>;
48
+ /**
49
+ * 判断一个路径是否为输入路径
50
+ * @param path
51
+ */
52
+ isInputPath(path: string): boolean;
53
+ }
54
+
55
+ declare function viteUniTailwindProcessor(options: IUniTailwind, strategy?: new (options: IUniTailwind) => IUniTailwindStrategy): Plugin;
56
+
57
+ export { viteUniTailwindProcessor as default };
package/dist/index.js ADDED
@@ -0,0 +1,244 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ default: () => viteUniTailwindProcessor
34
+ });
35
+ module.exports = __toCommonJS(index_exports);
36
+
37
+ // src/strategys/BaseStrategyAbstract.ts
38
+ var import_child_process = require("child_process");
39
+ var BaseStrategyAbstract = class {
40
+ /**
41
+ *
42
+ * @param options 初始化
43
+ */
44
+ constructor(options) {
45
+ this.options = options;
46
+ }
47
+ isInputPath(filePath) {
48
+ return this.options.inputPath === filePath || filePath.startsWith(this.options.inputPath);
49
+ }
50
+ /**
51
+ * 执行cmd指令
52
+ * @param command 指令
53
+ * @param args 参数
54
+ * @param options 配置项
55
+ */
56
+ runCmd(command, args, options) {
57
+ return new Promise((resolve, reject) => {
58
+ const subProcess = (0, import_child_process.spawn)(command, args, {
59
+ cwd: this.options.projectPath,
60
+ shell: true,
61
+ stdio: "inherit",
62
+ ...options
63
+ });
64
+ subProcess.on("error", (err) => {
65
+ reject(new Error(`\u8FDB\u7A0B\u542F\u52A8\u5931\u8D25\uFF1A${err.message}`));
66
+ });
67
+ if (args.includes("--watch")) {
68
+ subProcess.stderr?.on("data", () => {
69
+ resolve(true);
70
+ });
71
+ } else {
72
+ subProcess.on("close", (code) => {
73
+ if (code === 0) {
74
+ resolve(true);
75
+ } else {
76
+ reject(new Error(`\u547D\u4EE4\u6267\u884C\u5931\u8D25\uFF0C\u9000\u51FA\u7801\uFF1A${code}`));
77
+ }
78
+ });
79
+ }
80
+ });
81
+ }
82
+ };
83
+
84
+ // src/strategys/DefaultStrategy.ts
85
+ var import_path = __toESM(require("path"));
86
+ var import_promises = __toESM(require("fs/promises"));
87
+ var DefaultStrategy = class extends BaseStrategyAbstract {
88
+ constructor(options) {
89
+ super(options);
90
+ this.options = options;
91
+ }
92
+ generateTailwindCss(options) {
93
+ import_promises.default.writeFile(this.options.outputPath, "");
94
+ return this.runCmd(
95
+ "npx",
96
+ [
97
+ "tailwindcss",
98
+ "-i",
99
+ this.options.inputPath,
100
+ "-o",
101
+ options.tailwindCssPath,
102
+ "--optimize-for-compatibility"
103
+ ],
104
+ {
105
+ stdio: "pipe"
106
+ }
107
+ );
108
+ }
109
+ async cleanCss(options) {
110
+ try {
111
+ await this.runCmd("node", [options.scriptPath]);
112
+ await copyFile(options.disposeCssPath, this.options.outputPath);
113
+ } catch (err) {
114
+ throw err;
115
+ }
116
+ return true;
117
+ }
118
+ };
119
+ async function copyFile(sourcePath, targetPath) {
120
+ const absSource = import_path.default.resolve(sourcePath);
121
+ const absTarget = import_path.default.resolve(targetPath);
122
+ const targetDir = import_path.default.dirname(absTarget);
123
+ await import_promises.default.mkdir(targetDir, { recursive: true });
124
+ await import_promises.default.copyFile(absSource, absTarget);
125
+ }
126
+
127
+ // src/UniTailwindContext.ts
128
+ var import_path2 = __toESM(require("path"));
129
+ var defaultTailwindCssPath = import_path2.default.resolve(__dirname, "./cache/tailwindcss.css");
130
+ var defaultScriptPath = import_path2.default.resolve(__dirname, "./script/clear-modern-css.js");
131
+ var defaultDisposeCssPath = import_path2.default.resolve(__dirname, "./cache/dispose.css");
132
+ var UniTailwindContext = class {
133
+ /**
134
+ * 初始化
135
+ * @param strategy 策略
136
+ */
137
+ constructor(strategy) {
138
+ this.strategy = strategy;
139
+ }
140
+ /**
141
+ * 生成 tailwindcss 的规则类名,
142
+ * @param options
143
+ * @returns 成功或失败
144
+ */
145
+ generateTailwindCss() {
146
+ return this.strategy.generateTailwindCss({
147
+ tailwindCssPath: defaultTailwindCssPath
148
+ });
149
+ }
150
+ /**
151
+ * 清除小程序不识别的 css 样式
152
+ * @param options
153
+ * @returns 成功或失败
154
+ */
155
+ clearCss() {
156
+ return this.strategy.cleanCss({
157
+ disposeCssPath: defaultDisposeCssPath,
158
+ scriptPath: defaultScriptPath
159
+ });
160
+ }
161
+ /**
162
+ * 运行整个处理流程
163
+ */
164
+ async buildTailwindCss() {
165
+ try {
166
+ await this.generateTailwindCss();
167
+ await this.clearCss();
168
+ } catch (error) {
169
+ const err = error;
170
+ console.error("\u274C \u6784\u5EFA\u5931\u8D25:", err.message);
171
+ }
172
+ }
173
+ };
174
+
175
+ // src/UniTailwindWatcher.ts
176
+ var import_chokidar = __toESM(require("chokidar"));
177
+ var import_path3 = __toESM(require("path"));
178
+ var UniTailwindWatcher = class {
179
+ /**
180
+ * 初始化
181
+ * @param options 配置项
182
+ */
183
+ constructor(options) {
184
+ this.options = options;
185
+ this.options.watcherPaths = this.parserWatcherPaths(this.options.watcherPaths);
186
+ this.watcher = this.startWatch();
187
+ }
188
+ /**
189
+ * 处理监听路径,改为绝对路径
190
+ * @param watcherPaths 监听路径列表
191
+ * @returns 添加了绝对路径的列表
192
+ */
193
+ parserWatcherPaths(watcherPaths) {
194
+ return watcherPaths.map((watchPath) => import_path3.default.resolve(this.options.projectPath, watchPath));
195
+ }
196
+ /**
197
+ * 开启监听
198
+ * @returns 监听实例对象
199
+ */
200
+ startWatch() {
201
+ return import_chokidar.default.watch(this.options.watcherPaths, {
202
+ cwd: process.cwd(),
203
+ // 持续监听(退出进程才停止)
204
+ persistent: true,
205
+ // 忽略初始扫描(只监听后续变更)
206
+ ignoreInitial: true,
207
+ // 等待文件写入完成再触发(避免部分写入)
208
+ awaitWriteFinish: {
209
+ // 稳定时间(ms)
210
+ stabilityThreshold: 200,
211
+ // 轮询间隔(ms)
212
+ pollInterval: 100
213
+ },
214
+ ...this.options
215
+ });
216
+ }
217
+ on(eventName, listener) {
218
+ return this.watcher.on(eventName, listener);
219
+ }
220
+ };
221
+
222
+ // src/index.ts
223
+ function viteUniTailwindProcessor(options, strategy) {
224
+ let useStrategy;
225
+ if (strategy) {
226
+ useStrategy = new strategy(options);
227
+ } else {
228
+ useStrategy = new DefaultStrategy(options);
229
+ }
230
+ const context = new UniTailwindContext(useStrategy);
231
+ const unitailwindWatcher = new UniTailwindWatcher(options);
232
+ unitailwindWatcher.on("change", () => context.buildTailwindCss());
233
+ let _buildStarted = false;
234
+ return {
235
+ name: "vite-uni-tailwind-Processor",
236
+ buildStart() {
237
+ if (_buildStarted) {
238
+ return;
239
+ }
240
+ _buildStarted = true;
241
+ context.buildTailwindCss();
242
+ }
243
+ };
244
+ }
package/dist/index.mjs ADDED
@@ -0,0 +1,211 @@
1
+ // src/strategys/BaseStrategyAbstract.ts
2
+ import { spawn } from "child_process";
3
+ var BaseStrategyAbstract = class {
4
+ /**
5
+ *
6
+ * @param options 初始化
7
+ */
8
+ constructor(options) {
9
+ this.options = options;
10
+ }
11
+ isInputPath(filePath) {
12
+ return this.options.inputPath === filePath || filePath.startsWith(this.options.inputPath);
13
+ }
14
+ /**
15
+ * 执行cmd指令
16
+ * @param command 指令
17
+ * @param args 参数
18
+ * @param options 配置项
19
+ */
20
+ runCmd(command, args, options) {
21
+ return new Promise((resolve, reject) => {
22
+ const subProcess = spawn(command, args, {
23
+ cwd: this.options.projectPath,
24
+ shell: true,
25
+ stdio: "inherit",
26
+ ...options
27
+ });
28
+ subProcess.on("error", (err) => {
29
+ reject(new Error(`\u8FDB\u7A0B\u542F\u52A8\u5931\u8D25\uFF1A${err.message}`));
30
+ });
31
+ if (args.includes("--watch")) {
32
+ subProcess.stderr?.on("data", () => {
33
+ resolve(true);
34
+ });
35
+ } else {
36
+ subProcess.on("close", (code) => {
37
+ if (code === 0) {
38
+ resolve(true);
39
+ } else {
40
+ reject(new Error(`\u547D\u4EE4\u6267\u884C\u5931\u8D25\uFF0C\u9000\u51FA\u7801\uFF1A${code}`));
41
+ }
42
+ });
43
+ }
44
+ });
45
+ }
46
+ };
47
+
48
+ // src/strategys/DefaultStrategy.ts
49
+ import path from "path";
50
+ import fs from "fs/promises";
51
+ var DefaultStrategy = class extends BaseStrategyAbstract {
52
+ constructor(options) {
53
+ super(options);
54
+ this.options = options;
55
+ }
56
+ generateTailwindCss(options) {
57
+ fs.writeFile(this.options.outputPath, "");
58
+ return this.runCmd(
59
+ "npx",
60
+ [
61
+ "tailwindcss",
62
+ "-i",
63
+ this.options.inputPath,
64
+ "-o",
65
+ options.tailwindCssPath,
66
+ "--optimize-for-compatibility"
67
+ ],
68
+ {
69
+ stdio: "pipe"
70
+ }
71
+ );
72
+ }
73
+ async cleanCss(options) {
74
+ try {
75
+ await this.runCmd("node", [options.scriptPath]);
76
+ await copyFile(options.disposeCssPath, this.options.outputPath);
77
+ } catch (err) {
78
+ throw err;
79
+ }
80
+ return true;
81
+ }
82
+ };
83
+ async function copyFile(sourcePath, targetPath) {
84
+ const absSource = path.resolve(sourcePath);
85
+ const absTarget = path.resolve(targetPath);
86
+ const targetDir = path.dirname(absTarget);
87
+ await fs.mkdir(targetDir, { recursive: true });
88
+ await fs.copyFile(absSource, absTarget);
89
+ }
90
+
91
+ // src/UniTailwindContext.ts
92
+ import path2 from "path";
93
+ var defaultTailwindCssPath = path2.resolve(__dirname, "./cache/tailwindcss.css");
94
+ var defaultScriptPath = path2.resolve(__dirname, "./script/clear-modern-css.js");
95
+ var defaultDisposeCssPath = path2.resolve(__dirname, "./cache/dispose.css");
96
+ var UniTailwindContext = class {
97
+ /**
98
+ * 初始化
99
+ * @param strategy 策略
100
+ */
101
+ constructor(strategy) {
102
+ this.strategy = strategy;
103
+ }
104
+ /**
105
+ * 生成 tailwindcss 的规则类名,
106
+ * @param options
107
+ * @returns 成功或失败
108
+ */
109
+ generateTailwindCss() {
110
+ return this.strategy.generateTailwindCss({
111
+ tailwindCssPath: defaultTailwindCssPath
112
+ });
113
+ }
114
+ /**
115
+ * 清除小程序不识别的 css 样式
116
+ * @param options
117
+ * @returns 成功或失败
118
+ */
119
+ clearCss() {
120
+ return this.strategy.cleanCss({
121
+ disposeCssPath: defaultDisposeCssPath,
122
+ scriptPath: defaultScriptPath
123
+ });
124
+ }
125
+ /**
126
+ * 运行整个处理流程
127
+ */
128
+ async buildTailwindCss() {
129
+ try {
130
+ await this.generateTailwindCss();
131
+ await this.clearCss();
132
+ } catch (error) {
133
+ const err = error;
134
+ console.error("\u274C \u6784\u5EFA\u5931\u8D25:", err.message);
135
+ }
136
+ }
137
+ };
138
+
139
+ // src/UniTailwindWatcher.ts
140
+ import chokidar from "chokidar";
141
+ import path3 from "path";
142
+ var UniTailwindWatcher = class {
143
+ /**
144
+ * 初始化
145
+ * @param options 配置项
146
+ */
147
+ constructor(options) {
148
+ this.options = options;
149
+ this.options.watcherPaths = this.parserWatcherPaths(this.options.watcherPaths);
150
+ this.watcher = this.startWatch();
151
+ }
152
+ /**
153
+ * 处理监听路径,改为绝对路径
154
+ * @param watcherPaths 监听路径列表
155
+ * @returns 添加了绝对路径的列表
156
+ */
157
+ parserWatcherPaths(watcherPaths) {
158
+ return watcherPaths.map((watchPath) => path3.resolve(this.options.projectPath, watchPath));
159
+ }
160
+ /**
161
+ * 开启监听
162
+ * @returns 监听实例对象
163
+ */
164
+ startWatch() {
165
+ return chokidar.watch(this.options.watcherPaths, {
166
+ cwd: process.cwd(),
167
+ // 持续监听(退出进程才停止)
168
+ persistent: true,
169
+ // 忽略初始扫描(只监听后续变更)
170
+ ignoreInitial: true,
171
+ // 等待文件写入完成再触发(避免部分写入)
172
+ awaitWriteFinish: {
173
+ // 稳定时间(ms)
174
+ stabilityThreshold: 200,
175
+ // 轮询间隔(ms)
176
+ pollInterval: 100
177
+ },
178
+ ...this.options
179
+ });
180
+ }
181
+ on(eventName, listener) {
182
+ return this.watcher.on(eventName, listener);
183
+ }
184
+ };
185
+
186
+ // src/index.ts
187
+ function viteUniTailwindProcessor(options, strategy) {
188
+ let useStrategy;
189
+ if (strategy) {
190
+ useStrategy = new strategy(options);
191
+ } else {
192
+ useStrategy = new DefaultStrategy(options);
193
+ }
194
+ const context = new UniTailwindContext(useStrategy);
195
+ const unitailwindWatcher = new UniTailwindWatcher(options);
196
+ unitailwindWatcher.on("change", () => context.buildTailwindCss());
197
+ let _buildStarted = false;
198
+ return {
199
+ name: "vite-uni-tailwind-Processor",
200
+ buildStart() {
201
+ if (_buildStarted) {
202
+ return;
203
+ }
204
+ _buildStarted = true;
205
+ context.buildTailwindCss();
206
+ }
207
+ };
208
+ }
209
+ export {
210
+ viteUniTailwindProcessor as default
211
+ };
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "vite-plugin-uni-tailwind-processor",
3
+ "version": "1.0.0",
4
+ "description": "Vite插件:为uniapp项目适配tailwindcss的文件监听与样式处理",
5
+ "main": "dist/index.cjs",
6
+ "module": "dist/index.mjs",
7
+ "types": "dist/index.d.ts",
8
+ "files": [
9
+ "dist",
10
+ "README.md"
11
+ ],
12
+ "keywords": [
13
+ "vite",
14
+ "vite-plugin",
15
+ "uniapp",
16
+ "tailwindcss",
17
+ "chokidar"
18
+ ],
19
+ "author": "1848424733@qq.com",
20
+ "license": "MIT",
21
+ "peerDependencies": {
22
+ "vite": "^4.0.0 || ^5.0.0"
23
+ },
24
+ "devDependencies": {
25
+ "chokidar": "^3.5.3",
26
+ "tsup": "^8.0.0",
27
+ "typescript": "^5.0.0",
28
+ "vite": "^5.0.0"
29
+ },
30
+ "scripts": {
31
+ "build": "tsup src/index.ts --format cjs,esm --dts --external vite --external chokidar",
32
+ "prepublishOnly": "npm run build"
33
+ },
34
+ "peerDependenciesMeta": {
35
+ "chokidar": {
36
+ "optional": false
37
+ }
38
+ }
39
+ }