tailwindcss-injector 0.0.1 → 0.1.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.
- package/README.md +112 -0
- package/dist/postcss.cjs +118 -59
- package/dist/postcss.d.cts +1 -1
- package/dist/postcss.d.ts +1 -1
- package/dist/postcss.js +116 -54
- package/package.json +9 -7
package/README.md
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# TailwindCSS Injector
|
|
2
|
+
|
|
3
|
+
**English | [中文](./README-cn.md)**
|
|
4
|
+
|
|
5
|
+
- [TailwindCSS Injector](#tailwindcss-injector)
|
|
6
|
+
- [Overview](#overview)
|
|
7
|
+
- [Features](#features)
|
|
8
|
+
- [Installation](#installation)
|
|
9
|
+
- [Usage](#usage)
|
|
10
|
+
- [Basic Example](#basic-example)
|
|
11
|
+
- [Options](#options)
|
|
12
|
+
- [Example Configuration](#example-configuration)
|
|
13
|
+
- [How It Works](#how-it-works)
|
|
14
|
+
- [License](#license)
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Overview
|
|
19
|
+
|
|
20
|
+
`tailwindcss-injector` is a library designed to dynamically inject TailwindCSS directives and configurations into your CSS workflow. It includes a PostCSS plugin that supports multiple file extensions, dynamic configuration, and flexible filtering, enabling seamless integration into modern build pipelines.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Features
|
|
25
|
+
|
|
26
|
+
- **Dynamic Directive Injection**: Automatically inserts TailwindCSS directives like `@tailwind base`, `@tailwind components`, and `@tailwind utilities`.
|
|
27
|
+
- **Multi-extension Support**: Processes files with customizable extensions (e.g., `.html`, `.js`, `.ts`).
|
|
28
|
+
- **Inline or External Configuration**: Accepts inline configuration objects or paths to configuration files.
|
|
29
|
+
- **Customizable Filters**: Use a filter function to process specific files.
|
|
30
|
+
- **TailwindCSS Integration**: Dynamically adjusts TailwindCSS configurations per file.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Installation
|
|
35
|
+
|
|
36
|
+
Install the package and its dependencies:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npm install tailwindcss-injector tailwindcss postcss --save-dev
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Usage
|
|
45
|
+
|
|
46
|
+
To use the PostCSS plugin, import it from `tailwindcss-injector/postcss`:
|
|
47
|
+
|
|
48
|
+
### Basic Example
|
|
49
|
+
|
|
50
|
+
```javascript
|
|
51
|
+
const tailwindInjector = require('tailwindcss-injector/postcss')
|
|
52
|
+
|
|
53
|
+
module.exports = {
|
|
54
|
+
plugins: [
|
|
55
|
+
tailwindInjector({
|
|
56
|
+
cwd: process.cwd(),
|
|
57
|
+
config: './tailwind.config.js',
|
|
58
|
+
directiveParams: ['base', 'components', 'utilities'],
|
|
59
|
+
extensions: ['html', 'js', 'ts'],
|
|
60
|
+
filter: input => !!input?.file && input.file.endsWith('.css'),
|
|
61
|
+
}),
|
|
62
|
+
],
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Options
|
|
69
|
+
|
|
70
|
+
The plugin accepts the following options:
|
|
71
|
+
|
|
72
|
+
| Option | Type | Description |
|
|
73
|
+
| ----------------- | ------------------------------------------------------------------ | ------------------------------------------------------------------- |
|
|
74
|
+
| `cwd` | `string` | Current working directory. |
|
|
75
|
+
| `config` | `string \| Partial<Config> \| (input) => InlineTailwindcssOptions` | TailwindCSS configuration file path or inline configuration object. |
|
|
76
|
+
| `directiveParams` | `('base' \| 'components' \| 'utilities' \| 'variants')[]` | Array of TailwindCSS directives to inject. |
|
|
77
|
+
| `extensions` | `string[]` | Array of supported file extensions. |
|
|
78
|
+
| `filter` | `(input?: postcss.Input) => boolean` | Custom function to filter files to process. |
|
|
79
|
+
|
|
80
|
+
### Example Configuration
|
|
81
|
+
|
|
82
|
+
```javascript
|
|
83
|
+
{
|
|
84
|
+
cwd: process.cwd(), // Set current working directory
|
|
85
|
+
config: './tailwind.config.js', // Use an external TailwindCSS configuration file
|
|
86
|
+
directiveParams: ['base', 'components', 'utilities'], // Inject directives dynamically
|
|
87
|
+
extensions: ['html', 'js', 'ts'], // Process specific file extensions
|
|
88
|
+
filter: (input) => !!input?.file && input.file.endsWith('.css'), // Filter for CSS files only
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## How It Works
|
|
95
|
+
|
|
96
|
+
1. **Directive Injection**:
|
|
97
|
+
The plugin ensures that the specified TailwindCSS directives (`@tailwind base`, `@tailwind components`, etc.) are injected into the CSS files.
|
|
98
|
+
|
|
99
|
+
2. **Dynamic Configuration**:
|
|
100
|
+
TailwindCSS configurations are dynamically adjusted based on the processed files, including custom extensions.
|
|
101
|
+
|
|
102
|
+
3. **File Filtering**:
|
|
103
|
+
Files to process can be filtered using the `filter` option.
|
|
104
|
+
|
|
105
|
+
4. **PostCSS Processing**:
|
|
106
|
+
The plugin integrates with PostCSS to apply TailwindCSS transformations seamlessly.
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## License
|
|
111
|
+
|
|
112
|
+
This project is licensed under the **MIT License**. See the `LICENSE` file for details.
|
package/dist/postcss.cjs
CHANGED
|
@@ -28,12 +28,9 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
28
28
|
));
|
|
29
29
|
|
|
30
30
|
// ../../node_modules/.pnpm/tsup@8.3.5_jiti@2.4.1_postcss@8.4.49_tsx@4.19.2_typescript@5.7.2_yaml@2.6.1/node_modules/tsup/assets/cjs_shims.js
|
|
31
|
-
var getImportMetaUrl, importMetaUrl;
|
|
32
31
|
var init_cjs_shims = __esm({
|
|
33
32
|
"../../node_modules/.pnpm/tsup@8.3.5_jiti@2.4.1_postcss@8.4.49_tsx@4.19.2_typescript@5.7.2_yaml@2.6.1/node_modules/tsup/assets/cjs_shims.js"() {
|
|
34
33
|
"use strict";
|
|
35
|
-
getImportMetaUrl = () => typeof document === "undefined" ? new URL(`file:${__filename}`).href : document.currentScript && document.currentScript.src || new URL("main.js", document.baseURI).href;
|
|
36
|
-
importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
|
|
37
34
|
}
|
|
38
35
|
});
|
|
39
36
|
|
|
@@ -218,7 +215,15 @@ var require_set_value = __commonJS({
|
|
|
218
215
|
|
|
219
216
|
// src/postcss.ts
|
|
220
217
|
init_cjs_shims();
|
|
218
|
+
var import_set_value = __toESM(require_set_value(), 1);
|
|
221
219
|
var _process = require('process'); var _process2 = _interopRequireDefault(_process);
|
|
220
|
+
var _postcss = require('postcss'); var _postcss2 = _interopRequireDefault(_postcss);
|
|
221
|
+
var _tailwindcss = require('tailwindcss'); var _tailwindcss2 = _interopRequireDefault(_tailwindcss);
|
|
222
|
+
var _tailwindcssconfig = require('tailwindcss-config');
|
|
223
|
+
|
|
224
|
+
// src/utils.ts
|
|
225
|
+
init_cjs_shims();
|
|
226
|
+
var _path = require('path'); var _path2 = _interopRequireDefault(_path);
|
|
222
227
|
|
|
223
228
|
// ../../node_modules/.pnpm/defu@6.1.4/node_modules/defu/dist/defu.mjs
|
|
224
229
|
init_cjs_shims();
|
|
@@ -289,69 +294,116 @@ var defuArrayFn = createDefu((object, key, currentValue) => {
|
|
|
289
294
|
}
|
|
290
295
|
});
|
|
291
296
|
|
|
292
|
-
// src/
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
// src/config.ts
|
|
298
|
-
init_cjs_shims();
|
|
299
|
-
var _path = require('path'); var _path2 = _interopRequireDefault(_path);
|
|
300
|
-
|
|
301
|
-
var _jiti = require('jiti');
|
|
302
|
-
var _lilconfig = require('lilconfig');
|
|
303
|
-
var jiti = _jiti.createJiti.call(void 0, importMetaUrl);
|
|
304
|
-
var moduleName = "tailwind";
|
|
305
|
-
async function loadConfig(options) {
|
|
306
|
-
const { config, cwd } = defu(options, {
|
|
307
|
-
cwd: _process2.default.cwd()
|
|
308
|
-
});
|
|
309
|
-
const searcher = _lilconfig.lilconfig.call(void 0, "tailwindcss", {
|
|
310
|
-
searchPlaces: [
|
|
311
|
-
`${moduleName}.config.js`,
|
|
312
|
-
`${moduleName}.config.cjs`,
|
|
313
|
-
`${moduleName}.config.mjs`,
|
|
314
|
-
`${moduleName}.config.ts`,
|
|
315
|
-
`${moduleName}.config.cts`,
|
|
316
|
-
`${moduleName}.config.mts`
|
|
317
|
-
],
|
|
318
|
-
loaders: {
|
|
319
|
-
".js": jiti,
|
|
320
|
-
".cjs": jiti,
|
|
321
|
-
".mjs": jiti,
|
|
322
|
-
".ts": jiti,
|
|
323
|
-
".cts": jiti,
|
|
324
|
-
".mts": jiti
|
|
325
|
-
}
|
|
326
|
-
});
|
|
327
|
-
if (typeof config === "string" && config) {
|
|
328
|
-
const configPath = _path2.default.isAbsolute(config) ? config : _path2.default.resolve(cwd, config);
|
|
329
|
-
const result = await searcher.load(configPath);
|
|
330
|
-
return _optionalChain([result, 'optionalAccess', _ => _.config]);
|
|
331
|
-
} else {
|
|
332
|
-
const result = await searcher.search(cwd);
|
|
333
|
-
return _optionalChain([result, 'optionalAccess', _2 => _2.config]);
|
|
297
|
+
// src/utils.ts
|
|
298
|
+
function removeFileExtension(filePath) {
|
|
299
|
+
if (!filePath) {
|
|
300
|
+
return "";
|
|
334
301
|
}
|
|
302
|
+
let baseName = _path2.default.basename(filePath);
|
|
303
|
+
let ext = _path2.default.extname(baseName);
|
|
304
|
+
while (ext) {
|
|
305
|
+
baseName = baseName.slice(0, -ext.length);
|
|
306
|
+
ext = _path2.default.extname(baseName);
|
|
307
|
+
}
|
|
308
|
+
const dir = _path2.default.dirname(filePath);
|
|
309
|
+
return _path2.default.join(dir, baseName);
|
|
335
310
|
}
|
|
311
|
+
var defuOverrideArray = createDefu((obj, key, value) => {
|
|
312
|
+
if (Array.isArray(obj[key]) && Array.isArray(value)) {
|
|
313
|
+
obj[key] = value;
|
|
314
|
+
return true;
|
|
315
|
+
}
|
|
316
|
+
});
|
|
336
317
|
|
|
337
|
-
// src/
|
|
318
|
+
// src/wxml.ts
|
|
338
319
|
init_cjs_shims();
|
|
339
320
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
321
|
+
var _fsextra = require('fs-extra'); var _fsextra2 = _interopRequireDefault(_fsextra);
|
|
322
|
+
var _htmlparser2 = require('htmlparser2');
|
|
323
|
+
var _magicstring = require('magic-string'); var _magicstring2 = _interopRequireDefault(_magicstring);
|
|
324
|
+
var srcImportTagsMap = {
|
|
325
|
+
// audio: ['src', 'poster'],
|
|
326
|
+
// video: ['src', 'poster'],
|
|
327
|
+
// image: ['src'],
|
|
328
|
+
// https://developers.weixin.qq.com/miniprogram/dev/reference/wxs/01wxs-module.html
|
|
329
|
+
// wxs: ['src'],
|
|
330
|
+
// https://developers.weixin.qq.com/miniprogram/dev/reference/wxml/import.html
|
|
331
|
+
import: ["src"],
|
|
332
|
+
include: ["src"]
|
|
333
|
+
};
|
|
334
|
+
function processWxml(wxml) {
|
|
335
|
+
const ms = new (0, _magicstring2.default)(wxml.toString());
|
|
336
|
+
const deps = [];
|
|
337
|
+
let currentTagName = "";
|
|
338
|
+
let importAttrs;
|
|
339
|
+
let attrs = {};
|
|
340
|
+
const parser = new (0, _htmlparser2.Parser)(
|
|
341
|
+
{
|
|
342
|
+
onopentagname(name) {
|
|
343
|
+
currentTagName = name;
|
|
344
|
+
importAttrs = srcImportTagsMap[currentTagName];
|
|
345
|
+
},
|
|
346
|
+
onattribute(name, value, quote) {
|
|
347
|
+
attrs[name] = value;
|
|
348
|
+
if (importAttrs) {
|
|
349
|
+
for (const attrName of importAttrs) {
|
|
350
|
+
if (attrName === name) {
|
|
351
|
+
deps.push({
|
|
352
|
+
name,
|
|
353
|
+
value,
|
|
354
|
+
quote,
|
|
355
|
+
tagName: currentTagName,
|
|
356
|
+
start: parser.startIndex,
|
|
357
|
+
end: parser.endIndex,
|
|
358
|
+
attrs
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
},
|
|
364
|
+
onclosetag() {
|
|
365
|
+
currentTagName = "";
|
|
366
|
+
attrs = {};
|
|
367
|
+
importAttrs = void 0;
|
|
368
|
+
}
|
|
369
|
+
},
|
|
370
|
+
{
|
|
371
|
+
lowerCaseTags: false,
|
|
372
|
+
xmlMode: true
|
|
373
|
+
}
|
|
374
|
+
);
|
|
375
|
+
parser.write(
|
|
376
|
+
ms.original
|
|
377
|
+
);
|
|
378
|
+
parser.end();
|
|
379
|
+
return deps;
|
|
380
|
+
}
|
|
381
|
+
async function getDepFiles(file) {
|
|
382
|
+
const set2 = /* @__PURE__ */ new Set();
|
|
383
|
+
async function getDep(filepath) {
|
|
384
|
+
if (await _fsextra2.default.exists(filepath)) {
|
|
385
|
+
const dirname = _path2.default.dirname(filepath);
|
|
386
|
+
set2.add(filepath);
|
|
387
|
+
const wxml = await _fsextra2.default.readFile(filepath, "utf8");
|
|
388
|
+
const deps = await processWxml(wxml);
|
|
389
|
+
for (const { value } of deps) {
|
|
390
|
+
const p = _path2.default.resolve(dirname, value);
|
|
391
|
+
if (!set2.has(p)) {
|
|
392
|
+
await getDep(p);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
344
396
|
}
|
|
345
|
-
|
|
346
|
-
return
|
|
397
|
+
await getDep(file);
|
|
398
|
+
return set2;
|
|
347
399
|
}
|
|
348
400
|
|
|
349
401
|
// src/postcss.ts
|
|
350
402
|
var creator = (options) => {
|
|
351
|
-
const { config, filter, directiveParams, cwd, extensions } =
|
|
403
|
+
const { config, filter, directiveParams, cwd, extensions } = defuOverrideArray(options, {
|
|
352
404
|
filter: () => true,
|
|
353
405
|
config: void 0,
|
|
354
|
-
directiveParams: ["utilities"],
|
|
406
|
+
directiveParams: ["utilities", "components"],
|
|
355
407
|
cwd: _process2.default.cwd(),
|
|
356
408
|
extensions: ["wxml", "js", "ts"]
|
|
357
409
|
});
|
|
@@ -362,7 +414,7 @@ var creator = (options) => {
|
|
|
362
414
|
{
|
|
363
415
|
postcssPlugin: "post",
|
|
364
416
|
async Once(root, helpers) {
|
|
365
|
-
if (filter(_optionalChain([root, 'access',
|
|
417
|
+
if (filter(_optionalChain([root, 'access', _ => _.source, 'optionalAccess', _2 => _2.input]))) {
|
|
366
418
|
let _root = root;
|
|
367
419
|
for (const params of directiveParams) {
|
|
368
420
|
const node = root.nodes.find((x) => x.type === "atrule" && x.params === params);
|
|
@@ -370,10 +422,10 @@ var creator = (options) => {
|
|
|
370
422
|
_root = _root.prepend(helpers.atRule({ name: "tailwind", params }));
|
|
371
423
|
}
|
|
372
424
|
}
|
|
373
|
-
const cfg = typeof config === "function" ? config(_optionalChain([root, 'access',
|
|
425
|
+
const cfg = typeof config === "function" ? config(_optionalChain([root, 'access', _3 => _3.source, 'optionalAccess', _4 => _4.input])) : config;
|
|
374
426
|
let tailwindcssConfig;
|
|
375
427
|
if (typeof cfg === "string") {
|
|
376
|
-
tailwindcssConfig = await loadConfig({
|
|
428
|
+
tailwindcssConfig = await _tailwindcssconfig.loadConfig.call(void 0, {
|
|
377
429
|
cwd,
|
|
378
430
|
config: cfg
|
|
379
431
|
});
|
|
@@ -382,10 +434,17 @@ var creator = (options) => {
|
|
|
382
434
|
content: []
|
|
383
435
|
}));
|
|
384
436
|
}
|
|
385
|
-
if (tailwindcssConfig && _optionalChain([root, 'access',
|
|
437
|
+
if (tailwindcssConfig && _optionalChain([root, 'access', _5 => _5.source, 'optionalAccess', _6 => _6.input]) && root.source.input.file) {
|
|
438
|
+
const basename = removeFileExtension(root.source.input.file);
|
|
386
439
|
(0, import_set_value.default)(tailwindcssConfig, "content", [
|
|
387
|
-
`${
|
|
440
|
+
`${basename}.${extensionsGlob}`
|
|
388
441
|
]);
|
|
442
|
+
const deps = await getDepFiles(`${basename}.wxml`);
|
|
443
|
+
for (const dep of deps) {
|
|
444
|
+
if (Array.isArray(tailwindcssConfig.content)) {
|
|
445
|
+
tailwindcssConfig.content.push(`${removeFileExtension(dep)}.${extensionsGlob}`);
|
|
446
|
+
}
|
|
447
|
+
}
|
|
389
448
|
}
|
|
390
449
|
const { root: newRoot } = await _postcss2.default.call(void 0, [
|
|
391
450
|
_tailwindcss2.default.call(void 0, tailwindcssConfig)
|
package/dist/postcss.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import postcss, { PluginCreator } from 'postcss';
|
|
2
2
|
import { Config } from 'tailwindcss';
|
|
3
3
|
|
|
4
|
-
type InlineTailwindcssOptions = string | Config | undefined;
|
|
4
|
+
type InlineTailwindcssOptions = string | Partial<Config> | undefined;
|
|
5
5
|
interface Options {
|
|
6
6
|
cwd: string;
|
|
7
7
|
filter: (input?: postcss.Input) => boolean;
|
package/dist/postcss.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import postcss, { PluginCreator } from 'postcss';
|
|
2
2
|
import { Config } from 'tailwindcss';
|
|
3
3
|
|
|
4
|
-
type InlineTailwindcssOptions = string | Config | undefined;
|
|
4
|
+
type InlineTailwindcssOptions = string | Partial<Config> | undefined;
|
|
5
5
|
interface Options {
|
|
6
6
|
cwd: string;
|
|
7
7
|
filter: (input?: postcss.Input) => boolean;
|
package/dist/postcss.js
CHANGED
|
@@ -215,7 +215,15 @@ var require_set_value = __commonJS({
|
|
|
215
215
|
|
|
216
216
|
// src/postcss.ts
|
|
217
217
|
init_esm_shims();
|
|
218
|
-
|
|
218
|
+
var import_set_value = __toESM(require_set_value(), 1);
|
|
219
|
+
import process from "node:process";
|
|
220
|
+
import postcss from "postcss";
|
|
221
|
+
import tailwindcss from "tailwindcss";
|
|
222
|
+
import { loadConfig } from "tailwindcss-config";
|
|
223
|
+
|
|
224
|
+
// src/utils.ts
|
|
225
|
+
init_esm_shims();
|
|
226
|
+
import path from "node:path";
|
|
219
227
|
|
|
220
228
|
// ../../node_modules/.pnpm/defu@6.1.4/node_modules/defu/dist/defu.mjs
|
|
221
229
|
init_esm_shims();
|
|
@@ -286,70 +294,117 @@ var defuArrayFn = createDefu((object, key, currentValue) => {
|
|
|
286
294
|
}
|
|
287
295
|
});
|
|
288
296
|
|
|
289
|
-
// src/
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
// src/config.ts
|
|
295
|
-
init_esm_shims();
|
|
296
|
-
import path from "node:path";
|
|
297
|
-
import process from "node:process";
|
|
298
|
-
import { createJiti } from "jiti";
|
|
299
|
-
import { lilconfig } from "lilconfig";
|
|
300
|
-
var jiti = createJiti(import.meta.url);
|
|
301
|
-
var moduleName = "tailwind";
|
|
302
|
-
async function loadConfig(options) {
|
|
303
|
-
const { config, cwd } = defu(options, {
|
|
304
|
-
cwd: process.cwd()
|
|
305
|
-
});
|
|
306
|
-
const searcher = lilconfig("tailwindcss", {
|
|
307
|
-
searchPlaces: [
|
|
308
|
-
`${moduleName}.config.js`,
|
|
309
|
-
`${moduleName}.config.cjs`,
|
|
310
|
-
`${moduleName}.config.mjs`,
|
|
311
|
-
`${moduleName}.config.ts`,
|
|
312
|
-
`${moduleName}.config.cts`,
|
|
313
|
-
`${moduleName}.config.mts`
|
|
314
|
-
],
|
|
315
|
-
loaders: {
|
|
316
|
-
".js": jiti,
|
|
317
|
-
".cjs": jiti,
|
|
318
|
-
".mjs": jiti,
|
|
319
|
-
".ts": jiti,
|
|
320
|
-
".cts": jiti,
|
|
321
|
-
".mts": jiti
|
|
322
|
-
}
|
|
323
|
-
});
|
|
324
|
-
if (typeof config === "string" && config) {
|
|
325
|
-
const configPath = path.isAbsolute(config) ? config : path.resolve(cwd, config);
|
|
326
|
-
const result = await searcher.load(configPath);
|
|
327
|
-
return result?.config;
|
|
328
|
-
} else {
|
|
329
|
-
const result = await searcher.search(cwd);
|
|
330
|
-
return result?.config;
|
|
297
|
+
// src/utils.ts
|
|
298
|
+
function removeFileExtension(filePath) {
|
|
299
|
+
if (!filePath) {
|
|
300
|
+
return "";
|
|
331
301
|
}
|
|
302
|
+
let baseName = path.basename(filePath);
|
|
303
|
+
let ext = path.extname(baseName);
|
|
304
|
+
while (ext) {
|
|
305
|
+
baseName = baseName.slice(0, -ext.length);
|
|
306
|
+
ext = path.extname(baseName);
|
|
307
|
+
}
|
|
308
|
+
const dir = path.dirname(filePath);
|
|
309
|
+
return path.join(dir, baseName);
|
|
332
310
|
}
|
|
311
|
+
var defuOverrideArray = createDefu((obj, key, value) => {
|
|
312
|
+
if (Array.isArray(obj[key]) && Array.isArray(value)) {
|
|
313
|
+
obj[key] = value;
|
|
314
|
+
return true;
|
|
315
|
+
}
|
|
316
|
+
});
|
|
333
317
|
|
|
334
|
-
// src/
|
|
318
|
+
// src/wxml.ts
|
|
335
319
|
init_esm_shims();
|
|
336
320
|
import path2 from "node:path";
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
321
|
+
import fs from "fs-extra";
|
|
322
|
+
import { Parser } from "htmlparser2";
|
|
323
|
+
import MagicString from "magic-string";
|
|
324
|
+
var srcImportTagsMap = {
|
|
325
|
+
// audio: ['src', 'poster'],
|
|
326
|
+
// video: ['src', 'poster'],
|
|
327
|
+
// image: ['src'],
|
|
328
|
+
// https://developers.weixin.qq.com/miniprogram/dev/reference/wxs/01wxs-module.html
|
|
329
|
+
// wxs: ['src'],
|
|
330
|
+
// https://developers.weixin.qq.com/miniprogram/dev/reference/wxml/import.html
|
|
331
|
+
import: ["src"],
|
|
332
|
+
include: ["src"]
|
|
333
|
+
};
|
|
334
|
+
function processWxml(wxml) {
|
|
335
|
+
const ms = new MagicString(wxml.toString());
|
|
336
|
+
const deps = [];
|
|
337
|
+
let currentTagName = "";
|
|
338
|
+
let importAttrs;
|
|
339
|
+
let attrs = {};
|
|
340
|
+
const parser = new Parser(
|
|
341
|
+
{
|
|
342
|
+
onopentagname(name) {
|
|
343
|
+
currentTagName = name;
|
|
344
|
+
importAttrs = srcImportTagsMap[currentTagName];
|
|
345
|
+
},
|
|
346
|
+
onattribute(name, value, quote) {
|
|
347
|
+
attrs[name] = value;
|
|
348
|
+
if (importAttrs) {
|
|
349
|
+
for (const attrName of importAttrs) {
|
|
350
|
+
if (attrName === name) {
|
|
351
|
+
deps.push({
|
|
352
|
+
name,
|
|
353
|
+
value,
|
|
354
|
+
quote,
|
|
355
|
+
tagName: currentTagName,
|
|
356
|
+
start: parser.startIndex,
|
|
357
|
+
end: parser.endIndex,
|
|
358
|
+
attrs
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
},
|
|
364
|
+
onclosetag() {
|
|
365
|
+
currentTagName = "";
|
|
366
|
+
attrs = {};
|
|
367
|
+
importAttrs = void 0;
|
|
368
|
+
}
|
|
369
|
+
},
|
|
370
|
+
{
|
|
371
|
+
lowerCaseTags: false,
|
|
372
|
+
xmlMode: true
|
|
373
|
+
}
|
|
374
|
+
);
|
|
375
|
+
parser.write(
|
|
376
|
+
ms.original
|
|
377
|
+
);
|
|
378
|
+
parser.end();
|
|
379
|
+
return deps;
|
|
380
|
+
}
|
|
381
|
+
async function getDepFiles(file) {
|
|
382
|
+
const set2 = /* @__PURE__ */ new Set();
|
|
383
|
+
async function getDep(filepath) {
|
|
384
|
+
if (await fs.exists(filepath)) {
|
|
385
|
+
const dirname = path2.dirname(filepath);
|
|
386
|
+
set2.add(filepath);
|
|
387
|
+
const wxml = await fs.readFile(filepath, "utf8");
|
|
388
|
+
const deps = await processWxml(wxml);
|
|
389
|
+
for (const { value } of deps) {
|
|
390
|
+
const p = path2.resolve(dirname, value);
|
|
391
|
+
if (!set2.has(p)) {
|
|
392
|
+
await getDep(p);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
341
396
|
}
|
|
342
|
-
|
|
343
|
-
return
|
|
397
|
+
await getDep(file);
|
|
398
|
+
return set2;
|
|
344
399
|
}
|
|
345
400
|
|
|
346
401
|
// src/postcss.ts
|
|
347
402
|
var creator = (options) => {
|
|
348
|
-
const { config, filter, directiveParams, cwd, extensions } =
|
|
403
|
+
const { config, filter, directiveParams, cwd, extensions } = defuOverrideArray(options, {
|
|
349
404
|
filter: () => true,
|
|
350
405
|
config: void 0,
|
|
351
|
-
directiveParams: ["utilities"],
|
|
352
|
-
cwd:
|
|
406
|
+
directiveParams: ["utilities", "components"],
|
|
407
|
+
cwd: process.cwd(),
|
|
353
408
|
extensions: ["wxml", "js", "ts"]
|
|
354
409
|
});
|
|
355
410
|
const extensionsGlob = `{${extensions.join(",")}}`;
|
|
@@ -380,9 +435,16 @@ var creator = (options) => {
|
|
|
380
435
|
};
|
|
381
436
|
}
|
|
382
437
|
if (tailwindcssConfig && root.source?.input && root.source.input.file) {
|
|
438
|
+
const basename = removeFileExtension(root.source.input.file);
|
|
383
439
|
(0, import_set_value.default)(tailwindcssConfig, "content", [
|
|
384
|
-
`${
|
|
440
|
+
`${basename}.${extensionsGlob}`
|
|
385
441
|
]);
|
|
442
|
+
const deps = await getDepFiles(`${basename}.wxml`);
|
|
443
|
+
for (const dep of deps) {
|
|
444
|
+
if (Array.isArray(tailwindcssConfig.content)) {
|
|
445
|
+
tailwindcssConfig.content.push(`${removeFileExtension(dep)}.${extensionsGlob}`);
|
|
446
|
+
}
|
|
447
|
+
}
|
|
386
448
|
}
|
|
387
449
|
const { root: newRoot } = await postcss([
|
|
388
450
|
tailwindcss(tailwindcssConfig)
|
package/package.json
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tailwindcss-injector",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0
|
|
4
|
+
"version": "0.1.0",
|
|
5
5
|
"description": "tsup(esbuild) build package template",
|
|
6
6
|
"author": "ice breaker <1324318532@qq.com>",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
10
|
-
"url": "git+https://github.com/sonofmagic/
|
|
11
|
-
"directory": "packages/
|
|
10
|
+
"url": "git+https://github.com/sonofmagic/weapp-tailwindcss.git",
|
|
11
|
+
"directory": "packages/tailwindcss-injector"
|
|
12
12
|
},
|
|
13
13
|
"bugs": {
|
|
14
|
-
"url": "https://github.com/sonofmagic/
|
|
14
|
+
"url": "https://github.com/sonofmagic/weapp-tailwindcss/issues"
|
|
15
15
|
},
|
|
16
16
|
"keywords": [],
|
|
17
17
|
"sideEffects": false,
|
|
@@ -31,10 +31,12 @@
|
|
|
31
31
|
"dist"
|
|
32
32
|
],
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"
|
|
35
|
-
"
|
|
34
|
+
"fs-extra": "^11.2.0",
|
|
35
|
+
"htmlparser2": "^9.1.0",
|
|
36
|
+
"magic-string": "^0.30.14",
|
|
36
37
|
"postcss": "^8.4.49",
|
|
37
|
-
"tailwindcss": "^3.4.
|
|
38
|
+
"tailwindcss": "^3.4.16",
|
|
39
|
+
"tailwindcss-config": "0.0.0"
|
|
38
40
|
},
|
|
39
41
|
"scripts": {
|
|
40
42
|
"dev": "tsup --watch --sourcemap",
|