tailwindcss-patch 2.0.0-alpha.0 → 2.0.1

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 CHANGED
@@ -1,16 +1,19 @@
1
1
  # tailwindcss-patch
2
2
 
3
- get tailwindcss context at runtime ! extract all class to json file!
3
+ get tailwindcss context at runtime ! extract all classes into file!
4
4
 
5
5
  - [tailwindcss-patch](#tailwindcss-patch)
6
6
  - [Setup](#setup)
7
7
  - [Usage](#usage)
8
8
  - [Cli](#cli)
9
9
  - [Init Config File](#init-config-file)
10
- - [extract all class into a json](#extract-all-class-into-a-json)
10
+ - [Extract all class into a json](#extract-all-class-into-a-json)
11
11
  - [Nodejs](#nodejs)
12
12
  - [Migration form v1 to v2](#migration-form-v1-to-v2)
13
- - [Notice](#notice)
13
+ - [0. cli command change](#0-cli-command-change)
14
+ - [1. default remove `*` in json array result](#1-default-remove--in-json-array-result)
15
+
16
+ > Nodejs version should >= `16.6.0`
14
17
 
15
18
  ## Setup
16
19
 
@@ -51,7 +54,7 @@ tw-patch init
51
54
 
52
55
  Then there will be a ts file called `tailwindcss-patch.config.ts` exist in your `cwd`.
53
56
 
54
- ### extract all class into a json
57
+ ### Extract all class into a json
55
58
 
56
59
  ```sh
57
60
  tw-patch extract
@@ -70,11 +73,13 @@ const twPatcher = new TailwindcssPatcher(/* options */)
70
73
  // get all contexts at runtime
71
74
  twPatcher.getContexts()
72
75
  // get all class generated by tailwindcss utilities
73
- twPatcher.getClassCacheSet()
76
+ twPatcher.getClassSet()
74
77
  ```
75
78
 
76
79
  ## Migration form v1 to v2
77
80
 
81
+ ### 0. cli command change
82
+
78
83
  ```diff
79
84
  {
80
85
  - "tw-patch"
@@ -82,10 +87,12 @@ twPatcher.getClassCacheSet()
82
87
  }
83
88
  ```
84
89
 
85
- ## Notice
86
-
87
- `getContexts`,`getClassCacheSet` should be invoked after `postcss-loader`'s activation.
90
+ ### 1. default remove `*` in json array result
88
91
 
89
- which means you may not get tailwindcss contexts at build start time.
90
-
91
- you may call them at `generateBundle` lifetime hook in `vite/webpack plugin`.
92
+ ```diff
93
+ [
94
+ - "*",
95
+ "text-[99px]",
96
+ "text-[100px]"
97
+ ]
98
+ ```
package/bin/tw-patch.js CHANGED
@@ -1,7 +1,7 @@
1
- #!/usr/bin/env node
2
- const fs = require('node:fs')
3
- const path = require('node:path')
4
- const cliPath = path.resolve(__dirname, '../dist/cli.cjs')
5
- if (fs.existsSync(cliPath)) {
6
- require(cliPath)
7
- }
1
+ #!/usr/bin/env node
2
+ const fs = require('node:fs')
3
+ const path = require('node:path')
4
+ const cliPath = path.resolve(__dirname, '../dist/cli.cjs')
5
+ if (fs.existsSync(cliPath)) {
6
+ require(cliPath)
7
+ }
package/dist/cli.cjs CHANGED
@@ -1,9 +1,9 @@
1
1
  'use strict';
2
2
 
3
3
  const index = require('./index.cjs');
4
- const path = require('node:path');
4
+ require('node:path');
5
5
  require('node:fs');
6
- const fs = require('node:fs/promises');
6
+ require('node:fs/promises');
7
7
  require('resolve');
8
8
  require('@babel/types');
9
9
  require('@babel/generator');
@@ -12,86 +12,15 @@ require('@babel/parser');
12
12
  const cac = require('cac');
13
13
  require('semver');
14
14
  require('postcss');
15
- require('postcss-load-config');
16
15
  require('c12');
17
16
 
18
17
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
19
18
 
20
- const path__default = /*#__PURE__*/_interopDefaultCompat(path);
21
- const fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
22
19
  const cac__default = /*#__PURE__*/_interopDefaultCompat(cac);
23
20
 
24
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
25
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
26
- function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
27
- function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
28
- function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
29
- const dedent = createDedent({});
30
- function createDedent(options) {
31
- dedent.withOptions = newOptions => createDedent(_objectSpread(_objectSpread({}, options), newOptions));
32
- return dedent;
33
- function dedent(strings, ...values) {
34
- const raw = typeof strings === "string" ? [strings] : strings.raw;
35
- const {
36
- escapeSpecialCharacters = Array.isArray(strings)
37
- } = options;
38
-
39
- // first, perform interpolation
40
- let result = "";
41
- for (let i = 0; i < raw.length; i++) {
42
- let next = raw[i];
43
- if (escapeSpecialCharacters) {
44
- // handle escaped newlines, backticks, and interpolation characters
45
- next = next.replace(/\\\n[ \t]*/g, "").replace(/\\`/g, "`").replace(/\\\$/g, "$").replace(/\\{/g, "{");
46
- }
47
- result += next;
48
- if (i < values.length) {
49
- // eslint-disable-next-line @typescript-eslint/restrict-plus-operands
50
- result += values[i];
51
- }
52
- }
53
-
54
- // now strip indentation
55
- const lines = result.split("\n");
56
- let mindent = null;
57
- for (const l of lines) {
58
- const m = l.match(/^(\s+)\S+/);
59
- if (m) {
60
- const indent = m[1].length;
61
- if (!mindent) {
62
- // this is the first indented line
63
- mindent = indent;
64
- } else {
65
- mindent = Math.min(mindent, indent);
66
- }
67
- }
68
- }
69
- if (mindent !== null) {
70
- const m = mindent; // appease TypeScript
71
- result = lines
72
- // https://github.com/typescript-eslint/typescript-eslint/issues/7140
73
- // eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with
74
- .map(l => l[0] === " " || l[0] === "\t" ? l.slice(m) : l).join("\n");
75
- }
76
- return result
77
- // dedent eats leading and trailing whitespace too
78
- .trim()
79
- // handle escaped newlines at the end to ensure they don't get stripped too
80
- .replace(/\\n/g, "\n");
81
- }
82
- }
83
-
84
21
  function init() {
85
22
  const cwd = process.cwd();
86
- return fs__default.writeFile(
87
- path__default.resolve(cwd, "tailwindcss-patch.config.ts"),
88
- dedent`
89
- import { defineConfig } from 'tailwindcss-patch'
90
-
91
- export default defineConfig({})
92
- `,
93
- "utf8"
94
- );
23
+ return index.initConfig(cwd);
95
24
  }
96
25
  const cli = cac__default();
97
26
  cli.command("install", "patch install").action(() => {
@@ -105,13 +34,10 @@ cli.command("init").action(async () => {
105
34
  });
106
35
  cli.command("extract").action(async () => {
107
36
  const { config } = await index.getConfig();
108
- if (config?.output?.filename) {
37
+ if (config) {
109
38
  const twPatcher = new index.TailwindcssPatcher();
110
- await twPatcher.extract({
111
- filename: config.output.filename,
112
- configDir: config.postcss?.configDir,
113
- loose: config.postcss?.loose
114
- });
39
+ const p = await twPatcher.extract(config);
40
+ console.log("\u2728 tailwindcss-patch extract success! file path:\n" + p);
115
41
  }
116
42
  });
117
43
  cli.help();
package/dist/cli.mjs CHANGED
@@ -1,7 +1,7 @@
1
- import { getPatchOptions, getConfig, TailwindcssPatcher, createPatch } from './index.mjs';
2
- import path from 'node:path';
1
+ import { getPatchOptions, getConfig, TailwindcssPatcher, initConfig, createPatch } from './index.mjs';
2
+ import 'node:path';
3
3
  import 'node:fs';
4
- import fs from 'node:fs/promises';
4
+ import 'node:fs/promises';
5
5
  import 'resolve';
6
6
  import '@babel/types';
7
7
  import '@babel/generator';
@@ -10,80 +10,11 @@ import '@babel/parser';
10
10
  import cac from 'cac';
11
11
  import 'semver';
12
12
  import 'postcss';
13
- import 'postcss-load-config';
14
13
  import 'c12';
15
14
 
16
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
17
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
18
- function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
19
- function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
20
- function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
21
- const dedent = createDedent({});
22
- function createDedent(options) {
23
- dedent.withOptions = newOptions => createDedent(_objectSpread(_objectSpread({}, options), newOptions));
24
- return dedent;
25
- function dedent(strings, ...values) {
26
- const raw = typeof strings === "string" ? [strings] : strings.raw;
27
- const {
28
- escapeSpecialCharacters = Array.isArray(strings)
29
- } = options;
30
-
31
- // first, perform interpolation
32
- let result = "";
33
- for (let i = 0; i < raw.length; i++) {
34
- let next = raw[i];
35
- if (escapeSpecialCharacters) {
36
- // handle escaped newlines, backticks, and interpolation characters
37
- next = next.replace(/\\\n[ \t]*/g, "").replace(/\\`/g, "`").replace(/\\\$/g, "$").replace(/\\{/g, "{");
38
- }
39
- result += next;
40
- if (i < values.length) {
41
- // eslint-disable-next-line @typescript-eslint/restrict-plus-operands
42
- result += values[i];
43
- }
44
- }
45
-
46
- // now strip indentation
47
- const lines = result.split("\n");
48
- let mindent = null;
49
- for (const l of lines) {
50
- const m = l.match(/^(\s+)\S+/);
51
- if (m) {
52
- const indent = m[1].length;
53
- if (!mindent) {
54
- // this is the first indented line
55
- mindent = indent;
56
- } else {
57
- mindent = Math.min(mindent, indent);
58
- }
59
- }
60
- }
61
- if (mindent !== null) {
62
- const m = mindent; // appease TypeScript
63
- result = lines
64
- // https://github.com/typescript-eslint/typescript-eslint/issues/7140
65
- // eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with
66
- .map(l => l[0] === " " || l[0] === "\t" ? l.slice(m) : l).join("\n");
67
- }
68
- return result
69
- // dedent eats leading and trailing whitespace too
70
- .trim()
71
- // handle escaped newlines at the end to ensure they don't get stripped too
72
- .replace(/\\n/g, "\n");
73
- }
74
- }
75
-
76
15
  function init() {
77
16
  const cwd = process.cwd();
78
- return fs.writeFile(
79
- path.resolve(cwd, "tailwindcss-patch.config.ts"),
80
- dedent`
81
- import { defineConfig } from 'tailwindcss-patch'
82
-
83
- export default defineConfig({})
84
- `,
85
- "utf8"
86
- );
17
+ return initConfig(cwd);
87
18
  }
88
19
  const cli = cac();
89
20
  cli.command("install", "patch install").action(() => {
@@ -97,13 +28,10 @@ cli.command("init").action(async () => {
97
28
  });
98
29
  cli.command("extract").action(async () => {
99
30
  const { config } = await getConfig();
100
- if (config?.output?.filename) {
31
+ if (config) {
101
32
  const twPatcher = new TailwindcssPatcher();
102
- await twPatcher.extract({
103
- filename: config.output.filename,
104
- configDir: config.postcss?.configDir,
105
- loose: config.postcss?.loose
106
- });
33
+ const p = await twPatcher.extract(config);
34
+ console.log("\u2728 tailwindcss-patch extract success! file path:\n" + p);
107
35
  }
108
36
  });
109
37
  cli.help();
package/dist/index.cjs CHANGED
@@ -10,7 +10,6 @@ const generate = require('@babel/generator');
10
10
  const traverse = require('@babel/traverse');
11
11
  const parser = require('@babel/parser');
12
12
  const postcss = require('postcss');
13
- const postcssrc = require('postcss-load-config');
14
13
  const c12 = require('c12');
15
14
 
16
15
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
@@ -35,7 +34,6 @@ const t__namespace = /*#__PURE__*/_interopNamespaceCompat(t);
35
34
  const generate__default = /*#__PURE__*/_interopDefaultCompat(generate);
36
35
  const traverse__default = /*#__PURE__*/_interopDefaultCompat(traverse);
37
36
  const postcss__default = /*#__PURE__*/_interopDefaultCompat(postcss);
38
- const postcssrc__default = /*#__PURE__*/_interopDefaultCompat(postcssrc);
39
37
 
40
38
  const { sync } = pkg__default;
41
39
  function ensureFileContent(filepaths) {
@@ -86,13 +84,17 @@ function getClassCaches(basedir) {
86
84
  const contexts = getContexts(basedir);
87
85
  return contexts.map((x) => x.classCache);
88
86
  }
89
- function getClassCacheSet(basedir) {
87
+ function getClassCacheSet(basedir, options) {
90
88
  const classCaches = getClassCaches(basedir);
91
89
  const classSet = /* @__PURE__ */ new Set();
92
90
  for (const classCacheMap of classCaches) {
93
91
  const keys = classCacheMap.keys();
94
92
  for (const key of keys) {
95
- classSet.add(key.toString());
93
+ const v = key.toString();
94
+ if (options?.removeUniversalSelector && v === "*") {
95
+ continue;
96
+ }
97
+ classSet.add(v);
96
98
  }
97
99
  }
98
100
  return classSet;
@@ -359,9 +361,23 @@ function createDefu(merger) {
359
361
  }
360
362
  const defu = createDefu();
361
363
 
362
- const defaultOptions = {
363
- overwrite: true
364
- };
364
+ function getDefaultPatchOptions() {
365
+ return {
366
+ overwrite: true
367
+ };
368
+ }
369
+ function getDefaultUserConfig() {
370
+ return {
371
+ output: {
372
+ filename: ".tw-patch/tw-class-list.json",
373
+ removeUniversalSelector: true,
374
+ loose: true
375
+ },
376
+ tailwindcss: {
377
+ cwd: process.cwd()
378
+ }
379
+ };
380
+ }
365
381
 
366
382
  function getInstalledPkgJsonPath(options = {}) {
367
383
  try {
@@ -381,7 +397,7 @@ function getPatchOptions(options = {}) {
381
397
  {
382
398
  basedir: process.cwd()
383
399
  },
384
- defaultOptions
400
+ getDefaultPatchOptions()
385
401
  );
386
402
  }
387
403
  function createPatch(opt) {
@@ -436,11 +452,15 @@ function internalPatch(pkgJsonPath, options) {
436
452
  }
437
453
  }
438
454
 
439
- async function getCss(p) {
440
- const { options, plugins } = await postcssrc__default(void 0, p);
441
- const res = await postcss__default(plugins).process("@tailwind base;@tailwind components;@tailwind utilities;", {
442
- from: void 0,
443
- ...options
455
+ async function processTailwindcss(options) {
456
+ options.cwd = options.cwd ?? process.cwd();
457
+ const config = options.config && path__default.isAbsolute(options.config) ? options.config : path__default.resolve(options.cwd, "tailwind.config.js");
458
+ const res = await postcss__default([
459
+ require("tailwindcss")({
460
+ config
461
+ })
462
+ ]).process("@tailwind base;@tailwind components;@tailwind utilities;", {
463
+ from: void 0
444
464
  });
445
465
  return res;
446
466
  }
@@ -470,11 +490,11 @@ class TailwindcssPatcher {
470
490
  * @param basedir
471
491
  * @returns
472
492
  */
473
- getClassSet(options = {
474
- cacheStrategy: this.cacheOptions.strategy ?? "merge"
475
- }) {
476
- const { basedir, cacheStrategy } = options;
477
- const set = getClassCacheSet(basedir);
493
+ getClassSet(options) {
494
+ const { basedir, cacheStrategy = this.cacheOptions.strategy ?? "merge", removeUniversalSelector = true } = options ?? {};
495
+ const set = getClassCacheSet(basedir, {
496
+ removeUniversalSelector
497
+ });
478
498
  if (cacheStrategy === "overwrite") {
479
499
  set.size > 0 && this.setCache(set);
480
500
  } else if (cacheStrategy === "merge") {
@@ -492,31 +512,104 @@ class TailwindcssPatcher {
492
512
  return getContexts(basedir);
493
513
  }
494
514
  async extract(options) {
495
- const { configDir, filename, loose } = options;
496
- await getCss(configDir);
497
- const set = this.getClassSet();
498
- await ensureDir(path.dirname(filename));
499
- const classList = [...set];
500
- await fs__default$1.writeFile(filename, JSON.stringify(classList, null, loose ? 2 : void 0), "utf8");
501
- return classList;
515
+ const { output, tailwindcss } = options;
516
+ if (output && tailwindcss) {
517
+ const { removeUniversalSelector, filename, loose } = output;
518
+ await processTailwindcss(tailwindcss);
519
+ const set = this.getClassSet({
520
+ removeUniversalSelector
521
+ });
522
+ if (filename) {
523
+ await ensureDir(path.dirname(filename));
524
+ const classList = [...set];
525
+ await fs__default$1.writeFile(filename, JSON.stringify(classList, null, loose ? 2 : void 0), "utf8");
526
+ return filename;
527
+ }
528
+ }
502
529
  }
503
530
  }
504
531
 
505
- function getConfig() {
532
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
533
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
534
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
535
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
536
+ function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
537
+ const dedent = createDedent({});
538
+ function createDedent(options) {
539
+ dedent.withOptions = newOptions => createDedent(_objectSpread(_objectSpread({}, options), newOptions));
540
+ return dedent;
541
+ function dedent(strings, ...values) {
542
+ const raw = typeof strings === "string" ? [strings] : strings.raw;
543
+ const {
544
+ escapeSpecialCharacters = Array.isArray(strings)
545
+ } = options;
546
+
547
+ // first, perform interpolation
548
+ let result = "";
549
+ for (let i = 0; i < raw.length; i++) {
550
+ let next = raw[i];
551
+ if (escapeSpecialCharacters) {
552
+ // handle escaped newlines, backticks, and interpolation characters
553
+ next = next.replace(/\\\n[ \t]*/g, "").replace(/\\`/g, "`").replace(/\\\$/g, "$").replace(/\\{/g, "{");
554
+ }
555
+ result += next;
556
+ if (i < values.length) {
557
+ // eslint-disable-next-line @typescript-eslint/restrict-plus-operands
558
+ result += values[i];
559
+ }
560
+ }
561
+
562
+ // now strip indentation
563
+ const lines = result.split("\n");
564
+ let mindent = null;
565
+ for (const l of lines) {
566
+ const m = l.match(/^(\s+)\S+/);
567
+ if (m) {
568
+ const indent = m[1].length;
569
+ if (!mindent) {
570
+ // this is the first indented line
571
+ mindent = indent;
572
+ } else {
573
+ mindent = Math.min(mindent, indent);
574
+ }
575
+ }
576
+ }
577
+ if (mindent !== null) {
578
+ const m = mindent; // appease TypeScript
579
+ result = lines
580
+ // https://github.com/typescript-eslint/typescript-eslint/issues/7140
581
+ // eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with
582
+ .map(l => l[0] === " " || l[0] === "\t" ? l.slice(m) : l).join("\n");
583
+ }
584
+ return result
585
+ // dedent eats leading and trailing whitespace too
586
+ .trim()
587
+ // handle escaped newlines at the end to ensure they don't get stripped too
588
+ .replace(/\\n/g, "\n");
589
+ }
590
+ }
591
+
592
+ function getConfig(cwd) {
506
593
  return c12.loadConfig({
507
594
  name: "tailwindcss-patch",
508
595
  defaults: {
509
- output: {
510
- filename: ".tw-patch/tw-class-list.json"
511
- },
512
- postcss: {
513
- configDir: process.cwd(),
514
- loose: true
515
- }
516
- }
596
+ ...getDefaultUserConfig()
597
+ },
598
+ cwd
517
599
  });
518
600
  }
519
601
  const defineConfig = c12.createDefineConfig();
602
+ function initConfig(cwd) {
603
+ return fs__default$1.writeFile(
604
+ path__default.resolve(cwd, "tailwindcss-patch.config.ts"),
605
+ dedent`
606
+ import { defineConfig } from 'tailwindcss-patch'
607
+
608
+ export default defineConfig({})
609
+ `,
610
+ "utf8"
611
+ );
612
+ }
520
613
 
521
614
  exports.CacheManager = CacheManager;
522
615
  exports.TailwindcssPatcher = TailwindcssPatcher;
@@ -532,6 +625,7 @@ exports.getContexts = getContexts;
532
625
  exports.getInstalledPkgJsonPath = getInstalledPkgJsonPath;
533
626
  exports.getPatchOptions = getPatchOptions;
534
627
  exports.getTailwindcssEntry = getTailwindcssEntry;
628
+ exports.initConfig = initConfig;
535
629
  exports.inspectPostcssPlugin = inspectPostcssPlugin;
536
630
  exports.inspectProcessTailwindFeaturesReturnContext = inspectProcessTailwindFeaturesReturnContext;
537
631
  exports.internalPatch = internalPatch;
package/dist/index.d.ts CHANGED
@@ -76,13 +76,20 @@ type TailwindcssRuntimeContext = {
76
76
  interface UserConfig {
77
77
  output?: {
78
78
  filename?: string;
79
- };
80
- postcss?: {
81
- configDir?: string;
82
79
  loose?: boolean;
80
+ /**
81
+ * @description remove * in output json
82
+ */
83
+ removeUniversalSelector?: boolean;
84
+ };
85
+ tailwindcss?: {
86
+ cwd?: string;
87
+ config?: string;
83
88
  };
84
- tailwindcss?: {};
85
89
  }
90
+ type DeepRequired<T> = {
91
+ [K in keyof T]: Required<DeepRequired<T[K]>>;
92
+ };
86
93
 
87
94
  declare function getCacheOptions(options?: CacheOptions | boolean): InternalCacheOptions;
88
95
  declare class CacheManager {
@@ -117,19 +124,18 @@ declare class TailwindcssPatcher {
117
124
  getClassSet(options?: {
118
125
  basedir?: string;
119
126
  cacheStrategy?: CacheStrategy;
127
+ removeUniversalSelector?: boolean;
120
128
  }): Set<string>;
121
129
  getContexts(basedir?: string): TailwindcssRuntimeContext[];
122
- extract(options: {
123
- configDir: string;
124
- filename: string;
125
- loose: boolean;
126
- }): Promise<string[]>;
130
+ extract(options: UserConfig): Promise<string | undefined>;
127
131
  }
128
132
 
129
133
  declare function getTailwindcssEntry(basedir?: string): string;
130
134
  declare function getContexts(basedir?: string): TailwindcssRuntimeContext[];
131
135
  declare function getClassCaches(basedir?: string): TailwindcssClassCache[];
132
- declare function getClassCacheSet(basedir?: string): Set<string>;
136
+ declare function getClassCacheSet(basedir?: string, options?: {
137
+ removeUniversalSelector?: boolean;
138
+ }): Set<string>;
133
139
 
134
140
  declare function inspectProcessTailwindFeaturesReturnContext(content: string): {
135
141
  code: string;
@@ -149,11 +155,12 @@ declare function monkeyPatchForExposingContext(twDir: string, opt: InternalPatch
149
155
  } & Record<string, any>;
150
156
  declare function internalPatch(pkgJsonPath: string | undefined, options: InternalPatchOptions): any | undefined;
151
157
 
152
- declare function getConfig(): Promise<c12.ResolvedConfig<UserConfig, c12.ConfigLayerMeta>>;
158
+ declare function getConfig(cwd?: string): Promise<c12.ResolvedConfig<UserConfig, c12.ConfigLayerMeta>>;
153
159
  declare const defineConfig: c12.DefineConfig<UserConfig, c12.ConfigLayerMeta>;
160
+ declare function initConfig(cwd: string): Promise<void>;
154
161
 
155
162
  declare function ensureFileContent(filepaths: string | string[]): string | undefined;
156
163
  declare function requireResolve(id: string, opts?: SyncOpts): string;
157
164
  declare function ensureDir(p: string): Promise<void>;
158
165
 
159
- export { CacheManager, CacheOptions, CacheStrategy, InternalCacheOptions, InternalPatchOptions, PatchOptions, TailwindcssClassCache, TailwindcssPatcher, TailwindcssPatcherOptions, TailwindcssRuntimeContext, UserConfig, createPatch, defineConfig, ensureDir, ensureFileContent, getCacheOptions, getClassCacheSet, getClassCaches, getConfig, getContexts, getInstalledPkgJsonPath, getPatchOptions, getTailwindcssEntry, inspectPostcssPlugin, inspectProcessTailwindFeaturesReturnContext, internalPatch, monkeyPatchForExposingContext, requireResolve };
166
+ export { CacheManager, CacheOptions, CacheStrategy, DeepRequired, InternalCacheOptions, InternalPatchOptions, PatchOptions, TailwindcssClassCache, TailwindcssPatcher, TailwindcssPatcherOptions, TailwindcssRuntimeContext, UserConfig, createPatch, defineConfig, ensureDir, ensureFileContent, getCacheOptions, getClassCacheSet, getClassCaches, getConfig, getContexts, getInstalledPkgJsonPath, getPatchOptions, getTailwindcssEntry, initConfig, inspectPostcssPlugin, inspectProcessTailwindFeaturesReturnContext, internalPatch, monkeyPatchForExposingContext, requireResolve };
package/dist/index.mjs CHANGED
@@ -8,18 +8,8 @@ import generate from '@babel/generator';
8
8
  import traverse from '@babel/traverse';
9
9
  import { parse } from '@babel/parser';
10
10
  import postcss from 'postcss';
11
- import postcssrc from 'postcss-load-config';
12
11
  import { createDefineConfig, loadConfig } from 'c12';
13
12
 
14
-
15
-
16
- // -- Unbuild CommonJS Shims --
17
- import __cjs_url__ from 'url';
18
- import __cjs_path__ from 'path';
19
- import __cjs_mod__ from 'module';
20
- const __filename = __cjs_url__.fileURLToPath(import.meta.url);
21
- const __dirname = __cjs_path__.dirname(__filename);
22
- const require = __cjs_mod__.createRequire(import.meta.url);
23
13
  const { sync } = pkg;
24
14
  function ensureFileContent(filepaths) {
25
15
  if (typeof filepaths === "string") {
@@ -69,13 +59,17 @@ function getClassCaches(basedir) {
69
59
  const contexts = getContexts(basedir);
70
60
  return contexts.map((x) => x.classCache);
71
61
  }
72
- function getClassCacheSet(basedir) {
62
+ function getClassCacheSet(basedir, options) {
73
63
  const classCaches = getClassCaches(basedir);
74
64
  const classSet = /* @__PURE__ */ new Set();
75
65
  for (const classCacheMap of classCaches) {
76
66
  const keys = classCacheMap.keys();
77
67
  for (const key of keys) {
78
- classSet.add(key.toString());
68
+ const v = key.toString();
69
+ if (options?.removeUniversalSelector && v === "*") {
70
+ continue;
71
+ }
72
+ classSet.add(v);
79
73
  }
80
74
  }
81
75
  return classSet;
@@ -342,9 +336,23 @@ function createDefu(merger) {
342
336
  }
343
337
  const defu = createDefu();
344
338
 
345
- const defaultOptions = {
346
- overwrite: true
347
- };
339
+ function getDefaultPatchOptions() {
340
+ return {
341
+ overwrite: true
342
+ };
343
+ }
344
+ function getDefaultUserConfig() {
345
+ return {
346
+ output: {
347
+ filename: ".tw-patch/tw-class-list.json",
348
+ removeUniversalSelector: true,
349
+ loose: true
350
+ },
351
+ tailwindcss: {
352
+ cwd: process.cwd()
353
+ }
354
+ };
355
+ }
348
356
 
349
357
  function getInstalledPkgJsonPath(options = {}) {
350
358
  try {
@@ -364,7 +372,7 @@ function getPatchOptions(options = {}) {
364
372
  {
365
373
  basedir: process.cwd()
366
374
  },
367
- defaultOptions
375
+ getDefaultPatchOptions()
368
376
  );
369
377
  }
370
378
  function createPatch(opt) {
@@ -419,11 +427,15 @@ function internalPatch(pkgJsonPath, options) {
419
427
  }
420
428
  }
421
429
 
422
- async function getCss(p) {
423
- const { options, plugins } = await postcssrc(void 0, p);
424
- const res = await postcss(plugins).process("@tailwind base;@tailwind components;@tailwind utilities;", {
425
- from: void 0,
426
- ...options
430
+ async function processTailwindcss(options) {
431
+ options.cwd = options.cwd ?? process.cwd();
432
+ const config = options.config && path.isAbsolute(options.config) ? options.config : path.resolve(options.cwd, "tailwind.config.js");
433
+ const res = await postcss([
434
+ require("tailwindcss")({
435
+ config
436
+ })
437
+ ]).process("@tailwind base;@tailwind components;@tailwind utilities;", {
438
+ from: void 0
427
439
  });
428
440
  return res;
429
441
  }
@@ -453,11 +465,11 @@ class TailwindcssPatcher {
453
465
  * @param basedir
454
466
  * @returns
455
467
  */
456
- getClassSet(options = {
457
- cacheStrategy: this.cacheOptions.strategy ?? "merge"
458
- }) {
459
- const { basedir, cacheStrategy } = options;
460
- const set = getClassCacheSet(basedir);
468
+ getClassSet(options) {
469
+ const { basedir, cacheStrategy = this.cacheOptions.strategy ?? "merge", removeUniversalSelector = true } = options ?? {};
470
+ const set = getClassCacheSet(basedir, {
471
+ removeUniversalSelector
472
+ });
461
473
  if (cacheStrategy === "overwrite") {
462
474
  set.size > 0 && this.setCache(set);
463
475
  } else if (cacheStrategy === "merge") {
@@ -475,30 +487,112 @@ class TailwindcssPatcher {
475
487
  return getContexts(basedir);
476
488
  }
477
489
  async extract(options) {
478
- const { configDir, filename, loose } = options;
479
- await getCss(configDir);
480
- const set = this.getClassSet();
481
- await ensureDir(dirname(filename));
482
- const classList = [...set];
483
- await fs$1.writeFile(filename, JSON.stringify(classList, null, loose ? 2 : void 0), "utf8");
484
- return classList;
490
+ const { output, tailwindcss } = options;
491
+ if (output && tailwindcss) {
492
+ const { removeUniversalSelector, filename, loose } = output;
493
+ await processTailwindcss(tailwindcss);
494
+ const set = this.getClassSet({
495
+ removeUniversalSelector
496
+ });
497
+ if (filename) {
498
+ await ensureDir(dirname(filename));
499
+ const classList = [...set];
500
+ await fs$1.writeFile(filename, JSON.stringify(classList, null, loose ? 2 : void 0), "utf8");
501
+ return filename;
502
+ }
503
+ }
504
+ }
505
+ }
506
+
507
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
508
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
509
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
510
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
511
+ function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
512
+ const dedent = createDedent({});
513
+ function createDedent(options) {
514
+ dedent.withOptions = newOptions => createDedent(_objectSpread(_objectSpread({}, options), newOptions));
515
+ return dedent;
516
+ function dedent(strings, ...values) {
517
+ const raw = typeof strings === "string" ? [strings] : strings.raw;
518
+ const {
519
+ escapeSpecialCharacters = Array.isArray(strings)
520
+ } = options;
521
+
522
+ // first, perform interpolation
523
+ let result = "";
524
+ for (let i = 0; i < raw.length; i++) {
525
+ let next = raw[i];
526
+ if (escapeSpecialCharacters) {
527
+ // handle escaped newlines, backticks, and interpolation characters
528
+ next = next.replace(/\\\n[ \t]*/g, "").replace(/\\`/g, "`").replace(/\\\$/g, "$").replace(/\\{/g, "{");
529
+ }
530
+ result += next;
531
+ if (i < values.length) {
532
+ // eslint-disable-next-line @typescript-eslint/restrict-plus-operands
533
+ result += values[i];
534
+ }
535
+ }
536
+
537
+ // now strip indentation
538
+ const lines = result.split("\n");
539
+ let mindent = null;
540
+ for (const l of lines) {
541
+ const m = l.match(/^(\s+)\S+/);
542
+ if (m) {
543
+ const indent = m[1].length;
544
+ if (!mindent) {
545
+ // this is the first indented line
546
+ mindent = indent;
547
+ } else {
548
+ mindent = Math.min(mindent, indent);
549
+ }
550
+ }
551
+ }
552
+ if (mindent !== null) {
553
+ const m = mindent; // appease TypeScript
554
+ result = lines
555
+ // https://github.com/typescript-eslint/typescript-eslint/issues/7140
556
+ // eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with
557
+ .map(l => l[0] === " " || l[0] === "\t" ? l.slice(m) : l).join("\n");
558
+ }
559
+ return result
560
+ // dedent eats leading and trailing whitespace too
561
+ .trim()
562
+ // handle escaped newlines at the end to ensure they don't get stripped too
563
+ .replace(/\\n/g, "\n");
485
564
  }
486
565
  }
487
566
 
488
- function getConfig() {
567
+ function getConfig(cwd) {
489
568
  return loadConfig({
490
569
  name: "tailwindcss-patch",
491
570
  defaults: {
492
- output: {
493
- filename: ".tw-patch/tw-class-list.json"
494
- },
495
- postcss: {
496
- configDir: process.cwd(),
497
- loose: true
498
- }
499
- }
571
+ ...getDefaultUserConfig()
572
+ },
573
+ cwd
500
574
  });
501
575
  }
502
576
  const defineConfig = createDefineConfig();
577
+ function initConfig(cwd) {
578
+ return fs$1.writeFile(
579
+ path.resolve(cwd, "tailwindcss-patch.config.ts"),
580
+ dedent`
581
+ import { defineConfig } from 'tailwindcss-patch'
582
+
583
+
584
+
585
+ // -- Unbuild CommonJS Shims --
586
+ import __cjs_url__ from 'url';
587
+ import __cjs_path__ from 'path';
588
+ import __cjs_mod__ from 'module';
589
+ const __filename = __cjs_url__.fileURLToPath(import.meta.url);
590
+ const __dirname = __cjs_path__.dirname(__filename);
591
+ const require = __cjs_mod__.createRequire(import.meta.url);
592
+ export default defineConfig({})
593
+ `,
594
+ "utf8"
595
+ );
596
+ }
503
597
 
504
- export { CacheManager, TailwindcssPatcher, createPatch, defineConfig, ensureDir, ensureFileContent, getCacheOptions, getClassCacheSet, getClassCaches, getConfig, getContexts, getInstalledPkgJsonPath, getPatchOptions, getTailwindcssEntry, inspectPostcssPlugin, inspectProcessTailwindFeaturesReturnContext, internalPatch, monkeyPatchForExposingContext, requireResolve };
598
+ export { CacheManager, TailwindcssPatcher, createPatch, defineConfig, ensureDir, ensureFileContent, getCacheOptions, getClassCacheSet, getClassCaches, getConfig, getContexts, getInstalledPkgJsonPath, getPatchOptions, getTailwindcssEntry, initConfig, inspectPostcssPlugin, inspectProcessTailwindFeaturesReturnContext, internalPatch, monkeyPatchForExposingContext, requireResolve };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "tailwindcss-patch",
3
- "version": "2.0.0-alpha.0",
4
- "description": "patch tailwindcss for exposing context",
3
+ "version": "2.0.1",
4
+ "description": "patch tailwindcss for exposing context and extract classes",
5
5
  "exports": {
6
6
  ".": {
7
7
  "types": "./dist/index.d.ts",
@@ -30,7 +30,9 @@
30
30
  ],
31
31
  "keywords": [
32
32
  "tailwindcss",
33
- "patch"
33
+ "patch",
34
+ "extract",
35
+ "class"
34
36
  ],
35
37
  "author": "SonOfMagic <qq1324318532@gmail.com>",
36
38
  "license": "MIT",
@@ -38,13 +40,19 @@
38
40
  "access": "public",
39
41
  "registry": "https://registry.npmjs.org/"
40
42
  },
43
+ "peerDependencies": {
44
+ "tailwindcss": ">=3.0.0"
45
+ },
46
+ "peerDependenciesMeta": {
47
+ "tailwindcss": {
48
+ "optional": false
49
+ }
50
+ },
41
51
  "devDependencies": {
42
52
  "@types/babel__generator": "^7.6.4",
43
53
  "@types/babel__traverse": "^7.20.1",
44
54
  "@types/resolve": "^1.20.2",
45
55
  "@types/semver": "^7.5.0",
46
- "dedent": "^1.5.1",
47
- "defu": "^6.1.2",
48
56
  "pkg-types": "^1.0.3",
49
57
  "tailwindcss": "^3.3.3"
50
58
  },
@@ -56,7 +64,6 @@
56
64
  "c12": "^1.4.2",
57
65
  "cac": "^6.7.14",
58
66
  "postcss": "^8.4.27",
59
- "postcss-load-config": "^4.0.1",
60
67
  "resolve": "^1.22.4",
61
68
  "semver": "^7.5.4"
62
69
  },
@@ -75,6 +82,6 @@
75
82
  "build": "unbuild",
76
83
  "test": "vitest run --coverage.enabled",
77
84
  "test:dev": "vitest",
78
- "cli": "node bin/tw-patch.js"
85
+ "cli": "node bin/tw-patch.js install"
79
86
  }
80
87
  }