unplugin-tailwindcss-mangle 2.0.4 → 2.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/dist/esbuild.cjs CHANGED
@@ -6,10 +6,12 @@ require('node:path');
6
6
  require('@tailwindcss-mangle/shared');
7
7
  require('@tailwindcss-mangle/config');
8
8
  require('fast-sort');
9
+ require('modern-ahocorasick');
9
10
  require('node:fs/promises');
10
11
  require('micromatch');
11
12
  require('unplugin');
12
13
  require('@tailwindcss-mangle/core');
14
+ require('magic-string');
13
15
  require('./shared/unplugin-tailwindcss-mangle.e90953c3.cjs');
14
16
 
15
17
  const esbuild = index.esbuild;
package/dist/esbuild.mjs CHANGED
@@ -4,10 +4,12 @@ import 'node:path';
4
4
  import '@tailwindcss-mangle/shared';
5
5
  import '@tailwindcss-mangle/config';
6
6
  import 'fast-sort';
7
+ import 'modern-ahocorasick';
7
8
  import 'node:fs/promises';
8
9
  import 'micromatch';
9
10
  import 'unplugin';
10
11
  import '@tailwindcss-mangle/core';
12
+ import 'magic-string';
11
13
  import './shared/unplugin-tailwindcss-mangle.bbd58ece.mjs';
12
14
 
13
15
  const esbuild = unplugin.esbuild;
package/dist/index.cjs CHANGED
@@ -4,17 +4,21 @@ const path = require('node:path');
4
4
  const fs$1 = require('node:fs/promises');
5
5
  const unplugin$1 = require('unplugin');
6
6
  const core = require('@tailwindcss-mangle/core');
7
+ const MagicString = require('magic-string');
7
8
  const fs = require('node:fs');
8
9
  const shared = require('@tailwindcss-mangle/shared');
9
10
  const config = require('@tailwindcss-mangle/config');
10
11
  const fastSort = require('fast-sort');
12
+ const AhoCorasick = require('modern-ahocorasick');
11
13
  const utils = require('./shared/unplugin-tailwindcss-mangle.e90953c3.cjs');
12
14
  require('micromatch');
13
15
 
14
16
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
15
17
 
16
18
  const fs__default$1 = /*#__PURE__*/_interopDefaultCompat(fs$1);
19
+ const MagicString__default = /*#__PURE__*/_interopDefaultCompat(MagicString);
17
20
  const fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
21
+ const AhoCorasick__default = /*#__PURE__*/_interopDefaultCompat(AhoCorasick);
18
22
 
19
23
  function isObject(value) {
20
24
  return value !== null && typeof value === "object";
@@ -59,13 +63,14 @@ function createDefu(merger) {
59
63
  const defu = createDefu();
60
64
 
61
65
  class Context {
62
- constructor(opts) {
63
- this.options = defu(opts, config.getDefaultMangleUserConfig());
66
+ constructor(opts = {}) {
67
+ this.options = opts;
64
68
  this.classSet = /* @__PURE__ */ new Set();
65
69
  this.replaceMap = /* @__PURE__ */ new Map();
66
70
  this.includeMatcher = utils.createGlobMatcher(this.options.include, true);
67
71
  this.excludeMatcher = utils.createGlobMatcher(this.options.exclude, false);
68
72
  this.classGenerator = new shared.ClassGenerator(this.options.classGenerator);
73
+ this.useAC = false;
69
74
  }
70
75
  mergeOptions(opts) {
71
76
  this.options = defu(this.options, opts);
@@ -91,11 +96,34 @@ class Context {
91
96
  hit.usedBy.add(file);
92
97
  }
93
98
  }
94
- async initConfig() {
95
- const { config: config$1 } = await config.getConfig();
99
+ search(str) {
100
+ const arr = this.ahoCorasick?.search(str) ?? [];
101
+ const map = /* @__PURE__ */ new Map();
102
+ for (const [end, classNames] of arr) {
103
+ for (const className of classNames) {
104
+ if (map.has(className)) {
105
+ const v = map.get(className);
106
+ if (v) {
107
+ v.push([end - className.length + 1, end + 1]);
108
+ }
109
+ } else {
110
+ map.set(className, [[end - className.length + 1, end + 1]]);
111
+ }
112
+ }
113
+ }
114
+ return {
115
+ map,
116
+ arr: fastSort.sort([...map.entries()]).desc((x) => x[0].length)
117
+ };
118
+ }
119
+ async initConfig(cwd) {
120
+ const { config: config$1, cwd: configCwd } = await config.getConfig(cwd);
96
121
  const mangleConfig = config$1?.mangle;
97
122
  this.mergeOptions(mangleConfig);
98
- const jsonPath = this.options.classListPath ?? path.resolve(process.cwd(), config$1?.patch?.output?.filename);
123
+ let jsonPath = this.options.classListPath ?? path.resolve(process.cwd(), config$1?.patch?.output?.filename);
124
+ if (!path.isAbsolute(jsonPath)) {
125
+ jsonPath = path.resolve(configCwd ?? process.cwd(), jsonPath);
126
+ }
99
127
  if (jsonPath && fs__default.existsSync(jsonPath)) {
100
128
  const rawClassList = fs__default.readFileSync(jsonPath, "utf8");
101
129
  const list = JSON.parse(rawClassList);
@@ -106,9 +134,12 @@ class Context {
106
134
  }
107
135
  }
108
136
  }
137
+ const keywords = [];
109
138
  for (const cls of this.classSet) {
110
139
  this.classGenerator.generateClassName(cls);
140
+ keywords.push(cls);
111
141
  }
142
+ this.ahoCorasick = new AhoCorasick__default(keywords);
112
143
  for (const x of Object.entries(this.classGenerator.newClassMap)) {
113
144
  this.replaceMap.set(x[0], x[1].name);
114
145
  }
@@ -116,7 +147,7 @@ class Context {
116
147
  }
117
148
  }
118
149
 
119
- const unplugin = unplugin$1.createUnplugin((options = {}) => {
150
+ const unplugin = unplugin$1.createUnplugin((options) => {
120
151
  const ctx = new Context(options);
121
152
  if (ctx.options.disabled) {
122
153
  return {
@@ -133,21 +164,43 @@ const unplugin = unplugin$1.createUnplugin((options = {}) => {
133
164
  return ctx.isInclude(id);
134
165
  },
135
166
  transform(code, id) {
167
+ const s = new MagicString__default(code);
136
168
  const replaceMap = ctx.getReplaceMap();
137
169
  if (/\.[jt]sx?$/.test(id)) {
138
- const str = core.preProcessJs({
139
- code,
170
+ return core.preProcessJs({
171
+ code: s,
140
172
  replaceMap,
141
173
  addToUsedBy: ctx.addToUsedBy.bind(ctx),
142
174
  id
143
175
  });
144
- return str;
176
+ } else if (ctx.useAC) {
177
+ const { arr } = ctx.search(code);
178
+ const markArr = [];
179
+ for (const [cls, ranges] of arr) {
180
+ for (const [start, end] of ranges) {
181
+ const value = replaceMap.get(cls);
182
+ if (value) {
183
+ let flag = true;
184
+ for (const [ps, pe] of markArr) {
185
+ if (start > ps && start < pe || end < pe && end > start) {
186
+ flag = false;
187
+ break;
188
+ }
189
+ }
190
+ if (flag) {
191
+ markArr.push([start, end]);
192
+ s.update(start, end, value);
193
+ }
194
+ }
195
+ }
196
+ }
197
+ return s.toString();
145
198
  } else {
146
199
  for (const [key, value] of replaceMap) {
147
200
  code = code.replaceAll(key, value);
148
201
  }
202
+ return code;
149
203
  }
150
- return code;
151
204
  },
152
205
  vite: {
153
206
  generateBundle: {
@@ -226,21 +279,18 @@ const unplugin = unplugin$1.createUnplugin((options = {}) => {
226
279
  const entries = Object.entries(ctx.classGenerator.newClassMap);
227
280
  if (entries.length > 0 && opts) {
228
281
  await utils.ensureDir(path.dirname(opts.filename));
229
- await fs__default$1.writeFile(
230
- opts.filename,
231
- JSON.stringify(
232
- entries.map((x) => {
233
- return {
234
- origin: x[0],
235
- replacement: x[1].name,
236
- usedBy: [...x[1].usedBy]
237
- };
238
- }),
239
- null,
240
- 2
241
- ),
242
- "utf8"
282
+ const output = JSON.stringify(
283
+ entries.map((x) => {
284
+ return {
285
+ origin: x[0],
286
+ replacement: x[1].name,
287
+ usedBy: [...x[1].usedBy]
288
+ };
289
+ }),
290
+ null,
291
+ opts.loose ? 2 : 0
243
292
  );
293
+ await fs__default$1.writeFile(opts.filename, output, "utf8");
244
294
  console.log(`\u2728 ${opts.filename} generated!`);
245
295
  }
246
296
  }
package/dist/index.mjs CHANGED
@@ -1,11 +1,13 @@
1
- import { resolve, dirname } from 'node:path';
1
+ import { resolve, isAbsolute, dirname } from 'node:path';
2
2
  import fs$1 from 'node:fs/promises';
3
3
  import { createUnplugin } from 'unplugin';
4
4
  import { preProcessJs, cssHandler, jsHandler, htmlHandler } from '@tailwindcss-mangle/core';
5
+ import MagicString from 'magic-string';
5
6
  import fs from 'node:fs';
6
7
  import { ClassGenerator, defaultMangleClassFilter } from '@tailwindcss-mangle/shared';
7
- import { getDefaultMangleUserConfig, getConfig } from '@tailwindcss-mangle/config';
8
+ import { getConfig } from '@tailwindcss-mangle/config';
8
9
  import { sort } from 'fast-sort';
10
+ import AhoCorasick from 'modern-ahocorasick';
9
11
  import { c as createGlobMatcher, p as pluginName, g as getGroupedEntries, e as ensureDir } from './shared/unplugin-tailwindcss-mangle.bbd58ece.mjs';
10
12
  import 'micromatch';
11
13
 
@@ -52,13 +54,14 @@ function createDefu(merger) {
52
54
  const defu = createDefu();
53
55
 
54
56
  class Context {
55
- constructor(opts) {
56
- this.options = defu(opts, getDefaultMangleUserConfig());
57
+ constructor(opts = {}) {
58
+ this.options = opts;
57
59
  this.classSet = /* @__PURE__ */ new Set();
58
60
  this.replaceMap = /* @__PURE__ */ new Map();
59
61
  this.includeMatcher = createGlobMatcher(this.options.include, true);
60
62
  this.excludeMatcher = createGlobMatcher(this.options.exclude, false);
61
63
  this.classGenerator = new ClassGenerator(this.options.classGenerator);
64
+ this.useAC = false;
62
65
  }
63
66
  mergeOptions(opts) {
64
67
  this.options = defu(this.options, opts);
@@ -84,11 +87,34 @@ class Context {
84
87
  hit.usedBy.add(file);
85
88
  }
86
89
  }
87
- async initConfig() {
88
- const { config } = await getConfig();
90
+ search(str) {
91
+ const arr = this.ahoCorasick?.search(str) ?? [];
92
+ const map = /* @__PURE__ */ new Map();
93
+ for (const [end, classNames] of arr) {
94
+ for (const className of classNames) {
95
+ if (map.has(className)) {
96
+ const v = map.get(className);
97
+ if (v) {
98
+ v.push([end - className.length + 1, end + 1]);
99
+ }
100
+ } else {
101
+ map.set(className, [[end - className.length + 1, end + 1]]);
102
+ }
103
+ }
104
+ }
105
+ return {
106
+ map,
107
+ arr: sort([...map.entries()]).desc((x) => x[0].length)
108
+ };
109
+ }
110
+ async initConfig(cwd) {
111
+ const { config, cwd: configCwd } = await getConfig(cwd);
89
112
  const mangleConfig = config?.mangle;
90
113
  this.mergeOptions(mangleConfig);
91
- const jsonPath = this.options.classListPath ?? resolve(process.cwd(), config?.patch?.output?.filename);
114
+ let jsonPath = this.options.classListPath ?? resolve(process.cwd(), config?.patch?.output?.filename);
115
+ if (!isAbsolute(jsonPath)) {
116
+ jsonPath = resolve(configCwd ?? process.cwd(), jsonPath);
117
+ }
92
118
  if (jsonPath && fs.existsSync(jsonPath)) {
93
119
  const rawClassList = fs.readFileSync(jsonPath, "utf8");
94
120
  const list = JSON.parse(rawClassList);
@@ -99,9 +125,12 @@ class Context {
99
125
  }
100
126
  }
101
127
  }
128
+ const keywords = [];
102
129
  for (const cls of this.classSet) {
103
130
  this.classGenerator.generateClassName(cls);
131
+ keywords.push(cls);
104
132
  }
133
+ this.ahoCorasick = new AhoCorasick(keywords);
105
134
  for (const x of Object.entries(this.classGenerator.newClassMap)) {
106
135
  this.replaceMap.set(x[0], x[1].name);
107
136
  }
@@ -109,7 +138,7 @@ class Context {
109
138
  }
110
139
  }
111
140
 
112
- const unplugin = createUnplugin((options = {}) => {
141
+ const unplugin = createUnplugin((options) => {
113
142
  const ctx = new Context(options);
114
143
  if (ctx.options.disabled) {
115
144
  return {
@@ -126,21 +155,43 @@ const unplugin = createUnplugin((options = {}) => {
126
155
  return ctx.isInclude(id);
127
156
  },
128
157
  transform(code, id) {
158
+ const s = new MagicString(code);
129
159
  const replaceMap = ctx.getReplaceMap();
130
160
  if (/\.[jt]sx?$/.test(id)) {
131
- const str = preProcessJs({
132
- code,
161
+ return preProcessJs({
162
+ code: s,
133
163
  replaceMap,
134
164
  addToUsedBy: ctx.addToUsedBy.bind(ctx),
135
165
  id
136
166
  });
137
- return str;
167
+ } else if (ctx.useAC) {
168
+ const { arr } = ctx.search(code);
169
+ const markArr = [];
170
+ for (const [cls, ranges] of arr) {
171
+ for (const [start, end] of ranges) {
172
+ const value = replaceMap.get(cls);
173
+ if (value) {
174
+ let flag = true;
175
+ for (const [ps, pe] of markArr) {
176
+ if (start > ps && start < pe || end < pe && end > start) {
177
+ flag = false;
178
+ break;
179
+ }
180
+ }
181
+ if (flag) {
182
+ markArr.push([start, end]);
183
+ s.update(start, end, value);
184
+ }
185
+ }
186
+ }
187
+ }
188
+ return s.toString();
138
189
  } else {
139
190
  for (const [key, value] of replaceMap) {
140
191
  code = code.replaceAll(key, value);
141
192
  }
193
+ return code;
142
194
  }
143
- return code;
144
195
  },
145
196
  vite: {
146
197
  generateBundle: {
@@ -219,21 +270,18 @@ const unplugin = createUnplugin((options = {}) => {
219
270
  const entries = Object.entries(ctx.classGenerator.newClassMap);
220
271
  if (entries.length > 0 && opts) {
221
272
  await ensureDir(dirname(opts.filename));
222
- await fs$1.writeFile(
223
- opts.filename,
224
- JSON.stringify(
225
- entries.map((x) => {
226
- return {
227
- origin: x[0],
228
- replacement: x[1].name,
229
- usedBy: [...x[1].usedBy]
230
- };
231
- }),
232
- null,
233
- 2
234
- ),
235
- "utf8"
273
+ const output = JSON.stringify(
274
+ entries.map((x) => {
275
+ return {
276
+ origin: x[0],
277
+ replacement: x[1].name,
278
+ usedBy: [...x[1].usedBy]
279
+ };
280
+ }),
281
+ null,
282
+ opts.loose ? 2 : 0
236
283
  );
284
+ await fs$1.writeFile(opts.filename, output, "utf8");
237
285
  console.log(`\u2728 ${opts.filename} generated!`);
238
286
  }
239
287
  }
package/dist/nuxt.cjs CHANGED
@@ -6,10 +6,12 @@ require('node:path');
6
6
  require('@tailwindcss-mangle/shared');
7
7
  require('@tailwindcss-mangle/config');
8
8
  require('fast-sort');
9
+ require('modern-ahocorasick');
9
10
  require('node:fs/promises');
10
11
  require('micromatch');
11
12
  require('unplugin');
12
13
  require('@tailwindcss-mangle/core');
14
+ require('magic-string');
13
15
  require('./shared/unplugin-tailwindcss-mangle.e90953c3.cjs');
14
16
 
15
17
  function nuxt(options = {}, nuxt) {
package/dist/nuxt.mjs CHANGED
@@ -4,10 +4,12 @@ import 'node:path';
4
4
  import '@tailwindcss-mangle/shared';
5
5
  import '@tailwindcss-mangle/config';
6
6
  import 'fast-sort';
7
+ import 'modern-ahocorasick';
7
8
  import 'node:fs/promises';
8
9
  import 'micromatch';
9
10
  import 'unplugin';
10
11
  import '@tailwindcss-mangle/core';
12
+ import 'magic-string';
11
13
  import './shared/unplugin-tailwindcss-mangle.bbd58ece.mjs';
12
14
 
13
15
  function nuxt(options = {}, nuxt) {
package/dist/rollup.cjs CHANGED
@@ -6,10 +6,12 @@ require('node:path');
6
6
  require('@tailwindcss-mangle/shared');
7
7
  require('@tailwindcss-mangle/config');
8
8
  require('fast-sort');
9
+ require('modern-ahocorasick');
9
10
  require('node:fs/promises');
10
11
  require('micromatch');
11
12
  require('unplugin');
12
13
  require('@tailwindcss-mangle/core');
14
+ require('magic-string');
13
15
  require('./shared/unplugin-tailwindcss-mangle.e90953c3.cjs');
14
16
 
15
17
  const rollup = index.rollup;
package/dist/rollup.mjs CHANGED
@@ -4,10 +4,12 @@ import 'node:path';
4
4
  import '@tailwindcss-mangle/shared';
5
5
  import '@tailwindcss-mangle/config';
6
6
  import 'fast-sort';
7
+ import 'modern-ahocorasick';
7
8
  import 'node:fs/promises';
8
9
  import 'micromatch';
9
10
  import 'unplugin';
10
11
  import '@tailwindcss-mangle/core';
12
+ import 'magic-string';
11
13
  import './shared/unplugin-tailwindcss-mangle.bbd58ece.mjs';
12
14
 
13
15
  const rollup = unplugin.rollup;
package/dist/vite.cjs CHANGED
@@ -6,10 +6,12 @@ require('node:path');
6
6
  require('@tailwindcss-mangle/shared');
7
7
  require('@tailwindcss-mangle/config');
8
8
  require('fast-sort');
9
+ require('modern-ahocorasick');
9
10
  require('node:fs/promises');
10
11
  require('micromatch');
11
12
  require('unplugin');
12
13
  require('@tailwindcss-mangle/core');
14
+ require('magic-string');
13
15
  require('./shared/unplugin-tailwindcss-mangle.e90953c3.cjs');
14
16
 
15
17
  const vite = index.vite;
package/dist/vite.mjs CHANGED
@@ -4,10 +4,12 @@ import 'node:path';
4
4
  import '@tailwindcss-mangle/shared';
5
5
  import '@tailwindcss-mangle/config';
6
6
  import 'fast-sort';
7
+ import 'modern-ahocorasick';
7
8
  import 'node:fs/promises';
8
9
  import 'micromatch';
9
10
  import 'unplugin';
10
11
  import '@tailwindcss-mangle/core';
12
+ import 'magic-string';
11
13
  import './shared/unplugin-tailwindcss-mangle.bbd58ece.mjs';
12
14
 
13
15
  const vite = unplugin.vite;
package/dist/webpack.cjs CHANGED
@@ -6,10 +6,12 @@ require('node:path');
6
6
  require('@tailwindcss-mangle/shared');
7
7
  require('@tailwindcss-mangle/config');
8
8
  require('fast-sort');
9
+ require('modern-ahocorasick');
9
10
  require('node:fs/promises');
10
11
  require('micromatch');
11
12
  require('unplugin');
12
13
  require('@tailwindcss-mangle/core');
14
+ require('magic-string');
13
15
  require('./shared/unplugin-tailwindcss-mangle.e90953c3.cjs');
14
16
 
15
17
  const webpack = index.webpack;
package/dist/webpack.mjs CHANGED
@@ -4,10 +4,12 @@ import 'node:path';
4
4
  import '@tailwindcss-mangle/shared';
5
5
  import '@tailwindcss-mangle/config';
6
6
  import 'fast-sort';
7
+ import 'modern-ahocorasick';
7
8
  import 'node:fs/promises';
8
9
  import 'micromatch';
9
10
  import 'unplugin';
10
11
  import '@tailwindcss-mangle/core';
12
+ import 'magic-string';
11
13
  import './shared/unplugin-tailwindcss-mangle.bbd58ece.mjs';
12
14
 
13
15
  const webpack = unplugin.webpack;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "unplugin-tailwindcss-mangle",
3
- "version": "2.0.4",
3
+ "version": "2.1.0",
4
4
  "description": "mangle tailwindcss utilities class plugin. support vite and webpack!",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",
@@ -66,11 +66,13 @@
66
66
  "license": "MIT",
67
67
  "dependencies": {
68
68
  "fast-sort": "^3.4.0",
69
+ "magic-string": "^0.30.2",
69
70
  "micromatch": "^4.0.5",
71
+ "modern-ahocorasick": "^1.0.0",
70
72
  "unplugin": "^1.4.0",
71
- "@tailwindcss-mangle/config": "^2.0.4",
72
- "@tailwindcss-mangle/core": "^2.0.4",
73
- "@tailwindcss-mangle/shared": "^2.0.4"
73
+ "@tailwindcss-mangle/config": "^2.1.0",
74
+ "@tailwindcss-mangle/core": "^2.1.0",
75
+ "@tailwindcss-mangle/shared": "^2.1.0"
74
76
  },
75
77
  "publishConfig": {
76
78
  "access": "public",
@@ -82,13 +84,14 @@
82
84
  "css-loader": "^6.8.1",
83
85
  "html-webpack-plugin": "^5.5.3",
84
86
  "mini-css-extract-plugin": "^2.7.6",
87
+ "normalize-newline": "^4.1.0",
85
88
  "postcss": "^8.4.27",
86
89
  "postcss-loader": "^7.3.3",
87
90
  "tailwindcss": "^3.3.3",
88
91
  "vite": "^4.4.9",
89
92
  "webpack": "^5.88.2",
90
93
  "webpack-build-utils": "^0.0.4",
91
- "tailwindcss-patch": "^2.0.4"
94
+ "tailwindcss-patch": "^2.1.0"
92
95
  },
93
96
  "homepage": "https://github.com/sonofmagic/tailwindcss-mangle",
94
97
  "repository": {