weapp-tailwindcss 4.12.0-next.0 → 5.0.0-next.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/bin/weapp-tailwindcss.js +21 -1
- package/dist/babel/index.d.ts +3 -0
- package/dist/bundlers/gulp/index.d.ts +7 -0
- package/dist/bundlers/shared/cache.d.ts +16 -0
- package/dist/bundlers/shared/css-cleanup.d.ts +4 -0
- package/dist/bundlers/shared/css-imports.d.ts +8 -0
- package/dist/bundlers/shared/generator-candidates.d.ts +5 -0
- package/dist/bundlers/shared/generator-css.d.ts +41 -0
- package/dist/bundlers/shared/module-graph.d.ts +5 -0
- package/dist/bundlers/shared/run-tasks.d.ts +2 -0
- package/dist/bundlers/vite/bundle-entries.d.ts +14 -0
- package/dist/bundlers/vite/bundle-state.d.ts +43 -0
- package/dist/bundlers/vite/css-finalizer.d.ts +19 -0
- package/dist/bundlers/vite/generate-bundle.d.ts +20 -0
- package/dist/bundlers/vite/incremental-runtime-class-set.d.ts +21 -0
- package/dist/bundlers/vite/index.d.ts +3 -0
- package/dist/bundlers/vite/js-precheck.d.ts +1 -0
- package/dist/bundlers/vite/query.d.ts +15 -0
- package/dist/bundlers/vite/resolve-app-type.d.ts +2 -0
- package/dist/bundlers/vite/rewrite-css-imports.d.ts +11 -0
- package/dist/bundlers/vite/runtime-affecting-signature.d.ts +2 -0
- package/dist/bundlers/vite/utils.d.ts +9 -0
- package/dist/bundlers/webpack/BaseUnifiedPlugin/shared.d.ts +20 -0
- package/dist/bundlers/webpack/BaseUnifiedPlugin/v4-assets.d.ts +14 -0
- package/dist/bundlers/webpack/BaseUnifiedPlugin/v4-loaders.d.ts +15 -0
- package/dist/bundlers/webpack/BaseUnifiedPlugin/v4.d.ts +9 -0
- package/dist/bundlers/webpack/BaseUnifiedPlugin/v5-assets.d.ts +17 -0
- package/dist/bundlers/webpack/BaseUnifiedPlugin/v5-loaders.d.ts +19 -0
- package/dist/bundlers/webpack/BaseUnifiedPlugin/v5.d.ts +9 -0
- package/dist/bundlers/webpack/index.d.ts +1 -0
- package/dist/bundlers/webpack/loaders/weapp-tw-css-import-rewrite-loader.d.ts +12 -0
- package/dist/bundlers/webpack/loaders/weapp-tw-runtime-classset-loader.d.ts +11 -0
- package/dist/bundlers/webpack/shared/css-imports.d.ts +6 -0
- package/dist/bundlers/webpack/shared/loader-anchors.d.ts +8 -0
- package/dist/cache/index.d.ts +38 -0
- package/dist/cache/md5.d.ts +1 -0
- package/dist/chunk-8l464Juk.js +28 -0
- package/dist/cli/config.d.ts +5 -0
- package/dist/cli/context.d.ts +16 -0
- package/dist/cli/doctor/constants.d.ts +7 -0
- package/dist/cli/doctor/types.d.ts +31 -0
- package/dist/cli/doctor.d.ts +4 -0
- package/dist/cli/helpers/options/format.d.ts +2 -0
- package/dist/cli/helpers/options/parse.d.ts +3 -0
- package/dist/cli/helpers/options/resolve.d.ts +1 -0
- package/dist/cli/helpers/options.d.ts +3 -0
- package/dist/cli/helpers/patch-cwd.d.ts +1 -0
- package/dist/cli/helpers.d.ts +5 -0
- package/dist/cli/mount-options/patch-status.d.ts +2 -0
- package/dist/cli/mount-options.d.ts +2 -0
- package/dist/cli/patch-options.d.ts +6 -0
- package/dist/cli/tokens.d.ts +4 -0
- package/dist/cli/types.d.ts +17 -0
- package/dist/cli/vscode-entry.d.ts +14 -0
- package/dist/cli/workspace/package-dirs.d.ts +3 -0
- package/dist/cli/workspace/patch-package.d.ts +3 -0
- package/dist/cli/workspace/patch-utils.d.ts +3 -0
- package/dist/cli/workspace/types.d.ts +11 -0
- package/dist/cli/workspace/workspace-globs.d.ts +2 -0
- package/dist/cli/workspace/workspace-io.d.ts +1 -0
- package/dist/cli/workspace/workspace-lock.d.ts +1 -0
- package/dist/cli/workspace.d.ts +2 -0
- package/dist/cli.d.ts +1 -2
- package/dist/cli.js +2517 -1544
- package/dist/cli.mjs +2493 -1524
- package/dist/constants-B-_T5UnW.mjs +44 -0
- package/dist/constants-p1dyh1x1.js +73 -0
- package/dist/constants.d.ts +13 -0
- package/dist/context/compiler-context-cache.d.ts +3 -0
- package/dist/context/custom-attributes.d.ts +2 -0
- package/dist/context/handlers.d.ts +6 -0
- package/dist/context/index.d.ts +7 -0
- package/dist/context/logger.d.ts +4 -0
- package/dist/context/tailwindcss/basedir.d.ts +1 -0
- package/dist/context/tailwindcss/rax.d.ts +2 -0
- package/dist/context/tailwindcss.d.ts +4 -0
- package/dist/context/workspace.d.ts +3 -0
- package/dist/core.d.ts +5 -21
- package/dist/core.js +138 -180
- package/dist/core.mjs +135 -180
- package/dist/css-imports-BbrbluP9.js +177 -0
- package/dist/css-imports-CSdPq_Sc.mjs +128 -0
- package/dist/css-macro/constants.d.ts +14 -0
- package/dist/css-macro/index.d.ts +15 -0
- package/dist/css-macro/postcss.d.ts +3 -7
- package/dist/css-macro/postcss.js +44 -58
- package/dist/css-macro/postcss.mjs +44 -56
- package/dist/css-macro.d.ts +1 -20
- package/dist/css-macro.js +37 -50
- package/dist/css-macro.mjs +33 -47
- package/dist/debug/index.d.ts +5 -0
- package/dist/defaults.d.ts +2 -11
- package/dist/defaults.js +132 -8
- package/dist/defaults.mjs +128 -7
- package/dist/escape.js +31 -54
- package/dist/escape.mjs +18 -25
- package/dist/experimental/index.d.ts +2 -0
- package/dist/experimental/oxc/ast-utils.d.ts +30 -0
- package/dist/experimental/oxc/index.d.ts +2 -0
- package/dist/experimental/oxc/module-specifiers.d.ts +2 -0
- package/dist/experimental/shared/cache.d.ts +3 -0
- package/dist/experimental/shared/transform.d.ts +3 -0
- package/dist/experimental/shared.d.ts +8 -0
- package/dist/experimental/swc/ast-utils.d.ts +30 -0
- package/dist/experimental/swc/index.d.ts +2 -0
- package/dist/experimental/swc/module-specifiers.d.ts +2 -0
- package/dist/generator/index.d.ts +11 -0
- package/dist/generator/options.d.ts +15 -0
- package/dist/generator/types.d.ts +19 -0
- package/dist/generator-CZ-JXw6T.js +492 -0
- package/dist/generator-Dwxgra97.mjs +399 -0
- package/dist/generator-css-CnYjiMrD.js +1084 -0
- package/dist/generator-css-DhPFjSzK.mjs +1057 -0
- package/dist/generator.d.ts +1 -0
- package/dist/generator.js +19 -0
- package/dist/generator.mjs +2 -0
- package/dist/gulp.d.ts +4 -24
- package/dist/gulp.js +271 -13
- package/dist/gulp.mjs +263 -13
- package/dist/index.d.ts +8 -15
- package/dist/index.js +12 -24
- package/dist/index.mjs +6 -24
- package/dist/js/JsTokenUpdater.d.ts +14 -0
- package/dist/js/ModuleGraph.d.ts +18 -0
- package/dist/js/NodePathWalker.d.ts +33 -0
- package/dist/js/babel/parse.d.ts +9 -0
- package/dist/js/babel/process.d.ts +4 -0
- package/dist/js/babel.d.ts +13 -0
- package/dist/js/class-context.d.ts +3 -0
- package/dist/js/evalTransforms.d.ts +7 -0
- package/dist/js/handlers.d.ts +5 -0
- package/dist/js/index.d.ts +4 -0
- package/dist/js/module-graph/ignored-exports.d.ts +18 -0
- package/dist/js/module-graph/types.d.ts +17 -0
- package/dist/js/node-path-walker/export-handlers.d.ts +12 -0
- package/dist/js/node-path-walker/import-tokens.d.ts +24 -0
- package/dist/js/precheck.d.ts +2 -0
- package/dist/js/sourceAnalysis.d.ts +17 -0
- package/dist/js/syntax.d.ts +10 -0
- package/dist/js/taggedTemplateIgnore.d.ts +13 -0
- package/dist/js/types.d.ts +11 -0
- package/dist/lightningcss/index.d.ts +8 -0
- package/dist/lightningcss/style-handler/options.d.ts +3 -0
- package/dist/lightningcss/style-handler/selector-transform.d.ts +10 -0
- package/dist/lightningcss/style-handler/selector-utils.d.ts +10 -0
- package/dist/lightningcss/style-handler.d.ts +17 -0
- package/dist/loader-anchors-DvwgIYdA.mjs +205 -0
- package/dist/loader-anchors-cprm4Klq.js +273 -0
- package/dist/logger/index.d.ts +2 -0
- package/dist/logger-BZ45DZJT.js +1003 -0
- package/dist/logger-BoVx1Dbt.mjs +935 -0
- package/dist/patcher-options-6gJN2EXy.js +115 -0
- package/dist/patcher-options-DQfR5xxT.mjs +92 -0
- package/dist/postcss-html-transform.d.ts +3 -3
- package/dist/postcss-html-transform.js +7 -10
- package/dist/postcss-html-transform.mjs +3 -6
- package/dist/postcss.d.ts +15 -0
- package/dist/postcss.js +278 -0
- package/dist/postcss.mjs +268 -0
- package/dist/presets/hbuilderx.d.ts +4 -0
- package/dist/presets/index.d.ts +3 -0
- package/dist/presets/shared.d.ts +10 -0
- package/dist/presets/taro.d.ts +4 -0
- package/dist/presets/uni-app-x.d.ts +16 -0
- package/dist/presets/uni-app.d.ts +4 -0
- package/dist/presets.d.ts +1 -76
- package/dist/presets.js +115 -163
- package/dist/presets.mjs +107 -163
- package/dist/recorder-B_XyZ576.mjs +2763 -0
- package/dist/recorder-rn_2v_nd.js +2878 -0
- package/dist/reset/index.d.ts +2 -0
- package/dist/reset.d.ts +1 -4
- package/dist/reset.js +19 -8
- package/dist/reset.mjs +2 -8
- package/dist/shared/classname-transform.d.ts +14 -0
- package/dist/shared/mpx.d.ts +7 -0
- package/dist/shared/tailwindcss-css-redirect.d.ts +1 -0
- package/dist/tailwindcss/index.d.ts +11 -0
- package/dist/tailwindcss/miniprogram.d.ts +1 -0
- package/dist/tailwindcss/patcher-options.d.ts +56 -0
- package/dist/tailwindcss/patcher-resolve.d.ts +4 -0
- package/dist/tailwindcss/patcher.d.ts +13 -0
- package/dist/tailwindcss/recorder.d.ts +13 -0
- package/dist/tailwindcss/remove-unsupported-css.d.ts +2 -0
- package/dist/tailwindcss/runtime/cache.d.ts +11 -0
- package/dist/tailwindcss/runtime-logs.d.ts +3 -0
- package/dist/tailwindcss/runtime.d.ts +29 -0
- package/dist/tailwindcss/targets/paths.d.ts +13 -0
- package/dist/tailwindcss/targets/record-io.d.ts +5 -0
- package/dist/tailwindcss/targets/recorder.d.ts +3 -0
- package/dist/tailwindcss/targets/types.d.ts +35 -0
- package/dist/tailwindcss/targets.d.ts +6 -0
- package/dist/tailwindcss/v3-engine/generator.d.ts +2 -0
- package/dist/tailwindcss/v3-engine/index.d.ts +4 -0
- package/dist/tailwindcss/v3-engine/miniprogram.d.ts +4 -0
- package/dist/tailwindcss/v3-engine/source.d.ts +5 -0
- package/dist/tailwindcss/v3-engine/types.d.ts +55 -0
- package/dist/tailwindcss/v4/config.d.ts +5 -0
- package/dist/tailwindcss/v4/css-entries.d.ts +7 -0
- package/dist/tailwindcss/v4/index.d.ts +2 -0
- package/dist/tailwindcss/v4/multi-patcher.d.ts +2 -0
- package/dist/tailwindcss/v4/patcher-options.d.ts +24 -0
- package/dist/tailwindcss/v4/patcher.d.ts +14 -0
- package/dist/tailwindcss/v4-engine/design-system.d.ts +1 -0
- package/dist/tailwindcss/v4-engine/generator.d.ts +2 -0
- package/dist/tailwindcss/v4-engine/index.d.ts +5 -0
- package/dist/tailwindcss/v4-engine/miniprogram.d.ts +4 -0
- package/dist/tailwindcss/v4-engine/source.d.ts +7 -0
- package/dist/tailwindcss/v4-engine/types.d.ts +17 -0
- package/dist/typedoc.export.d.ts +5 -0
- package/dist/types/base.d.ts +1 -0
- package/dist/types/disabled-options.d.ts +4 -0
- package/dist/types/index.d.ts +104 -0
- package/dist/types/shared.d.ts +7 -0
- package/dist/types/user-defined-options/general.d.ts +31 -0
- package/dist/types/user-defined-options/important.d.ts +37 -0
- package/dist/types/user-defined-options/index.d.ts +11 -0
- package/dist/types/user-defined-options/lifecycle.d.ts +6 -0
- package/dist/types/user-defined-options/matcher.d.ts +9 -0
- package/dist/types.d.ts +1 -150
- package/dist/types.js +0 -1
- package/dist/types.mjs +1 -1
- package/dist/uni-app-x/component-local-style.d.ts +19 -0
- package/dist/uni-app-x/index.d.ts +2 -0
- package/dist/uni-app-x/options.d.ts +12 -0
- package/dist/uni-app-x/style-isolation.d.ts +2 -0
- package/dist/uni-app-x/transform.d.ts +9 -0
- package/dist/uni-app-x/vite.d.ts +36 -0
- package/dist/utils/decode.d.ts +2 -0
- package/dist/utils/disabled.d.ts +6 -0
- package/dist/utils/hbuilderx.d.ts +5 -0
- package/dist/utils/index.d.ts +7 -0
- package/dist/utils/nameMatcher.d.ts +4 -0
- package/dist/utils/resolve-package.d.ts +1 -0
- package/dist/utils/uni-platform.d.ts +11 -0
- package/dist/utils-7DUGTFED.mjs +48 -0
- package/dist/utils-DmC9_In3.js +61 -0
- package/dist/vite-BHpAqldo.js +1952 -0
- package/dist/vite-C8JlHiyR.mjs +1940 -0
- package/dist/vite.d.ts +4 -17
- package/dist/vite.js +5 -14
- package/dist/vite.mjs +2 -14
- package/dist/weapp-tw-css-import-rewrite-loader.js +59 -87
- package/dist/weapp-tw-runtime-classset-loader.js +33 -47
- package/dist/webpack-CABjKGGQ.mjs +441 -0
- package/dist/webpack-DNIJ0ysE.js +456 -0
- package/dist/webpack.d.ts +4 -25
- package/dist/webpack.js +6 -17
- package/dist/webpack.mjs +2 -17
- package/dist/webpack4.d.ts +4 -26
- package/dist/webpack4.js +379 -481
- package/dist/webpack4.mjs +370 -482
- package/dist/wxml/Tokenizer.d.ts +15 -0
- package/dist/wxml/custom-attributes.d.ts +4 -0
- package/dist/wxml/index.d.ts +2 -0
- package/dist/wxml/shared.d.ts +2 -0
- package/dist/wxml/tokenizer/types.d.ts +18 -0
- package/dist/wxml/utils/codegen/legacy-rewriter.d.ts +2 -0
- package/dist/wxml/utils/codegen/legacy-visitor.d.ts +8 -0
- package/dist/wxml/utils/codegen.d.ts +2 -0
- package/dist/wxml/utils/custom-template.d.ts +3 -0
- package/dist/wxml/utils/fragment-helpers.d.ts +6 -0
- package/dist/wxml/utils/fragment-updater.d.ts +4 -0
- package/dist/wxml/utils/template-fragments.d.ts +3 -0
- package/dist/wxml/utils.d.ts +8 -0
- package/dist/wxml/whitespace.d.ts +2 -0
- package/generator-placeholder.css +1 -0
- package/package.json +28 -13
- package/scripts/postinstall.mjs +59 -0
- package/dist/chunk-2LH6PZH3.mjs +0 -51
- package/dist/chunk-4AFQP74Z.js +0 -24
- package/dist/chunk-5ONE75V7.js +0 -2381
- package/dist/chunk-76S2EME4.mjs +0 -34
- package/dist/chunk-A5PB4KZT.js +0 -138
- package/dist/chunk-AYJ4HLWZ.mjs +0 -1508
- package/dist/chunk-DYLQ6UOI.js +0 -71
- package/dist/chunk-F2CKKG6Q.mjs +0 -171
- package/dist/chunk-F5XJWJYO.mjs +0 -582
- package/dist/chunk-FMK6SFQQ.js +0 -276
- package/dist/chunk-GC7WXUOW.js +0 -3906
- package/dist/chunk-GD4SQMVF.mjs +0 -2378
- package/dist/chunk-GMKSBLNY.js +0 -175
- package/dist/chunk-HL3US2OT.mjs +0 -10
- package/dist/chunk-LVSUBDJC.js +0 -579
- package/dist/chunk-NIS74SI6.js +0 -1511
- package/dist/chunk-OF6MFURR.js +0 -34
- package/dist/chunk-ONLKZIRQ.js +0 -7
- package/dist/chunk-OOHJLO5M.mjs +0 -71
- package/dist/chunk-OYSABARD.js +0 -51
- package/dist/chunk-QNRJCEZN.mjs +0 -3906
- package/dist/chunk-UUJWDME4.mjs +0 -276
- package/dist/chunk-WSS26HZS.js +0 -292
- package/dist/chunk-XAKAD2CR.mjs +0 -138
- package/dist/chunk-ZR3KN3FG.mjs +0 -292
- package/dist/cli.d.mts +0 -2
- package/dist/core.d.mts +0 -26
- package/dist/css-macro/postcss.d.mts +0 -7
- package/dist/css-macro.d.mts +0 -18
- package/dist/defaults.d.mts +0 -11
- package/dist/gulp.d.mts +0 -24
- package/dist/index-BXrmQelt.d.mts +0 -672
- package/dist/index-BXrmQelt.d.ts +0 -672
- package/dist/index.d.mts +0 -15
- package/dist/postcss-html-transform.d.mts +0 -2
- package/dist/presets.d.mts +0 -76
- package/dist/reset.d.mts +0 -1
- package/dist/types.d.mts +0 -150
- package/dist/vite.d.mts +0 -17
- package/dist/webpack.d.mts +0 -25
- package/dist/webpack4.d.mts +0 -26
package/dist/cli.mjs
CHANGED
|
@@ -1,1621 +1,2590 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
import process from "node:process";
|
|
3
3
|
import semver from "semver";
|
|
4
|
-
import { createTailwindcssPatchCli } from "tailwindcss-patch";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
import
|
|
8
|
-
import process12 from "process";
|
|
9
|
-
|
|
10
|
-
// src/context/index.ts
|
|
11
|
-
import { rm } from "fs/promises";
|
|
12
|
-
import { logger as logger11 } from "@weapp-tailwindcss/logger";
|
|
13
|
-
|
|
14
|
-
// src/cache/index.ts
|
|
4
|
+
import { TailwindcssPatcher, createTailwindcssPatchCli, normalizeOptions } from "tailwindcss-patch";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import { access, mkdir, rm, writeFile } from "node:fs/promises";
|
|
7
|
+
import { logger, logger as logger$1 } from "@weapp-tailwindcss/logger";
|
|
15
8
|
import { LRUCache } from "lru-cache";
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
import
|
|
19
|
-
|
|
20
|
-
// src/defaults.ts
|
|
21
|
-
import { isAllowedClassName, MappingChars2String } from "@weapp-core/escape";
|
|
22
|
-
|
|
23
|
-
// src/utils/index.ts
|
|
24
|
-
import { defu, defuOverrideArray, groupBy, isMap, isRegexp, noop, regExpTest, removeExt } from "@weapp-tailwindcss/shared";
|
|
25
|
-
|
|
26
|
-
// src/utils/hbuilderx.ts
|
|
27
|
-
import path from "path";
|
|
28
|
-
import process from "process";
|
|
29
|
-
|
|
30
|
-
// src/utils/uni-platform.ts
|
|
31
|
-
import process2 from "process";
|
|
32
|
-
|
|
33
|
-
// src/debug/index.ts
|
|
9
|
+
import { md5 as md5Hash } from "@weapp-tailwindcss/shared/node";
|
|
10
|
+
import { MappingChars2String, escape } from "@weapp-core/escape";
|
|
11
|
+
import "@weapp-tailwindcss/shared";
|
|
34
12
|
import _createDebug from "debug";
|
|
35
|
-
|
|
13
|
+
import { constants, existsSync, readFileSync } from "node:fs";
|
|
14
|
+
import "@weapp-tailwindcss/postcss";
|
|
15
|
+
import _babelTraverse from "@babel/traverse";
|
|
16
|
+
import { parse as parse$1 } from "@babel/parser";
|
|
17
|
+
import { escapeStringRegexp } from "@weapp-core/regex";
|
|
18
|
+
import MagicString from "magic-string";
|
|
19
|
+
import { jsStringEscape } from "@ast-core/escape";
|
|
20
|
+
import { splitCode } from "@weapp-tailwindcss/shared/extractors";
|
|
21
|
+
import "@babel/types";
|
|
22
|
+
import "htmlparser2";
|
|
23
|
+
import { getPackageInfoSync } from "local-pkg";
|
|
24
|
+
import fg from "fast-glob";
|
|
25
|
+
import { parse } from "yaml";
|
|
26
|
+
//#region src/debug/index.ts
|
|
27
|
+
const _debug = _createDebug("weapp-tw");
|
|
36
28
|
function createDebug(prefix) {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
var debug = createDebug("[tailwindcss:runtime] ");
|
|
55
|
-
|
|
56
|
-
// src/tailwindcss/runtime-logs.ts
|
|
57
|
-
import process3 from "process";
|
|
58
|
-
import { logger, pc } from "@weapp-tailwindcss/logger";
|
|
59
|
-
var runtimeLogDedupeHolder = globalThis;
|
|
60
|
-
var runtimeLogDedupe = runtimeLogDedupeHolder.__WEAPP_TW_RUNTIME_LOG_DEDUPE__ ?? (runtimeLogDedupeHolder.__WEAPP_TW_RUNTIME_LOG_DEDUPE__ = /* @__PURE__ */ new Set());
|
|
29
|
+
const debug = ((formatter, ...args) => {
|
|
30
|
+
return _debug((prefix ?? "") + formatter, ...args);
|
|
31
|
+
});
|
|
32
|
+
Object.defineProperty(debug, "enabled", {
|
|
33
|
+
enumerable: false,
|
|
34
|
+
configurable: false,
|
|
35
|
+
get() {
|
|
36
|
+
return _debug.enabled;
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
return debug;
|
|
40
|
+
}
|
|
41
|
+
createDebug("[tailwindcss:runtime] ");
|
|
42
|
+
//#endregion
|
|
43
|
+
//#region src/tailwindcss/runtime-logs.ts
|
|
44
|
+
const runtimeLogDedupeHolder = globalThis;
|
|
45
|
+
const runtimeLogDedupe = runtimeLogDedupeHolder.__WEAPP_TW_RUNTIME_LOG_DEDUPE__ ?? (runtimeLogDedupeHolder.__WEAPP_TW_RUNTIME_LOG_DEDUPE__ = /* @__PURE__ */ new Set());
|
|
61
46
|
function createRuntimeLogKey(category, baseDir, rootPath, version) {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
47
|
+
return JSON.stringify([
|
|
48
|
+
category,
|
|
49
|
+
baseDir ?? process.cwd(),
|
|
50
|
+
rootPath ?? "",
|
|
51
|
+
version ?? ""
|
|
52
|
+
]);
|
|
68
53
|
}
|
|
69
54
|
function markRuntimeLog(category, baseDir, rootPath, version) {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
runtimeLogDedupe.add(key);
|
|
75
|
-
return true;
|
|
55
|
+
const key = createRuntimeLogKey(category, baseDir, rootPath, version);
|
|
56
|
+
if (runtimeLogDedupe.has(key)) return false;
|
|
57
|
+
runtimeLogDedupe.add(key);
|
|
58
|
+
return true;
|
|
76
59
|
}
|
|
77
60
|
function logRuntimeTailwindcssTarget(baseDir, rootPath, version) {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
// src/tailwindcss/targets.ts
|
|
86
|
-
import process6 from "process";
|
|
87
|
-
import { logger as logger3 } from "@weapp-tailwindcss/logger";
|
|
88
|
-
|
|
89
|
-
// src/tailwindcss/targets/paths.ts
|
|
90
|
-
import { existsSync as existsSync2 } from "fs";
|
|
91
|
-
import path3 from "path";
|
|
92
|
-
|
|
93
|
-
// src/context/workspace.ts
|
|
94
|
-
import { existsSync, readdirSync, readFileSync } from "fs";
|
|
95
|
-
import path2 from "path";
|
|
61
|
+
if (!markRuntimeLog("target", baseDir, rootPath, version)) return;
|
|
62
|
+
const versionText = version ? ` (v${version})` : "";
|
|
63
|
+
logger.info("%s 使用 Tailwind CSS%s", "Weapp-tailwindcss", versionText);
|
|
64
|
+
}
|
|
65
|
+
//#endregion
|
|
66
|
+
//#region src/context/workspace.ts
|
|
96
67
|
function findWorkspaceRoot(startDir) {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
}
|
|
106
|
-
const parent = path2.dirname(current);
|
|
107
|
-
if (parent === current) {
|
|
108
|
-
return void 0;
|
|
109
|
-
}
|
|
110
|
-
current = parent;
|
|
111
|
-
}
|
|
68
|
+
if (!startDir) return;
|
|
69
|
+
let current = path.resolve(startDir);
|
|
70
|
+
while (true) {
|
|
71
|
+
if (existsSync(path.join(current, "pnpm-workspace.yaml"))) return current;
|
|
72
|
+
const parent = path.dirname(current);
|
|
73
|
+
if (parent === current) return;
|
|
74
|
+
current = parent;
|
|
75
|
+
}
|
|
112
76
|
}
|
|
113
77
|
function findNearestPackageRoot(startDir) {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
// src/tailwindcss/targets/paths.ts
|
|
132
|
-
var PATCH_INFO_FILENAME = "tailwindcss-target.json";
|
|
133
|
-
var PATCH_INFO_CACHE_RELATIVE_PATH = path3.join("node_modules", ".cache", "weapp-tailwindcss", PATCH_INFO_FILENAME);
|
|
134
|
-
var PATCH_INFO_LEGACY_RELATIVE_PATH = path3.join(".tw-patch", PATCH_INFO_FILENAME);
|
|
78
|
+
if (!startDir) return;
|
|
79
|
+
let current = path.resolve(startDir);
|
|
80
|
+
while (true) {
|
|
81
|
+
if (existsSync(path.join(current, "package.json"))) return current;
|
|
82
|
+
const parent = path.dirname(current);
|
|
83
|
+
if (parent === current) return;
|
|
84
|
+
current = parent;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
//#endregion
|
|
88
|
+
//#region src/tailwindcss/targets/paths.ts
|
|
89
|
+
const PATCH_INFO_FILENAME = "tailwindcss-target.json";
|
|
90
|
+
const PATCH_INFO_CACHE_RELATIVE_PATH = path.join("node_modules", ".cache", "weapp-tailwindcss", PATCH_INFO_FILENAME);
|
|
91
|
+
const PATCH_INFO_LEGACY_RELATIVE_PATH = path.join(".tw-patch", PATCH_INFO_FILENAME);
|
|
92
|
+
function toDisplayPath(value) {
|
|
93
|
+
return path.normalize(value).replace(/\\/g, "/");
|
|
94
|
+
}
|
|
135
95
|
function formatRelativeToBase(targetPath, baseDir) {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
return ".";
|
|
142
|
-
}
|
|
143
|
-
if (relative.startsWith("..")) {
|
|
144
|
-
return path3.normalize(targetPath);
|
|
145
|
-
}
|
|
146
|
-
return path3.join(".", relative);
|
|
96
|
+
if (!baseDir) return toDisplayPath(targetPath);
|
|
97
|
+
const relative = path.relative(baseDir, targetPath);
|
|
98
|
+
if (!relative || relative === ".") return ".";
|
|
99
|
+
if (relative.startsWith("..")) return toDisplayPath(targetPath);
|
|
100
|
+
return toDisplayPath(path.join(".", relative));
|
|
147
101
|
}
|
|
148
102
|
function resolveRecordLocation(baseDir) {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
};
|
|
103
|
+
const normalizedBase = path.normalize(baseDir);
|
|
104
|
+
const packageRoot = findNearestPackageRoot(normalizedBase) ?? normalizedBase;
|
|
105
|
+
const packageJsonPath = path.join(packageRoot, "package.json");
|
|
106
|
+
const hasPackageJson = existsSync(packageJsonPath);
|
|
107
|
+
const recordKeySource = hasPackageJson ? packageJsonPath : normalizedBase;
|
|
108
|
+
const recordKey = md5Hash(path.normalize(recordKeySource));
|
|
109
|
+
const recordDir = path.join(packageRoot, "node_modules", ".cache", "weapp-tailwindcss", recordKey);
|
|
110
|
+
return {
|
|
111
|
+
normalizedBase,
|
|
112
|
+
packageRoot,
|
|
113
|
+
recordDir,
|
|
114
|
+
recordKey,
|
|
115
|
+
recordPath: path.join(recordDir, PATCH_INFO_FILENAME),
|
|
116
|
+
packageJsonPath: hasPackageJson ? packageJsonPath : void 0
|
|
117
|
+
};
|
|
165
118
|
}
|
|
166
119
|
function getRecordFileCandidates(baseDir) {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
var package_default = {
|
|
186
|
-
name: "weapp-tailwindcss",
|
|
187
|
-
version: "4.12.0-next.0",
|
|
188
|
-
description: "\u628A tailwindcss \u539F\u5B50\u5316\u6837\u5F0F\u601D\u60F3\uFF0C\u5E26\u7ED9\u5C0F\u7A0B\u5E8F\u5F00\u53D1\u8005\u4EEC! bring tailwindcss to miniprogram developers!",
|
|
189
|
-
author: "ice breaker <1324318532@qq.com>",
|
|
190
|
-
license: "MIT",
|
|
191
|
-
homepage: "https://tw.icebreaker.top",
|
|
192
|
-
repository: {
|
|
193
|
-
type: "git",
|
|
194
|
-
url: "git+https://github.com/sonofmagic/weapp-tailwindcss.git",
|
|
195
|
-
directory: "packages/weapp-tailwindcss"
|
|
196
|
-
},
|
|
197
|
-
bugs: {
|
|
198
|
-
url: "https://github.com/sonofmagic/weapp-tailwindcss/issues"
|
|
199
|
-
},
|
|
200
|
-
keywords: [
|
|
201
|
-
"tailwindcss",
|
|
202
|
-
"weapp",
|
|
203
|
-
"wechat",
|
|
204
|
-
"mini",
|
|
205
|
-
"miniprogram",
|
|
206
|
-
"mini app",
|
|
207
|
-
"weapp-tw",
|
|
208
|
-
"weapp-tailwindcss",
|
|
209
|
-
"taro",
|
|
210
|
-
"uni-app",
|
|
211
|
-
"remax",
|
|
212
|
-
"rax",
|
|
213
|
-
"mpx",
|
|
214
|
-
"jit",
|
|
215
|
-
"mp",
|
|
216
|
-
"android",
|
|
217
|
-
"ios",
|
|
218
|
-
"\u5C0F\u7A0B\u5E8F",
|
|
219
|
-
"vite",
|
|
220
|
-
"postcss",
|
|
221
|
-
"webpack",
|
|
222
|
-
"webpack-plugin",
|
|
223
|
-
"gulp",
|
|
224
|
-
"gulp-plugin"
|
|
225
|
-
],
|
|
226
|
-
exports: {
|
|
227
|
-
".": {
|
|
228
|
-
style: "./index.css",
|
|
229
|
-
types: "./dist/index.d.ts",
|
|
230
|
-
import: "./dist/index.mjs",
|
|
231
|
-
require: "./dist/index.js"
|
|
232
|
-
},
|
|
233
|
-
"./escape": {
|
|
234
|
-
types: "./dist/escape.d.ts",
|
|
235
|
-
import: "./dist/escape.mjs",
|
|
236
|
-
require: "./dist/escape.js"
|
|
237
|
-
},
|
|
238
|
-
"./vite": {
|
|
239
|
-
types: "./dist/vite.d.ts",
|
|
240
|
-
import: "./dist/vite.mjs",
|
|
241
|
-
require: "./dist/vite.js"
|
|
242
|
-
},
|
|
243
|
-
"./webpack": {
|
|
244
|
-
types: "./dist/webpack.d.ts",
|
|
245
|
-
import: "./dist/webpack.mjs",
|
|
246
|
-
require: "./dist/webpack.js"
|
|
247
|
-
},
|
|
248
|
-
"./webpack4": {
|
|
249
|
-
types: "./dist/webpack4.d.ts",
|
|
250
|
-
import: "./dist/webpack4.mjs",
|
|
251
|
-
require: "./dist/webpack4.js"
|
|
252
|
-
},
|
|
253
|
-
"./core": {
|
|
254
|
-
types: "./dist/core.d.ts",
|
|
255
|
-
import: "./dist/core.mjs",
|
|
256
|
-
require: "./dist/core.js"
|
|
257
|
-
},
|
|
258
|
-
"./gulp": {
|
|
259
|
-
types: "./dist/gulp.d.ts",
|
|
260
|
-
import: "./dist/gulp.mjs",
|
|
261
|
-
require: "./dist/gulp.js"
|
|
262
|
-
},
|
|
263
|
-
"./defaults": {
|
|
264
|
-
types: "./dist/defaults.d.ts",
|
|
265
|
-
import: "./dist/defaults.mjs",
|
|
266
|
-
require: "./dist/defaults.js"
|
|
267
|
-
},
|
|
268
|
-
"./presets": {
|
|
269
|
-
types: "./dist/presets.d.ts",
|
|
270
|
-
import: "./dist/presets.mjs",
|
|
271
|
-
require: "./dist/presets.js"
|
|
272
|
-
},
|
|
273
|
-
"./reset": {
|
|
274
|
-
types: "./dist/reset.d.ts",
|
|
275
|
-
import: "./dist/reset.mjs",
|
|
276
|
-
require: "./dist/reset.js"
|
|
277
|
-
},
|
|
278
|
-
"./css-macro/postcss": {
|
|
279
|
-
types: "./dist/css-macro/postcss.d.ts",
|
|
280
|
-
import: "./dist/css-macro/postcss.mjs",
|
|
281
|
-
require: "./dist/css-macro/postcss.js"
|
|
282
|
-
},
|
|
283
|
-
"./css-macro": {
|
|
284
|
-
types: "./dist/css-macro.d.ts",
|
|
285
|
-
import: "./dist/css-macro.mjs",
|
|
286
|
-
require: "./dist/css-macro.js"
|
|
287
|
-
},
|
|
288
|
-
"./types": {
|
|
289
|
-
types: "./dist/types.d.ts",
|
|
290
|
-
import: "./dist/types.mjs",
|
|
291
|
-
require: "./dist/types.js"
|
|
292
|
-
},
|
|
293
|
-
"./postcss-html-transform": {
|
|
294
|
-
types: "./dist/postcss-html-transform.d.ts",
|
|
295
|
-
import: "./dist/postcss-html-transform.mjs",
|
|
296
|
-
require: "./dist/postcss-html-transform.js"
|
|
297
|
-
},
|
|
298
|
-
"./package.json": "./package.json",
|
|
299
|
-
"./index.css": "./index.css",
|
|
300
|
-
"./index": "./index.css",
|
|
301
|
-
"./preflight.css": "./preflight.css",
|
|
302
|
-
"./preflight": "./preflight.css",
|
|
303
|
-
"./theme.css": "./theme.css",
|
|
304
|
-
"./theme": "./theme.css",
|
|
305
|
-
"./utilities.css": "./utilities.css",
|
|
306
|
-
"./utilities": "./utilities.css",
|
|
307
|
-
"./with-layer.css": "./with-layer.css",
|
|
308
|
-
"./with-layer": "./with-layer.css",
|
|
309
|
-
"./uni-app-x": "./uni-app-x.css",
|
|
310
|
-
"./uni-app-x.css": "./uni-app-x.css",
|
|
311
|
-
"./css": "./css/index.css",
|
|
312
|
-
"./*": "./*"
|
|
313
|
-
},
|
|
314
|
-
main: "./dist/index.js",
|
|
315
|
-
module: "./dist/index.mjs",
|
|
316
|
-
types: "./dist/index.d.ts",
|
|
317
|
-
style: "index.css",
|
|
318
|
-
typesVersions: {
|
|
319
|
-
"*": {
|
|
320
|
-
"*": [
|
|
321
|
-
"./dist/*",
|
|
322
|
-
"./dist/index.d.ts"
|
|
323
|
-
]
|
|
324
|
-
}
|
|
325
|
-
},
|
|
326
|
-
bin: {
|
|
327
|
-
"weapp-tailwindcss-webpack-plugin": "bin/weapp-tailwindcss.js",
|
|
328
|
-
"weapp-tailwindcss": "bin/weapp-tailwindcss.js",
|
|
329
|
-
"weapp-tw": "bin/weapp-tailwindcss.js"
|
|
330
|
-
},
|
|
331
|
-
files: [
|
|
332
|
-
"bin",
|
|
333
|
-
"css",
|
|
334
|
-
"dist",
|
|
335
|
-
"index.css",
|
|
336
|
-
"preflight.css",
|
|
337
|
-
"theme.css",
|
|
338
|
-
"uni-app-x.css",
|
|
339
|
-
"utilities.css",
|
|
340
|
-
"with-layer.css"
|
|
341
|
-
],
|
|
342
|
-
engines: {
|
|
343
|
-
node: "^18.17.0 || >=20.5.0"
|
|
344
|
-
},
|
|
345
|
-
scripts: {
|
|
346
|
-
dev: "tsup --watch --sourcemap",
|
|
347
|
-
build: "tsup && node scripts/ensure-escape-dts.mjs",
|
|
348
|
-
"build:tsc": "cross-env NODE_ENV=development tsc --build tsconfig.json",
|
|
349
|
-
"build:cli": "cd plugins/cli && pnpm run build",
|
|
350
|
-
"build:css": "tsx scripts/build-css.ts",
|
|
351
|
-
"build:weapp-theme": "tsx scripts/build-weapp-theme.ts",
|
|
352
|
-
test: "npm run postinstall && vitest run",
|
|
353
|
-
"test:dev": "vitest",
|
|
354
|
-
"test:ui": "vitest --ui",
|
|
355
|
-
bench: "vitest bench --config ./vitest.config.ts",
|
|
356
|
-
"bench:vite-perf": "tsx scripts/vite-perf-bench.ts",
|
|
357
|
-
"bench:vite-perf:summary": "tsx scripts/vite-perf-summary.ts",
|
|
358
|
-
"bench:js-handlers": "tsx scripts/js-bench.ts",
|
|
359
|
-
"bench:js-diff": "tsx scripts/js-bench-diff.ts",
|
|
360
|
-
tsd: "tsd",
|
|
361
|
-
clean: "tsx scripts/clean.ts",
|
|
362
|
-
"get-decl": "tsx scripts/get-decl.ts",
|
|
363
|
-
"ls:pack": "npm pack --dry-run",
|
|
364
|
-
"cli:patch": "node bin/weapp-tailwindcss.js patch",
|
|
365
|
-
colors: "tsx scripts/colors.ts",
|
|
366
|
-
release: "tsx scripts/release.ts",
|
|
367
|
-
lint: "eslint .",
|
|
368
|
-
"lint:fix": "eslint ./src --fix",
|
|
369
|
-
postinstall: "node bin/weapp-tailwindcss.js patch",
|
|
370
|
-
"bench:vite-dev-hmr": "tsx scripts/vite-dev-hmr-bench.ts",
|
|
371
|
-
"test:watch-hmr": "node --import tsx scripts/watch-hmr-regression/index.ts"
|
|
372
|
-
},
|
|
373
|
-
publishConfig: {
|
|
374
|
-
access: "public",
|
|
375
|
-
registry: "https://registry.npmjs.org"
|
|
376
|
-
},
|
|
377
|
-
dependencies: {
|
|
378
|
-
"@ast-core/escape": "~1.0.1",
|
|
379
|
-
"@babel/parser": "~7.29.2",
|
|
380
|
-
"@babel/traverse": "~7.29.0",
|
|
381
|
-
"@babel/types": "~7.29.0",
|
|
382
|
-
"@tailwindcss-mangle/config": "^7.0.0",
|
|
383
|
-
"@vue/compiler-dom": "catalog:vue3",
|
|
384
|
-
"@vue/compiler-sfc": "catalog:vue3",
|
|
385
|
-
"@weapp-core/escape": "~7.0.0",
|
|
386
|
-
"@weapp-core/regex": "~1.0.1",
|
|
387
|
-
"@weapp-tailwindcss/logger": "workspace:*",
|
|
388
|
-
"@weapp-tailwindcss/postcss": "workspace:*",
|
|
389
|
-
"@weapp-tailwindcss/reset": "workspace:*",
|
|
390
|
-
"@weapp-tailwindcss/shared": "workspace:*",
|
|
391
|
-
cac: "6.7.14",
|
|
392
|
-
"comment-json": "^4.6.2",
|
|
393
|
-
debug: "~4.4.3",
|
|
394
|
-
"fast-glob": "^3.3.3",
|
|
395
|
-
htmlparser2: "10.1.0",
|
|
396
|
-
"loader-utils": "2.0.4",
|
|
397
|
-
"local-pkg": "^1.1.2",
|
|
398
|
-
"lru-cache": "10.4.3",
|
|
399
|
-
"magic-string": "0.30.21",
|
|
400
|
-
semver: "~7.7.4",
|
|
401
|
-
"tailwindcss-patch": "catalog:tailwindcssPatch",
|
|
402
|
-
"webpack-sources": "3.3.4",
|
|
403
|
-
yaml: "^2.8.3"
|
|
404
|
-
},
|
|
405
|
-
devDependencies: {
|
|
406
|
-
"fast-check": "^4.7.0"
|
|
407
|
-
}
|
|
408
|
-
};
|
|
409
|
-
|
|
410
|
-
// src/constants.ts
|
|
411
|
-
var WEAPP_TW_REQUIRED_NODE_VERSION = "18.17.0";
|
|
412
|
-
var WEAPP_TW_VERSION = package_default.version;
|
|
413
|
-
|
|
414
|
-
// src/tailwindcss/targets/record-io.ts
|
|
415
|
-
var loggedInvalidPatchRecords = /* @__PURE__ */ new Set();
|
|
120
|
+
const { normalizedBase, packageRoot, recordPath } = resolveRecordLocation(baseDir);
|
|
121
|
+
return [...new Set([
|
|
122
|
+
recordPath,
|
|
123
|
+
path.join(packageRoot, PATCH_INFO_CACHE_RELATIVE_PATH),
|
|
124
|
+
path.join(normalizedBase, PATCH_INFO_CACHE_RELATIVE_PATH),
|
|
125
|
+
path.join(normalizedBase, PATCH_INFO_LEGACY_RELATIVE_PATH)
|
|
126
|
+
])];
|
|
127
|
+
}
|
|
128
|
+
//#endregion
|
|
129
|
+
//#region package.json
|
|
130
|
+
var version = "5.0.0-next.1";
|
|
131
|
+
//#endregion
|
|
132
|
+
//#region src/constants.ts
|
|
133
|
+
const WEAPP_TW_REQUIRED_NODE_VERSION_RANGE = "^20.19.0 || >=22.12.0";
|
|
134
|
+
const WEAPP_TW_VERSION = version;
|
|
135
|
+
//#endregion
|
|
136
|
+
//#region src/tailwindcss/targets/record-io.ts
|
|
137
|
+
const loggedInvalidPatchRecords = /* @__PURE__ */ new Set();
|
|
416
138
|
function warnInvalidPatchTargetRecord(baseDir, recordPath, reason) {
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
const reasonMessage = reason ? `\uFF1A${reason}` : "";
|
|
425
|
-
logger2.warn(
|
|
426
|
-
`\u68C0\u6D4B\u5230\u635F\u574F\u7684 Tailwind CSS \u76EE\u6807\u8BB0\u5F55 ${fileDisplay}${reasonMessage}\u3002\u8BF7\u5728 ${baseDisplay} \u91CD\u65B0\u6267\u884C "weapp-tw patch --record-target" \u6216\u5220\u9664\u8BE5\u6587\u4EF6\u540E\u518D\u8FD0\u884C\u3002`
|
|
427
|
-
);
|
|
139
|
+
const normalizedPath = path.normalize(recordPath);
|
|
140
|
+
if (loggedInvalidPatchRecords.has(normalizedPath)) return;
|
|
141
|
+
loggedInvalidPatchRecords.add(normalizedPath);
|
|
142
|
+
const fileDisplay = formatRelativeToBase(normalizedPath, baseDir);
|
|
143
|
+
const baseDisplay = formatRelativeToBase(path.normalize(baseDir), process.cwd());
|
|
144
|
+
const reasonMessage = reason ? `:${reason}` : "";
|
|
145
|
+
logger.warn(`检测到损坏的 Tailwind CSS 目标记录 ${fileDisplay}${reasonMessage}。请在 ${baseDisplay} 重新执行 "weapp-tw patch --record-target" 或删除该文件后再运行。`);
|
|
428
146
|
}
|
|
429
147
|
function readPatchTargetRecord(baseDir) {
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
const reason = error instanceof Error ? error.message : String(error);
|
|
452
|
-
warnInvalidPatchTargetRecord(normalizedBase, recordPath, reason);
|
|
453
|
-
continue;
|
|
454
|
-
}
|
|
455
|
-
}
|
|
456
|
-
return void 0;
|
|
148
|
+
if (!baseDir) return;
|
|
149
|
+
const normalizedBase = path.normalize(baseDir);
|
|
150
|
+
for (const recordPath of getRecordFileCandidates(normalizedBase)) {
|
|
151
|
+
if (!existsSync(recordPath)) continue;
|
|
152
|
+
try {
|
|
153
|
+
const content = readFileSync(recordPath, "utf8");
|
|
154
|
+
const parsed = JSON.parse(content);
|
|
155
|
+
if (!parsed || typeof parsed.tailwindPackagePath !== "string") {
|
|
156
|
+
warnInvalidPatchTargetRecord(normalizedBase, recordPath, "缺少 tailwindPackagePath 字段");
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
return {
|
|
160
|
+
baseDir: normalizedBase,
|
|
161
|
+
path: recordPath,
|
|
162
|
+
record: parsed
|
|
163
|
+
};
|
|
164
|
+
} catch (error) {
|
|
165
|
+
warnInvalidPatchTargetRecord(normalizedBase, recordPath, error instanceof Error ? error.message : String(error));
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
457
169
|
}
|
|
458
170
|
async function saveCliPatchTargetRecord(baseDir, patcher, options) {
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
);
|
|
488
|
-
logger2.debug("failed to persist patch target record %s: %O", recordPath, error);
|
|
489
|
-
return void 0;
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
// src/tailwindcss/targets/recorder.ts
|
|
494
|
-
import path5 from "path";
|
|
495
|
-
import process5 from "process";
|
|
171
|
+
if (!baseDir || !patcher?.packageInfo?.rootPath) return;
|
|
172
|
+
const normalizedBase = path.normalize(baseDir);
|
|
173
|
+
const location = resolveRecordLocation(normalizedBase);
|
|
174
|
+
const recordPath = options?.recordPath ? path.normalize(options.recordPath) : location.recordPath;
|
|
175
|
+
const record = {
|
|
176
|
+
tailwindPackagePath: path.normalize(patcher.packageInfo.rootPath),
|
|
177
|
+
packageVersion: patcher.packageInfo.version,
|
|
178
|
+
recordedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
179
|
+
source: options?.source ?? "cli",
|
|
180
|
+
tailwindcssBasedir: normalizedBase,
|
|
181
|
+
cwd: options?.cwd ? path.normalize(options.cwd) : normalizedBase,
|
|
182
|
+
patchVersion: WEAPP_TW_VERSION,
|
|
183
|
+
packageJsonPath: options?.packageJsonPath ?? location.packageJsonPath,
|
|
184
|
+
recordKey: options?.recordKey ?? location.recordKey
|
|
185
|
+
};
|
|
186
|
+
try {
|
|
187
|
+
await mkdir(path.dirname(recordPath), { recursive: true });
|
|
188
|
+
await writeFile(recordPath, `${JSON.stringify(record, null, 2)}\n`, "utf8");
|
|
189
|
+
return recordPath;
|
|
190
|
+
} catch (error) {
|
|
191
|
+
const baseDisplay = formatRelativeToBase(normalizedBase, process.cwd());
|
|
192
|
+
logger.warn("自动更新 Tailwind CSS 补丁记录失败,请在 %s 运行 \"weapp-tw patch --cwd %s\"。", baseDisplay, normalizedBase);
|
|
193
|
+
logger.debug("failed to persist patch target record %s: %O", recordPath, error);
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
//#endregion
|
|
198
|
+
//#region src/tailwindcss/targets/recorder.ts
|
|
496
199
|
function findPatchTargetRecord(baseDir) {
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
}
|
|
509
|
-
visited.add(current);
|
|
510
|
-
current = parent;
|
|
511
|
-
}
|
|
512
|
-
return void 0;
|
|
200
|
+
const visited = /* @__PURE__ */ new Set();
|
|
201
|
+
const fallback = baseDir ?? process.cwd();
|
|
202
|
+
let current = path.resolve(fallback);
|
|
203
|
+
while (!visited.has(current)) {
|
|
204
|
+
const record = readPatchTargetRecord(current);
|
|
205
|
+
if (record) return record;
|
|
206
|
+
const parent = path.dirname(current);
|
|
207
|
+
if (parent === current) break;
|
|
208
|
+
visited.add(current);
|
|
209
|
+
current = parent;
|
|
210
|
+
}
|
|
513
211
|
}
|
|
514
212
|
function createPatchTargetRecorder(baseDir, patcher, options) {
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
const onPatched = async () => saveCliPatchTargetRecord(normalizedBase, patcher, {
|
|
559
|
-
cwd: options?.cwd ?? normalizedBase,
|
|
560
|
-
source: options?.source ?? "cli",
|
|
561
|
-
recordPath: location.recordPath,
|
|
562
|
-
recordKey: location.recordKey,
|
|
563
|
-
packageJsonPath: location.packageJsonPath
|
|
564
|
-
});
|
|
565
|
-
return {
|
|
566
|
-
recordPath: location.recordPath,
|
|
567
|
-
message,
|
|
568
|
-
reason,
|
|
569
|
-
onPatched
|
|
570
|
-
};
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
// src/tailwindcss/targets.ts
|
|
213
|
+
if (!baseDir || !patcher?.packageInfo?.rootPath || options?.recordTarget === false) return;
|
|
214
|
+
const normalizedBase = path.normalize(baseDir);
|
|
215
|
+
const recorded = findPatchTargetRecord(normalizedBase);
|
|
216
|
+
const location = resolveRecordLocation(normalizedBase);
|
|
217
|
+
const expectedPath = path.normalize(patcher.packageInfo.rootPath);
|
|
218
|
+
let reason;
|
|
219
|
+
if (!recorded) reason = "missing";
|
|
220
|
+
else if (path.normalize(recorded.record.tailwindPackagePath) !== expectedPath) reason = "mismatch";
|
|
221
|
+
else if (path.normalize(recorded.path) !== path.normalize(location.recordPath) || !recorded.record.recordKey || recorded.record.recordKey !== location.recordKey) reason = "migrate";
|
|
222
|
+
else if (!recorded.record.patchVersion || recorded.record.patchVersion !== WEAPP_TW_VERSION) reason = "stale";
|
|
223
|
+
else if (options?.cwd && recorded.record.cwd && path.normalize(recorded.record.cwd) !== path.normalize(options.cwd)) reason = "metadata";
|
|
224
|
+
else if (!recorded.record.cwd && options?.cwd) reason = "metadata";
|
|
225
|
+
if (!(options?.alwaysRecord || !recorded || Boolean(reason))) return;
|
|
226
|
+
let message;
|
|
227
|
+
switch (reason) {
|
|
228
|
+
case "mismatch":
|
|
229
|
+
message = "检测到 Tailwind CSS 目标记录与当前解析结果不一致,正在自动重新 patch 并刷新缓存。";
|
|
230
|
+
break;
|
|
231
|
+
case "migrate":
|
|
232
|
+
case "stale":
|
|
233
|
+
message = "正在刷新当前子包的 Tailwind CSS 补丁记录,确保缓存隔离。";
|
|
234
|
+
break;
|
|
235
|
+
case "missing":
|
|
236
|
+
message = "未找到当前子包的 Tailwind CSS 目标记录,正在生成。";
|
|
237
|
+
break;
|
|
238
|
+
default: break;
|
|
239
|
+
}
|
|
240
|
+
const onPatched = async () => saveCliPatchTargetRecord(normalizedBase, patcher, {
|
|
241
|
+
cwd: options?.cwd ?? normalizedBase,
|
|
242
|
+
source: options?.source ?? "cli",
|
|
243
|
+
recordPath: location.recordPath,
|
|
244
|
+
recordKey: location.recordKey,
|
|
245
|
+
packageJsonPath: location.packageJsonPath
|
|
246
|
+
});
|
|
247
|
+
return {
|
|
248
|
+
recordPath: location.recordPath,
|
|
249
|
+
message,
|
|
250
|
+
reason,
|
|
251
|
+
onPatched
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
//#endregion
|
|
255
|
+
//#region src/tailwindcss/targets.ts
|
|
574
256
|
function logTailwindcssTarget(kind, patcher, baseDir) {
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
import { logger as logger4 } from "@weapp-tailwindcss/logger";
|
|
596
|
-
|
|
597
|
-
// src/tailwindcss/v4/patcher.ts
|
|
598
|
-
import { logger as logger6 } from "@weapp-tailwindcss/logger";
|
|
599
|
-
|
|
600
|
-
// src/tailwindcss/patcher.ts
|
|
601
|
-
import path7 from "path";
|
|
602
|
-
import process8 from "process";
|
|
603
|
-
import { logger as logger5 } from "@weapp-tailwindcss/logger";
|
|
604
|
-
import { defuOverrideArray as defuOverrideArray2 } from "@weapp-tailwindcss/shared";
|
|
605
|
-
import { TailwindcssPatcher } from "tailwindcss-patch";
|
|
606
|
-
|
|
607
|
-
// src/tailwindcss/patcher-resolve.ts
|
|
608
|
-
import { existsSync as existsSync4 } from "fs";
|
|
609
|
-
import { createRequire } from "module";
|
|
610
|
-
import path6 from "path";
|
|
611
|
-
import process7 from "process";
|
|
612
|
-
import { fileURLToPath } from "url";
|
|
613
|
-
|
|
614
|
-
// src/tailwindcss/v4/css-entries.ts
|
|
615
|
-
import path8 from "path";
|
|
616
|
-
|
|
617
|
-
// src/context/compiler-context-cache.ts
|
|
618
|
-
import { Buffer } from "buffer";
|
|
619
|
-
import path9 from "path";
|
|
620
|
-
import process9 from "process";
|
|
621
|
-
import { logger as logger7 } from "@weapp-tailwindcss/logger";
|
|
622
|
-
var globalCacheHolder = globalThis;
|
|
623
|
-
var compilerContextCache = globalCacheHolder.__WEAPP_TW_COMPILER_CONTEXT_CACHE__ ?? (globalCacheHolder.__WEAPP_TW_COMPILER_CONTEXT_CACHE__ = /* @__PURE__ */ new Map());
|
|
624
|
-
|
|
625
|
-
// src/context/handlers.ts
|
|
626
|
-
import { createStyleHandler } from "@weapp-tailwindcss/postcss";
|
|
627
|
-
|
|
628
|
-
// src/js/index.ts
|
|
629
|
-
import { LRUCache as LRUCache3 } from "lru-cache";
|
|
630
|
-
|
|
631
|
-
// src/babel/index.ts
|
|
632
|
-
import _babelTraverse from "@babel/traverse";
|
|
633
|
-
import { parse, parseExpression } from "@babel/parser";
|
|
257
|
+
const packageInfo = patcher?.packageInfo;
|
|
258
|
+
const label = kind === "cli" ? "weapp-tw patch" : "Weapp-tailwindcss";
|
|
259
|
+
if (!packageInfo?.rootPath) {
|
|
260
|
+
logger.warn("%s 未找到 Tailwind CSS 依赖,请检查在 %s 是否已安装 tailwindcss", label, baseDir ?? process.cwd());
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
const displayPath = formatRelativeToBase(packageInfo.rootPath, baseDir);
|
|
264
|
+
const version = packageInfo.version ? ` (v${packageInfo.version})` : "";
|
|
265
|
+
if (kind === "runtime") {
|
|
266
|
+
logRuntimeTailwindcssTarget(baseDir, packageInfo.rootPath, packageInfo.version);
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
logger.info("%s 绑定 Tailwind CSS -> %s%s", label, displayPath, version);
|
|
270
|
+
}
|
|
271
|
+
//#endregion
|
|
272
|
+
//#region src/context/compiler-context-cache.ts
|
|
273
|
+
const globalCacheHolder = globalThis;
|
|
274
|
+
globalCacheHolder.__WEAPP_TW_COMPILER_CONTEXT_CACHE__ ?? (globalCacheHolder.__WEAPP_TW_COMPILER_CONTEXT_CACHE__ = /* @__PURE__ */ new Map());
|
|
275
|
+
//#endregion
|
|
276
|
+
//#region src/babel/index.ts
|
|
634
277
|
function _interopDefaultCompat(e) {
|
|
635
|
-
|
|
278
|
+
return e && typeof e === "object" && "default" in e ? e.default : e;
|
|
636
279
|
}
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
);
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
}
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
280
|
+
const traverse = _interopDefaultCompat(_babelTraverse);
|
|
281
|
+
//#endregion
|
|
282
|
+
//#region src/utils/nameMatcher.ts
|
|
283
|
+
const NEVER_MATCH_NAME$1 = () => false;
|
|
284
|
+
const GLOBAL_FLAG_REGEXP = /g/g;
|
|
285
|
+
function buildFuzzyMatcher(fuzzyStrings) {
|
|
286
|
+
if (fuzzyStrings.length === 0) return;
|
|
287
|
+
if (fuzzyStrings.length === 1) {
|
|
288
|
+
const [needle] = fuzzyStrings;
|
|
289
|
+
return (value) => value.includes(needle);
|
|
290
|
+
}
|
|
291
|
+
const unique = [...new Set(fuzzyStrings)];
|
|
292
|
+
const pattern = new RegExp(unique.map(escapeStringRegexp).join("|"));
|
|
293
|
+
return (value) => pattern.test(value);
|
|
294
|
+
}
|
|
295
|
+
function normaliseRegex(regex) {
|
|
296
|
+
const { source, flags } = regex;
|
|
297
|
+
if (!flags.includes("g")) return regex;
|
|
298
|
+
return new RegExp(source, flags.replace(GLOBAL_FLAG_REGEXP, ""));
|
|
299
|
+
}
|
|
300
|
+
function createNameMatcher(list, { exact = false } = {}) {
|
|
301
|
+
if (!list || list.length === 0) return NEVER_MATCH_NAME$1;
|
|
302
|
+
const exactStrings = exact ? /* @__PURE__ */ new Set() : void 0;
|
|
303
|
+
const fuzzyStrings = [];
|
|
304
|
+
const regexList = [];
|
|
305
|
+
for (const item of list) if (typeof item === "string") if (exact) exactStrings.add(item);
|
|
306
|
+
else fuzzyStrings.push(item);
|
|
307
|
+
else regexList.push(normaliseRegex(item));
|
|
308
|
+
if (exact) {
|
|
309
|
+
const exactStringCount = exactStrings?.size ?? 0;
|
|
310
|
+
if (exactStringCount === 1 && regexList.length === 0) {
|
|
311
|
+
const [needle] = exactStrings;
|
|
312
|
+
return (value) => value === needle;
|
|
313
|
+
}
|
|
314
|
+
if (regexList.length === 0) return (value) => exactStrings.has(value);
|
|
315
|
+
if (exactStringCount === 0 && regexList.length === 1) {
|
|
316
|
+
const [regex] = regexList;
|
|
317
|
+
return (value) => regex.test(value);
|
|
318
|
+
}
|
|
319
|
+
return (value) => {
|
|
320
|
+
if (exactStrings?.has(value)) return true;
|
|
321
|
+
return regexList.some((regex) => regex.test(value));
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
const fuzzyMatcher = exact ? void 0 : buildFuzzyMatcher(fuzzyStrings);
|
|
325
|
+
const hasRegex = regexList.length > 0;
|
|
326
|
+
if (fuzzyMatcher && !hasRegex) return fuzzyMatcher;
|
|
327
|
+
if (!fuzzyMatcher && regexList.length === 1) {
|
|
328
|
+
const [regex] = regexList;
|
|
329
|
+
return (value) => regex.test(value);
|
|
330
|
+
}
|
|
331
|
+
return (value) => {
|
|
332
|
+
if (fuzzyMatcher?.(value)) return true;
|
|
333
|
+
if (!hasRegex) return false;
|
|
334
|
+
return regexList.some((regex) => regex.test(value));
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
//#endregion
|
|
338
|
+
//#region src/js/babel/parse.ts
|
|
339
|
+
const parseCache = new LRUCache({ max: 1024 });
|
|
340
|
+
function genCacheKey(source, options) {
|
|
341
|
+
if (typeof options === "string") return source + options;
|
|
342
|
+
return source + JSON.stringify(options, (_, val) => typeof val === "function" ? val.toString() : val);
|
|
343
|
+
}
|
|
344
|
+
function babelParse(code, opts = {}) {
|
|
345
|
+
const { cache, cacheKey, ...rest } = opts;
|
|
346
|
+
const cacheKeyString = genCacheKey(code, cacheKey ?? rest);
|
|
347
|
+
let result;
|
|
348
|
+
if (cache) result = parseCache.get(cacheKeyString);
|
|
349
|
+
if (!result) {
|
|
350
|
+
const { cache: _cache, cacheKey: _cacheKey, ...parseOptions } = opts;
|
|
351
|
+
result = parse$1(code, parseOptions);
|
|
352
|
+
if (cache) parseCache.set(cacheKeyString, result);
|
|
353
|
+
}
|
|
354
|
+
return result;
|
|
355
|
+
}
|
|
356
|
+
//#endregion
|
|
357
|
+
//#region src/wxml/shared.ts
|
|
358
|
+
const NEWLINE_RE = /[\n\r]+/g;
|
|
359
|
+
function replaceWxml(original, options = {
|
|
360
|
+
keepEOL: false,
|
|
361
|
+
escapeMap: MappingChars2String
|
|
362
|
+
}) {
|
|
363
|
+
const { keepEOL, escapeMap, ignoreHead } = options;
|
|
364
|
+
let res = original;
|
|
365
|
+
if (!keepEOL) res = res.replaceAll(NEWLINE_RE, "");
|
|
366
|
+
res = escape(res, {
|
|
367
|
+
map: escapeMap,
|
|
368
|
+
ignoreHead
|
|
369
|
+
});
|
|
370
|
+
return res;
|
|
371
|
+
}
|
|
372
|
+
//#endregion
|
|
373
|
+
//#region src/shared/classname-transform.ts
|
|
374
|
+
const escapedCandidateCacheByEscapeMap = /* @__PURE__ */ new WeakMap();
|
|
375
|
+
const defaultEscapedCandidateCache = /* @__PURE__ */ new Map();
|
|
376
|
+
let lastEscapedCandidateEscapeMap;
|
|
377
|
+
let lastEscapedCandidateCacheStore;
|
|
378
|
+
function isUrlLikeCandidate(candidate) {
|
|
379
|
+
return candidate.startsWith("//") || candidate.startsWith("http://") || candidate.startsWith("https://");
|
|
380
|
+
}
|
|
381
|
+
function isArbitraryValueCandidate(candidate) {
|
|
382
|
+
let hasOpenBracket = false;
|
|
383
|
+
let hasCloseBracket = false;
|
|
384
|
+
for (let i = 0; i < candidate.length; i++) {
|
|
385
|
+
const char = candidate[i];
|
|
386
|
+
if (char === "[") hasOpenBracket = true;
|
|
387
|
+
else if (char === "]") hasCloseBracket = true;
|
|
388
|
+
if (hasOpenBracket && hasCloseBracket) break;
|
|
389
|
+
}
|
|
390
|
+
if (!hasOpenBracket || !hasCloseBracket) return false;
|
|
391
|
+
if (isUrlLikeCandidate(candidate.trim())) return false;
|
|
392
|
+
return true;
|
|
393
|
+
}
|
|
394
|
+
function shouldEnableArbitraryValueFallbackByInputs(classNameSet, jsArbitraryValueFallback, tailwindcssMajorVersion) {
|
|
395
|
+
if (jsArbitraryValueFallback === true) return true;
|
|
396
|
+
if (jsArbitraryValueFallback === false) return false;
|
|
397
|
+
return tailwindcssMajorVersion === 4 && (!classNameSet || classNameSet.size === 0);
|
|
398
|
+
}
|
|
399
|
+
function shouldEnableArbitraryValueFallback({ classNameSet, jsArbitraryValueFallback, tailwindcssMajorVersion }) {
|
|
400
|
+
return shouldEnableArbitraryValueFallbackByInputs(classNameSet, jsArbitraryValueFallback, tailwindcssMajorVersion);
|
|
401
|
+
}
|
|
402
|
+
const SKIP_RESULT = { decision: "skip" };
|
|
403
|
+
const DIRECT_RESULT = { decision: "direct" };
|
|
404
|
+
const FALLBACK_RESULT = { decision: "fallback" };
|
|
405
|
+
function getEscapedCandidateCacheStore(escapeMap) {
|
|
406
|
+
if (!escapeMap) return defaultEscapedCandidateCache;
|
|
407
|
+
if (escapeMap === lastEscapedCandidateEscapeMap && lastEscapedCandidateCacheStore) return lastEscapedCandidateCacheStore;
|
|
408
|
+
let store = escapedCandidateCacheByEscapeMap.get(escapeMap);
|
|
409
|
+
if (!store) {
|
|
410
|
+
store = /* @__PURE__ */ new Map();
|
|
411
|
+
escapedCandidateCacheByEscapeMap.set(escapeMap, store);
|
|
412
|
+
}
|
|
413
|
+
lastEscapedCandidateEscapeMap = escapeMap;
|
|
414
|
+
lastEscapedCandidateCacheStore = store;
|
|
415
|
+
return store;
|
|
416
|
+
}
|
|
417
|
+
function getEscapedCandidate(candidate, escapeMap, store = getEscapedCandidateCacheStore(escapeMap)) {
|
|
418
|
+
let cached = store.get(candidate);
|
|
419
|
+
if (cached === void 0) {
|
|
420
|
+
cached = replaceWxml(candidate, { escapeMap });
|
|
421
|
+
store.set(candidate, cached);
|
|
422
|
+
}
|
|
423
|
+
return cached;
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* JS 转译严格遵循 runtime class set:
|
|
427
|
+
* 1. 直接命中 classNameSet 原始值;
|
|
428
|
+
* 2. 兼容命中 classNameSet 中已转义值;
|
|
429
|
+
* 3. 仅在受控条件下允许 class 语义兜底。
|
|
430
|
+
*
|
|
431
|
+
* 返回结构化结果,附带已计算的 escapedValue 以避免下游重复 escape。
|
|
432
|
+
*/
|
|
433
|
+
function resolveClassNameTransformWithResult(candidate, { alwaysEscape, classNameSet, escapeMap, jsArbitraryValueFallback, jsPreserveClass, tailwindcssMajorVersion, classContext }) {
|
|
434
|
+
if (alwaysEscape) return DIRECT_RESULT;
|
|
435
|
+
if (jsPreserveClass?.(candidate)) return SKIP_RESULT;
|
|
436
|
+
if (classNameSet?.has(candidate)) return DIRECT_RESULT;
|
|
437
|
+
if (classNameSet && classNameSet.size > 0) {
|
|
438
|
+
const escapedCandidate = getEscapedCandidate(candidate, escapeMap);
|
|
439
|
+
if (escapedCandidate !== candidate && classNameSet.has(escapedCandidate)) return {
|
|
440
|
+
decision: "escaped",
|
|
441
|
+
escapedValue: escapedCandidate
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
if (classContext && shouldEnableArbitraryValueFallbackByInputs(classNameSet, jsArbitraryValueFallback, tailwindcssMajorVersion) && isArbitraryValueCandidate(candidate)) return FALLBACK_RESULT;
|
|
445
|
+
return SKIP_RESULT;
|
|
446
|
+
}
|
|
447
|
+
//#endregion
|
|
448
|
+
//#region src/utils/decode.ts
|
|
449
|
+
const unicodeEscapeRE = /\\u([\dA-Fa-f]{4})/g;
|
|
450
|
+
const unicodeEscapeTestRE = /\\u[\dA-Fa-f]{4}/;
|
|
451
|
+
function decodeUnicode(value) {
|
|
452
|
+
if (!unicodeEscapeTestRE.test(value)) return value;
|
|
453
|
+
return value.replace(unicodeEscapeRE, (_match, hex) => {
|
|
454
|
+
const codePoint = Number.parseInt(hex, 16);
|
|
455
|
+
return Number.isNaN(codePoint) ? _match : String.fromCharCode(codePoint);
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
function decodeUnicode2(input) {
|
|
459
|
+
if (!unicodeEscapeTestRE.test(input)) return input;
|
|
460
|
+
try {
|
|
461
|
+
return JSON.parse(`"${input}"`);
|
|
462
|
+
} catch (_error) {
|
|
463
|
+
return decodeUnicode(input);
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
//#endregion
|
|
467
|
+
//#region src/js/class-context.ts
|
|
468
|
+
const CLASS_LIKE_KEYWORDS = new Set([
|
|
469
|
+
"class",
|
|
470
|
+
"classname",
|
|
471
|
+
"hoverclass",
|
|
472
|
+
"virtualhostclass",
|
|
473
|
+
"rootclass"
|
|
474
|
+
]);
|
|
475
|
+
const CLASS_HELPER_IDENTIFIERS = new Set([
|
|
476
|
+
"cn",
|
|
477
|
+
"clsx",
|
|
478
|
+
"classnames",
|
|
479
|
+
"twmerge",
|
|
480
|
+
"cva",
|
|
481
|
+
"tv",
|
|
482
|
+
"cx",
|
|
483
|
+
"r"
|
|
484
|
+
]);
|
|
485
|
+
const DASH_CODE = 45;
|
|
486
|
+
const COLON_CODE = 58;
|
|
487
|
+
const UPPERCASE_A_CODE = 65;
|
|
488
|
+
const UPPERCASE_Z_CODE = 90;
|
|
489
|
+
const UNDERSCORE_CODE = 95;
|
|
490
|
+
const ASCII_MAX_CODE = 127;
|
|
491
|
+
const NORMALIZE_KEYWORD_REGEXP = /[-_:]/g;
|
|
492
|
+
function normalizeKeyword(name) {
|
|
493
|
+
const length = name.length;
|
|
494
|
+
let firstNormalizedIndex = -1;
|
|
495
|
+
for (let i = 0; i < length; i++) {
|
|
496
|
+
const code = name.charCodeAt(i);
|
|
497
|
+
if (code === DASH_CODE || code === UNDERSCORE_CODE || code === COLON_CODE || code >= UPPERCASE_A_CODE && code <= UPPERCASE_Z_CODE) {
|
|
498
|
+
firstNormalizedIndex = i;
|
|
499
|
+
break;
|
|
500
|
+
}
|
|
501
|
+
if (code > ASCII_MAX_CODE) return name.replace(NORMALIZE_KEYWORD_REGEXP, "").toLowerCase();
|
|
502
|
+
}
|
|
503
|
+
if (firstNormalizedIndex === -1) return name;
|
|
504
|
+
let normalized = name.slice(0, firstNormalizedIndex);
|
|
505
|
+
for (let i = firstNormalizedIndex; i < length; i++) {
|
|
506
|
+
const code = name.charCodeAt(i);
|
|
507
|
+
if (code === DASH_CODE || code === UNDERSCORE_CODE || code === COLON_CODE) continue;
|
|
508
|
+
if (code >= UPPERCASE_A_CODE && code <= UPPERCASE_Z_CODE) {
|
|
509
|
+
normalized += String.fromCharCode(code + 32);
|
|
510
|
+
continue;
|
|
511
|
+
}
|
|
512
|
+
if (code > ASCII_MAX_CODE) return name.replace(NORMALIZE_KEYWORD_REGEXP, "").toLowerCase();
|
|
513
|
+
normalized += name[i];
|
|
514
|
+
}
|
|
515
|
+
return normalized;
|
|
516
|
+
}
|
|
517
|
+
function readObjectKeyName(path) {
|
|
518
|
+
if (path.isIdentifier()) return path.node.name;
|
|
519
|
+
if (path.isStringLiteral()) return path.node.value;
|
|
520
|
+
if (path.isTemplateLiteral() && path.node.expressions.length === 0) return path.node.quasis[0]?.value.cooked ?? path.node.quasis[0]?.value.raw;
|
|
521
|
+
}
|
|
522
|
+
function isClassLikeObjectProperty(path, valuePath) {
|
|
523
|
+
if (!path.isObjectProperty()) return false;
|
|
524
|
+
if (path.get("value") !== valuePath) return false;
|
|
525
|
+
const keyName = readObjectKeyName(path.get("key"));
|
|
526
|
+
if (!keyName) return false;
|
|
527
|
+
return CLASS_LIKE_KEYWORDS.has(normalizeKeyword(keyName));
|
|
528
|
+
}
|
|
529
|
+
function isClassLikeJsxAttribute(path) {
|
|
530
|
+
if (!path.isJSXAttribute()) return false;
|
|
531
|
+
const namePath = path.get("name");
|
|
532
|
+
if (!namePath.isJSXIdentifier()) return false;
|
|
533
|
+
return CLASS_LIKE_KEYWORDS.has(normalizeKeyword(namePath.node.name));
|
|
534
|
+
}
|
|
535
|
+
function readCallHelperName(calleePath) {
|
|
536
|
+
if (calleePath.isIdentifier()) return calleePath.node.name;
|
|
537
|
+
if (calleePath.isMemberExpression()) {
|
|
538
|
+
const propertyPath = calleePath.get("property");
|
|
539
|
+
if (propertyPath.isIdentifier()) return propertyPath.node.name;
|
|
540
|
+
if (propertyPath.isStringLiteral()) return propertyPath.node.value;
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
function isClassLikeCallExpression(path, valuePath) {
|
|
544
|
+
if (!path.isCallExpression()) return false;
|
|
545
|
+
const helperName = readCallHelperName(path.get("callee"));
|
|
546
|
+
if (!helperName || !CLASS_HELPER_IDENTIFIERS.has(normalizeKeyword(helperName))) return false;
|
|
547
|
+
return path.get("arguments").some((argumentPath) => argumentPath.node === valuePath.node);
|
|
548
|
+
}
|
|
549
|
+
/**
|
|
550
|
+
* 判断字符串字面量是否处于 class 语义上下文。
|
|
551
|
+
* 仅用于受控兜底场景,避免将普通业务文本误判为 class。
|
|
552
|
+
*/
|
|
553
|
+
function isClassContextLiteralPath(path) {
|
|
554
|
+
let current = path;
|
|
555
|
+
while (current.parentPath) {
|
|
556
|
+
const parent = current.parentPath;
|
|
557
|
+
if (isClassLikeObjectProperty(parent, current)) return true;
|
|
558
|
+
if (isClassLikeJsxAttribute(parent)) return true;
|
|
559
|
+
if (isClassLikeCallExpression(parent, current)) return true;
|
|
560
|
+
current = parent;
|
|
561
|
+
}
|
|
562
|
+
return false;
|
|
563
|
+
}
|
|
564
|
+
//#endregion
|
|
565
|
+
//#region src/js/handlers.ts
|
|
566
|
+
const debug = createDebug("[js:handlers] ");
|
|
567
|
+
const replacementCacheByEscapeMap = /* @__PURE__ */ new WeakMap();
|
|
568
|
+
const defaultReplacementCache = /* @__PURE__ */ new Map();
|
|
569
|
+
const WEAPP_TW_IGNORE_MARKER = "weapp-tw";
|
|
570
|
+
const IGNORE_MARKER = "ignore";
|
|
571
|
+
function getReplacementCacheStore(escapeMap) {
|
|
572
|
+
if (!escapeMap) return defaultReplacementCache;
|
|
573
|
+
let store = replacementCacheByEscapeMap.get(escapeMap);
|
|
574
|
+
if (!store) {
|
|
575
|
+
store = /* @__PURE__ */ new Map();
|
|
576
|
+
replacementCacheByEscapeMap.set(escapeMap, store);
|
|
577
|
+
}
|
|
578
|
+
return store;
|
|
579
|
+
}
|
|
580
|
+
function getReplacement(candidate, escapeMap, store = getReplacementCacheStore(escapeMap)) {
|
|
581
|
+
let cached = store.get(candidate);
|
|
582
|
+
if (cached === void 0) {
|
|
583
|
+
cached = replaceWxml(candidate, { escapeMap });
|
|
584
|
+
store.set(candidate, cached);
|
|
585
|
+
}
|
|
586
|
+
return cached;
|
|
587
|
+
}
|
|
588
|
+
function hasIgnoreComment(node) {
|
|
589
|
+
const { leadingComments } = node;
|
|
590
|
+
if (!Array.isArray(leadingComments) || leadingComments.length === 0) return false;
|
|
591
|
+
for (const comment of leadingComments) {
|
|
592
|
+
const { value } = comment;
|
|
593
|
+
if (value.includes(WEAPP_TW_IGNORE_MARKER) && value.includes(IGNORE_MARKER)) return true;
|
|
594
|
+
}
|
|
595
|
+
return false;
|
|
596
|
+
}
|
|
597
|
+
function extractLiteralValue(path, { unescapeUnicode, arbitraryValues }) {
|
|
598
|
+
const allowDoubleQuotes = arbitraryValues?.allowDoubleQuotes;
|
|
599
|
+
const { node } = path;
|
|
600
|
+
let offset = 0;
|
|
601
|
+
let original;
|
|
602
|
+
if (node.type === "StringLiteral") {
|
|
603
|
+
offset = 1;
|
|
604
|
+
original = node.value;
|
|
605
|
+
} else if (node.type === "TemplateElement") original = node.value.raw;
|
|
606
|
+
else original = "";
|
|
607
|
+
let literal = original;
|
|
608
|
+
if (unescapeUnicode && original.includes("\\u")) literal = decodeUnicode2(original);
|
|
609
|
+
return {
|
|
610
|
+
allowDoubleQuotes,
|
|
611
|
+
literal,
|
|
612
|
+
offset,
|
|
613
|
+
original
|
|
614
|
+
};
|
|
615
|
+
}
|
|
616
|
+
function createCandidatePlanResolver(options, classContext) {
|
|
617
|
+
const { escapeMap } = options;
|
|
618
|
+
const replacementCache = getReplacementCacheStore(escapeMap);
|
|
619
|
+
const transformOptions = classContext ? {
|
|
620
|
+
...options,
|
|
621
|
+
classContext
|
|
622
|
+
} : options;
|
|
623
|
+
let firstCandidate = "";
|
|
624
|
+
let firstPlan;
|
|
625
|
+
let cache;
|
|
626
|
+
const buildCandidatePlan = (candidate) => {
|
|
627
|
+
const result = resolveClassNameTransformWithResult(candidate, transformOptions);
|
|
628
|
+
if (result.decision === "skip") return { result };
|
|
629
|
+
let replacement;
|
|
630
|
+
if (result.decision === "escaped" && result.escapedValue) {
|
|
631
|
+
replacement = result.escapedValue;
|
|
632
|
+
replacementCache.set(candidate, replacement);
|
|
633
|
+
} else replacement = getReplacement(candidate, escapeMap, replacementCache);
|
|
634
|
+
return {
|
|
635
|
+
result,
|
|
636
|
+
replacement
|
|
637
|
+
};
|
|
638
|
+
};
|
|
639
|
+
return (candidate) => {
|
|
640
|
+
if (cache) {
|
|
641
|
+
const cached = cache.get(candidate);
|
|
642
|
+
if (cached) return cached;
|
|
643
|
+
} else if (firstPlan && candidate === firstCandidate) return firstPlan;
|
|
644
|
+
const plan = buildCandidatePlan(candidate);
|
|
645
|
+
if (!firstPlan) {
|
|
646
|
+
firstCandidate = candidate;
|
|
647
|
+
firstPlan = plan;
|
|
648
|
+
return plan;
|
|
649
|
+
}
|
|
650
|
+
if (!cache) {
|
|
651
|
+
cache = /* @__PURE__ */ new Map();
|
|
652
|
+
cache.set(firstCandidate, firstPlan);
|
|
653
|
+
}
|
|
654
|
+
cache.set(candidate, plan);
|
|
655
|
+
return plan;
|
|
656
|
+
};
|
|
657
|
+
}
|
|
658
|
+
function replaceHandleValue(path, options) {
|
|
659
|
+
const { needEscaped = false } = options;
|
|
660
|
+
const { classNameSet, alwaysEscape } = options;
|
|
661
|
+
const fallbackEnabled = shouldEnableArbitraryValueFallback(options);
|
|
662
|
+
if (!alwaysEscape && !fallbackEnabled && (!classNameSet || classNameSet.size === 0)) return;
|
|
663
|
+
if (hasIgnoreComment(path.node)) return;
|
|
664
|
+
const { literal, original, allowDoubleQuotes, offset } = extractLiteralValue(path, options);
|
|
665
|
+
const candidates = splitCode(literal, allowDoubleQuotes);
|
|
666
|
+
if (candidates.length === 0) return;
|
|
667
|
+
const debugEnabled = debug.enabled;
|
|
668
|
+
const classContext = options.wrapExpression || isClassContextLiteralPath(path);
|
|
669
|
+
let transformed = literal;
|
|
670
|
+
let mutated = false;
|
|
671
|
+
let matchedCandidateCount = 0;
|
|
672
|
+
let escapedDecisionCount = 0;
|
|
673
|
+
let fallbackDecisionCount = 0;
|
|
674
|
+
let escapedSamples;
|
|
675
|
+
let skippedSamples;
|
|
676
|
+
const resolveCandidatePlan = createCandidatePlanResolver(options, classContext);
|
|
677
|
+
for (const candidate of candidates) {
|
|
678
|
+
const plan = resolveCandidatePlan(candidate);
|
|
679
|
+
if (plan.result.decision === "skip") {
|
|
680
|
+
if (debugEnabled) {
|
|
681
|
+
if (!skippedSamples) skippedSamples = [];
|
|
682
|
+
if (skippedSamples.length < 6) skippedSamples.push(candidate);
|
|
683
|
+
}
|
|
684
|
+
continue;
|
|
685
|
+
}
|
|
686
|
+
if (debugEnabled) {
|
|
687
|
+
matchedCandidateCount += 1;
|
|
688
|
+
if (plan.result.decision === "escaped") {
|
|
689
|
+
escapedDecisionCount += 1;
|
|
690
|
+
if (!escapedSamples) escapedSamples = [];
|
|
691
|
+
if (escapedSamples.length < 6) escapedSamples.push(candidate);
|
|
692
|
+
}
|
|
693
|
+
if (plan.result.decision === "fallback") fallbackDecisionCount += 1;
|
|
694
|
+
}
|
|
695
|
+
const replaced = transformed.replace(candidate, plan.replacement);
|
|
696
|
+
if (replaced !== transformed) {
|
|
697
|
+
transformed = replaced;
|
|
698
|
+
mutated = true;
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
const node = path.node;
|
|
702
|
+
if (!mutated || typeof node.start !== "number" || typeof node.end !== "number") return;
|
|
703
|
+
if (debugEnabled) debug("runtimeSet size=%d fallbackTriggered=%s candidates=%d matched=%d escapedHits=%d skipped=%d file=%s escapedSamples=%s skippedSamples=%s", classNameSet?.size ?? 0, fallbackDecisionCount > 0, candidates.length, matchedCandidateCount, escapedDecisionCount, skippedSamples?.length ?? 0, options.filename ?? "unknown", escapedSamples?.join(",") || "-", skippedSamples?.join(",") || "-");
|
|
704
|
+
const start = node.start + offset;
|
|
705
|
+
const end = node.end - offset;
|
|
706
|
+
if (start >= end || transformed === original) return;
|
|
707
|
+
return {
|
|
708
|
+
start,
|
|
709
|
+
end,
|
|
710
|
+
value: needEscaped ? jsStringEscape(transformed) : transformed,
|
|
711
|
+
path
|
|
712
|
+
};
|
|
713
|
+
}
|
|
714
|
+
//#endregion
|
|
715
|
+
//#region src/js/sourceAnalysis.ts
|
|
716
|
+
function hasReplacementEntries(replacements) {
|
|
717
|
+
for (const key in replacements) if (Object.hasOwn(replacements, key)) return true;
|
|
718
|
+
return false;
|
|
719
|
+
}
|
|
720
|
+
function createModuleSpecifierReplacementToken(path, replacement) {
|
|
721
|
+
const node = path.node;
|
|
722
|
+
if (node.value === replacement) return;
|
|
723
|
+
if (typeof node.start !== "number" || typeof node.end !== "number") return;
|
|
724
|
+
const start = node.start + 1;
|
|
725
|
+
const end = node.end - 1;
|
|
726
|
+
if (start >= end) return;
|
|
727
|
+
return {
|
|
728
|
+
start,
|
|
729
|
+
end,
|
|
730
|
+
value: replacement,
|
|
731
|
+
path
|
|
732
|
+
};
|
|
733
|
+
}
|
|
734
|
+
function collectModuleSpecifierReplacementTokens(analysis, replacements) {
|
|
735
|
+
if (!hasReplacementEntries(replacements)) return [];
|
|
736
|
+
if (analysis.importDeclarations.size === 0 && analysis.exportDeclarations.size === 0 && analysis.requireCallPaths.length === 0 && analysis.walker.imports.size === 0) return [];
|
|
737
|
+
const tokens = [];
|
|
738
|
+
const applyReplacement = (path) => {
|
|
739
|
+
const replacement = replacements[path.node.value];
|
|
740
|
+
if (!replacement) return;
|
|
741
|
+
const token = createModuleSpecifierReplacementToken(path, replacement);
|
|
742
|
+
if (token) tokens.push(token);
|
|
743
|
+
};
|
|
744
|
+
for (const importPath of analysis.importDeclarations) {
|
|
745
|
+
const source = importPath.get("source");
|
|
746
|
+
if (source.isStringLiteral()) applyReplacement(source);
|
|
747
|
+
}
|
|
748
|
+
for (const exportPath of analysis.exportDeclarations) if (exportPath.isExportNamedDeclaration() || exportPath.isExportAllDeclaration()) {
|
|
749
|
+
const source = exportPath.get("source");
|
|
750
|
+
if (source && !Array.isArray(source) && source.isStringLiteral()) applyReplacement(source);
|
|
751
|
+
}
|
|
752
|
+
for (const literalPath of analysis.requireCallPaths) applyReplacement(literalPath);
|
|
753
|
+
for (const token of analysis.walker.imports) {
|
|
754
|
+
const replacement = replacements[token.source];
|
|
755
|
+
if (replacement) token.source = replacement;
|
|
756
|
+
}
|
|
757
|
+
return tokens;
|
|
758
|
+
}
|
|
759
|
+
//#endregion
|
|
760
|
+
//#region src/js/babel/process.ts
|
|
761
|
+
const optionVariantsCache = /* @__PURE__ */ new WeakMap();
|
|
762
|
+
function getNeedEscapedOptions(options, needEscaped) {
|
|
763
|
+
if (options.needEscaped === needEscaped) return options;
|
|
764
|
+
let cached = optionVariantsCache.get(options);
|
|
765
|
+
if (!cached) {
|
|
766
|
+
cached = {};
|
|
767
|
+
optionVariantsCache.set(options, cached);
|
|
768
|
+
}
|
|
769
|
+
if (needEscaped) {
|
|
770
|
+
if (!cached.stringLiteralOptions) cached.stringLiteralOptions = {
|
|
771
|
+
...options,
|
|
772
|
+
needEscaped: true
|
|
773
|
+
};
|
|
774
|
+
return cached.stringLiteralOptions;
|
|
775
|
+
}
|
|
776
|
+
if (!cached.templateLiteralOptions) cached.templateLiteralOptions = {
|
|
777
|
+
...options,
|
|
778
|
+
needEscaped: false
|
|
779
|
+
};
|
|
780
|
+
return cached.templateLiteralOptions;
|
|
781
|
+
}
|
|
782
|
+
function processUpdatedSource(rawSource, options, analysis) {
|
|
783
|
+
const { targetPaths, jsTokenUpdater, ignoredPaths } = analysis;
|
|
784
|
+
if (targetPaths.length === 0 && !options.moduleSpecifierReplacements && jsTokenUpdater.length === 0) return new MagicString(rawSource);
|
|
785
|
+
const replacementTokens = [];
|
|
786
|
+
for (const path of targetPaths) {
|
|
787
|
+
if (ignoredPaths.has(path)) continue;
|
|
788
|
+
const token = replaceHandleValue(path, path.isStringLiteral() ? getNeedEscapedOptions(options, true) : getNeedEscapedOptions(options, false));
|
|
789
|
+
if (token) replacementTokens.push(token);
|
|
790
|
+
}
|
|
791
|
+
if (options.moduleSpecifierReplacements) replacementTokens.push(...collectModuleSpecifierReplacementTokens(analysis, options.moduleSpecifierReplacements));
|
|
792
|
+
if (jsTokenUpdater.length + replacementTokens.length === 0) return new MagicString(rawSource);
|
|
793
|
+
const ms = new MagicString(rawSource);
|
|
794
|
+
jsTokenUpdater.push(...replacementTokens).filter((token) => !ignoredPaths.has(token.path)).updateMagicString(ms);
|
|
795
|
+
return ms;
|
|
796
|
+
}
|
|
797
|
+
//#endregion
|
|
798
|
+
//#region src/js/evalTransforms.ts
|
|
799
|
+
const evalHandlerOptionsCache = /* @__PURE__ */ new WeakMap();
|
|
800
|
+
const EVAL_SCOPE_ERROR_REGEXP = /pass a scope and parentPath|traversing a Program\/File/i;
|
|
801
|
+
function isEvalPath(path) {
|
|
802
|
+
if (path.isCallExpression()) return path.get("callee").isIdentifier({ name: "eval" });
|
|
803
|
+
return false;
|
|
804
|
+
}
|
|
805
|
+
function createEvalReplacementToken(path, updated) {
|
|
806
|
+
const node = path.node;
|
|
807
|
+
let offset = 0;
|
|
808
|
+
let original;
|
|
809
|
+
if (path.isStringLiteral()) {
|
|
810
|
+
offset = 1;
|
|
811
|
+
original = path.node.value;
|
|
812
|
+
} else if (path.isTemplateElement()) original = path.node.value.raw;
|
|
813
|
+
else original = "";
|
|
814
|
+
if (typeof node.start !== "number" || typeof node.end !== "number") return;
|
|
815
|
+
const start = node.start + offset;
|
|
816
|
+
const end = node.end - offset;
|
|
817
|
+
if (start >= end) return;
|
|
818
|
+
if (original === updated) return;
|
|
819
|
+
return {
|
|
820
|
+
start,
|
|
821
|
+
end,
|
|
822
|
+
value: path.isStringLiteral() ? jsStringEscape(updated) : updated,
|
|
823
|
+
path
|
|
824
|
+
};
|
|
825
|
+
}
|
|
826
|
+
function handleEvalStringLiteral(path, handlerOptions, updater, handler) {
|
|
827
|
+
const { code } = handler(path.node.value, handlerOptions);
|
|
828
|
+
if (!code) return;
|
|
829
|
+
const token = createEvalReplacementToken(path, code);
|
|
830
|
+
if (token) updater.addToken(token);
|
|
831
|
+
}
|
|
832
|
+
function handleEvalTemplateElement(path, handlerOptions, updater, handler) {
|
|
833
|
+
const { code } = handler(path.node.value.raw, handlerOptions);
|
|
834
|
+
if (!code) return;
|
|
835
|
+
const token = createEvalReplacementToken(path, code);
|
|
836
|
+
if (token) updater.addToken(token);
|
|
837
|
+
}
|
|
838
|
+
function getEvalStringHandlerOptions(options) {
|
|
839
|
+
if (options.needEscaped === false && options.generateMap === false) return options;
|
|
840
|
+
let cached = evalHandlerOptionsCache.get(options);
|
|
841
|
+
if (!cached) {
|
|
842
|
+
cached = {};
|
|
843
|
+
evalHandlerOptionsCache.set(options, cached);
|
|
844
|
+
}
|
|
845
|
+
if (!cached.stringLiteralOptions) cached.stringLiteralOptions = {
|
|
846
|
+
...options,
|
|
847
|
+
needEscaped: false,
|
|
848
|
+
generateMap: false
|
|
849
|
+
};
|
|
850
|
+
return cached.stringLiteralOptions;
|
|
851
|
+
}
|
|
852
|
+
function getEvalTemplateHandlerOptions(options) {
|
|
853
|
+
if (options.generateMap === false) return options;
|
|
854
|
+
let cached = evalHandlerOptionsCache.get(options);
|
|
855
|
+
if (!cached) {
|
|
856
|
+
cached = {};
|
|
857
|
+
evalHandlerOptionsCache.set(options, cached);
|
|
858
|
+
}
|
|
859
|
+
if (!cached.templateLiteralOptions) cached.templateLiteralOptions = {
|
|
860
|
+
...options,
|
|
861
|
+
generateMap: false
|
|
862
|
+
};
|
|
863
|
+
return cached.templateLiteralOptions;
|
|
864
|
+
}
|
|
865
|
+
function walkEvalExpression(path, options, updater, handler) {
|
|
866
|
+
const stringHandlerOptions = getEvalStringHandlerOptions(options);
|
|
867
|
+
const templateHandlerOptions = getEvalTemplateHandlerOptions(options);
|
|
868
|
+
const maybeTraverse = path?.traverse;
|
|
869
|
+
if (typeof maybeTraverse === "function") try {
|
|
870
|
+
return maybeTraverse.call(path, {
|
|
871
|
+
StringLiteral(innerPath) {
|
|
872
|
+
handleEvalStringLiteral(innerPath, stringHandlerOptions, updater, handler);
|
|
873
|
+
},
|
|
874
|
+
TemplateElement(innerPath) {
|
|
875
|
+
handleEvalTemplateElement(innerPath, templateHandlerOptions, updater, handler);
|
|
876
|
+
}
|
|
877
|
+
});
|
|
878
|
+
} catch (error) {
|
|
879
|
+
const msg = error?.message ?? "";
|
|
880
|
+
if (!EVAL_SCOPE_ERROR_REGEXP.test(msg)) throw error;
|
|
881
|
+
}
|
|
882
|
+
const getArgs = path?.get?.("arguments");
|
|
883
|
+
if (Array.isArray(getArgs)) {
|
|
884
|
+
for (const arg of getArgs) {
|
|
885
|
+
if (arg?.isStringLiteral?.()) {
|
|
886
|
+
handleEvalStringLiteral(arg, stringHandlerOptions, updater, handler);
|
|
887
|
+
continue;
|
|
888
|
+
}
|
|
889
|
+
if (arg?.isTemplateLiteral?.()) for (const quasi of arg.get("quasis")) handleEvalTemplateElement(quasi, templateHandlerOptions, updater, handler);
|
|
890
|
+
}
|
|
891
|
+
return;
|
|
892
|
+
}
|
|
893
|
+
const nodeArgs = path?.node?.arguments;
|
|
894
|
+
if (Array.isArray(nodeArgs)) {
|
|
895
|
+
for (const n of nodeArgs) if (n?.type === "StringLiteral") handleEvalStringLiteral({
|
|
896
|
+
node: n,
|
|
897
|
+
isStringLiteral: () => true
|
|
898
|
+
}, stringHandlerOptions, updater, handler);
|
|
899
|
+
else if (n?.type === "TemplateLiteral" && Array.isArray(n.quasis)) for (const q of n.quasis) handleEvalTemplateElement({
|
|
900
|
+
node: q,
|
|
901
|
+
isStringLiteral: () => false,
|
|
902
|
+
isTemplateElement: () => true
|
|
903
|
+
}, templateHandlerOptions, updater, handler);
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
//#endregion
|
|
907
|
+
//#region src/js/JsTokenUpdater.ts
|
|
908
|
+
/**
|
|
909
|
+
* Lightweight helper that batches updates to {@link MagicString}.
|
|
910
|
+
* It keeps the transformation logic out of the traversal code and makes
|
|
911
|
+
* it easier to reason about the order in which tokens are written back.
|
|
912
|
+
*/
|
|
913
|
+
var JsTokenUpdater = class {
|
|
914
|
+
constructor({ value } = {}) {
|
|
915
|
+
this.tokens = value ? [...value] : [];
|
|
916
|
+
}
|
|
917
|
+
addToken(token) {
|
|
918
|
+
if (token) this.tokens.push(token);
|
|
919
|
+
}
|
|
920
|
+
push(...args) {
|
|
921
|
+
this.tokens.push(...args);
|
|
922
|
+
return this;
|
|
923
|
+
}
|
|
924
|
+
/**
|
|
925
|
+
* 待写入的 token 数量。
|
|
926
|
+
*/
|
|
927
|
+
get length() {
|
|
928
|
+
return this.tokens.length;
|
|
929
|
+
}
|
|
930
|
+
map(callbackfn) {
|
|
931
|
+
this.tokens = this.tokens.map(callbackfn);
|
|
932
|
+
return this;
|
|
933
|
+
}
|
|
934
|
+
filter(callbackfn) {
|
|
935
|
+
this.tokens = this.tokens.filter(callbackfn);
|
|
936
|
+
return this;
|
|
937
|
+
}
|
|
938
|
+
updateMagicString(ms) {
|
|
939
|
+
for (const { start, end, value } of this.tokens) ms.update(start, end, value);
|
|
940
|
+
return ms;
|
|
941
|
+
}
|
|
942
|
+
};
|
|
943
|
+
//#endregion
|
|
944
|
+
//#region src/js/module-graph/ignored-exports.ts
|
|
945
|
+
var IgnoredExportsTracker = class {
|
|
946
|
+
constructor(options) {
|
|
947
|
+
this.options = options;
|
|
948
|
+
this.ignoredExportNames = /* @__PURE__ */ new Map();
|
|
949
|
+
}
|
|
950
|
+
addIgnoredExport(filename, exportName) {
|
|
951
|
+
if (!exportName) return;
|
|
952
|
+
let pending = this.ignoredExportNames.get(filename);
|
|
953
|
+
if (!pending) {
|
|
954
|
+
pending = /* @__PURE__ */ new Set();
|
|
955
|
+
this.ignoredExportNames.set(filename, pending);
|
|
956
|
+
}
|
|
957
|
+
if (pending.has(exportName)) return;
|
|
958
|
+
pending.add(exportName);
|
|
959
|
+
const existing = this.options.modules.get(filename);
|
|
960
|
+
if (existing) this.applyIgnoredExportsToAnalysis(filename, existing.analysis);
|
|
961
|
+
}
|
|
962
|
+
registerIgnoredExportsFromTokens(resolved, tokens) {
|
|
963
|
+
for (const token of tokens) if (token.type === "ImportSpecifier") this.addIgnoredExport(resolved, token.imported);
|
|
964
|
+
else if (token.type === "ImportDefaultSpecifier") this.addIgnoredExport(resolved, "default");
|
|
965
|
+
}
|
|
966
|
+
applyIgnoredExportsToAnalysis(filename, analysis) {
|
|
967
|
+
const pending = this.ignoredExportNames.get(filename);
|
|
968
|
+
if (!pending || pending.size === 0) return;
|
|
969
|
+
const names = new Set(pending);
|
|
970
|
+
pending.clear();
|
|
971
|
+
const propagate = [];
|
|
972
|
+
for (const exportPath of analysis.exportDeclarations) {
|
|
973
|
+
if (names.size === 0) break;
|
|
974
|
+
if (exportPath.isExportDefaultDeclaration()) {
|
|
975
|
+
if (names.has("default")) {
|
|
976
|
+
analysis.walker.walkExportDefaultDeclaration(exportPath);
|
|
977
|
+
names.delete("default");
|
|
978
|
+
}
|
|
979
|
+
continue;
|
|
980
|
+
}
|
|
981
|
+
if (exportPath.isExportNamedDeclaration()) {
|
|
982
|
+
const source = exportPath.node.source?.value;
|
|
983
|
+
if (typeof source === "string") {
|
|
984
|
+
for (const spec of exportPath.get("specifiers")) {
|
|
985
|
+
if (!spec.isExportSpecifier()) continue;
|
|
986
|
+
const exported = spec.get("exported");
|
|
987
|
+
let exportedName;
|
|
988
|
+
if (exported.isIdentifier()) exportedName = exported.node.name;
|
|
989
|
+
else if (exported.isStringLiteral()) exportedName = exported.node.value;
|
|
990
|
+
if (!exportedName || !names.has(exportedName)) continue;
|
|
991
|
+
const local = spec.get("local");
|
|
992
|
+
if (local.isIdentifier()) {
|
|
993
|
+
propagate.push({
|
|
994
|
+
specifier: source,
|
|
995
|
+
exportName: local.node.name
|
|
996
|
+
});
|
|
997
|
+
names.delete(exportedName);
|
|
998
|
+
} else if (local.isStringLiteral()) {
|
|
999
|
+
propagate.push({
|
|
1000
|
+
specifier: source,
|
|
1001
|
+
exportName: local.node.value
|
|
1002
|
+
});
|
|
1003
|
+
names.delete(exportedName);
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
continue;
|
|
1007
|
+
}
|
|
1008
|
+
const declaration = exportPath.get("declaration");
|
|
1009
|
+
if (declaration.isVariableDeclaration()) for (const decl of declaration.get("declarations")) {
|
|
1010
|
+
const id = decl.get("id");
|
|
1011
|
+
if (id.isIdentifier()) {
|
|
1012
|
+
const exportName = id.node.name;
|
|
1013
|
+
if (names.has(exportName)) {
|
|
1014
|
+
analysis.walker.walkVariableDeclarator(decl);
|
|
1015
|
+
names.delete(exportName);
|
|
1016
|
+
}
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
for (const spec of exportPath.get("specifiers")) {
|
|
1020
|
+
if (!spec.isExportSpecifier()) continue;
|
|
1021
|
+
const exported = spec.get("exported");
|
|
1022
|
+
let exportedName;
|
|
1023
|
+
if (exported.isIdentifier()) exportedName = exported.node.name;
|
|
1024
|
+
else if (exported.isStringLiteral()) exportedName = exported.node.value;
|
|
1025
|
+
if (!exportedName || !names.has(exportedName)) continue;
|
|
1026
|
+
const local = spec.get("local");
|
|
1027
|
+
analysis.walker.walkNode(local);
|
|
1028
|
+
names.delete(exportedName);
|
|
1029
|
+
}
|
|
1030
|
+
continue;
|
|
1031
|
+
}
|
|
1032
|
+
if (exportPath.isExportAllDeclaration()) {
|
|
1033
|
+
const source = exportPath.node.source?.value;
|
|
1034
|
+
if (typeof source === "string") {
|
|
1035
|
+
for (const exportName of names) propagate.push({
|
|
1036
|
+
specifier: source,
|
|
1037
|
+
exportName
|
|
1038
|
+
});
|
|
1039
|
+
names.clear();
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
1042
|
+
}
|
|
1043
|
+
for (const { specifier, exportName } of propagate) {
|
|
1044
|
+
let resolved;
|
|
1045
|
+
try {
|
|
1046
|
+
resolved = this.options.resolve(specifier, filename);
|
|
1047
|
+
} catch {
|
|
1048
|
+
resolved = void 0;
|
|
1049
|
+
}
|
|
1050
|
+
if (!resolved) {
|
|
1051
|
+
pending.add(exportName);
|
|
1052
|
+
continue;
|
|
1053
|
+
}
|
|
1054
|
+
if (this.options.filter && !this.options.filter(resolved, specifier, filename)) {
|
|
1055
|
+
pending.add(exportName);
|
|
1056
|
+
continue;
|
|
1057
|
+
}
|
|
1058
|
+
this.addIgnoredExport(resolved, exportName);
|
|
1059
|
+
}
|
|
1060
|
+
for (const name of names) pending.add(name);
|
|
1061
|
+
}
|
|
1062
|
+
};
|
|
1063
|
+
//#endregion
|
|
1064
|
+
//#region src/js/ModuleGraph.ts
|
|
1065
|
+
var JsModuleGraph = class {
|
|
1066
|
+
constructor(entry, graphOptions) {
|
|
1067
|
+
this.modules = /* @__PURE__ */ new Map();
|
|
1068
|
+
this.queue = [];
|
|
1069
|
+
this.resolve = graphOptions.resolve;
|
|
1070
|
+
this.load = graphOptions.load;
|
|
1071
|
+
this.filter = graphOptions.filter;
|
|
1072
|
+
this.maxDepth = graphOptions.maxDepth ?? Number.POSITIVE_INFINITY;
|
|
1073
|
+
const { moduleGraph: _moduleGraph, filename: _ignoredFilename, ...rest } = entry.handlerOptions;
|
|
1074
|
+
this.baseOptions = {
|
|
1075
|
+
...rest,
|
|
1076
|
+
filename: entry.filename
|
|
1077
|
+
};
|
|
1078
|
+
this.parserOptions = entry.handlerOptions.babelParserOptions;
|
|
1079
|
+
this.rootFilename = entry.filename;
|
|
1080
|
+
this.ignoredExports = new IgnoredExportsTracker({
|
|
1081
|
+
resolve: this.resolve,
|
|
1082
|
+
filter: this.filter,
|
|
1083
|
+
modules: this.modules
|
|
1084
|
+
});
|
|
1085
|
+
this.modules.set(entry.filename, {
|
|
1086
|
+
filename: entry.filename,
|
|
1087
|
+
source: entry.source,
|
|
1088
|
+
analysis: entry.analysis
|
|
1089
|
+
});
|
|
1090
|
+
this.queue.push({
|
|
1091
|
+
filename: entry.filename,
|
|
1092
|
+
depth: 0
|
|
1093
|
+
});
|
|
1094
|
+
}
|
|
1095
|
+
build() {
|
|
1096
|
+
this.collectDependencies();
|
|
1097
|
+
let linked;
|
|
1098
|
+
for (const [filename, state] of this.modules) {
|
|
1099
|
+
if (filename === this.rootFilename) continue;
|
|
1100
|
+
const childOptions = {
|
|
1101
|
+
...this.baseOptions,
|
|
1102
|
+
filename
|
|
1103
|
+
};
|
|
1104
|
+
const code = processUpdatedSource(state.source, childOptions, state.analysis).toString();
|
|
1105
|
+
if (code !== state.source) {
|
|
1106
|
+
if (!linked) linked = {};
|
|
1107
|
+
linked[filename] = { code };
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
return linked;
|
|
1111
|
+
}
|
|
1112
|
+
collectDependencies() {
|
|
1113
|
+
while (this.queue.length > 0) {
|
|
1114
|
+
const { filename, depth } = this.queue.shift();
|
|
1115
|
+
if (depth >= this.maxDepth) continue;
|
|
1116
|
+
const state = this.modules.get(filename);
|
|
1117
|
+
if (!state) continue;
|
|
1118
|
+
const dependencySpecifiers = /* @__PURE__ */ new Map();
|
|
1119
|
+
for (const token of state.analysis.walker.imports) {
|
|
1120
|
+
if (!dependencySpecifiers.has(token.source)) dependencySpecifiers.set(token.source, []);
|
|
1121
|
+
dependencySpecifiers.get(token.source).push(token);
|
|
1122
|
+
}
|
|
1123
|
+
for (const exportPath of state.analysis.exportDeclarations) if (exportPath.isExportAllDeclaration() || exportPath.isExportNamedDeclaration()) {
|
|
1124
|
+
const source = exportPath.node.source?.value;
|
|
1125
|
+
if (typeof source === "string" && !dependencySpecifiers.has(source)) dependencySpecifiers.set(source, []);
|
|
1126
|
+
}
|
|
1127
|
+
for (const [specifier, tokens] of dependencySpecifiers) {
|
|
1128
|
+
let resolved;
|
|
1129
|
+
try {
|
|
1130
|
+
resolved = this.resolve(specifier, filename);
|
|
1131
|
+
} catch {
|
|
1132
|
+
continue;
|
|
1133
|
+
}
|
|
1134
|
+
if (!resolved) continue;
|
|
1135
|
+
if (this.filter && !this.filter(resolved, specifier, filename)) continue;
|
|
1136
|
+
if (tokens.length > 0) this.ignoredExports.registerIgnoredExportsFromTokens(resolved, tokens);
|
|
1137
|
+
if (this.modules.has(resolved)) continue;
|
|
1138
|
+
let source;
|
|
1139
|
+
try {
|
|
1140
|
+
source = this.load(resolved);
|
|
1141
|
+
} catch {
|
|
1142
|
+
continue;
|
|
1143
|
+
}
|
|
1144
|
+
if (typeof source !== "string") continue;
|
|
1145
|
+
let analysis;
|
|
1146
|
+
try {
|
|
1147
|
+
analysis = analyzeSource(babelParse(source, {
|
|
1148
|
+
...this.parserOptions,
|
|
1149
|
+
sourceFilename: resolved
|
|
1150
|
+
}), {
|
|
1151
|
+
...this.baseOptions,
|
|
1152
|
+
filename: resolved
|
|
1153
|
+
});
|
|
1154
|
+
this.ignoredExports.applyIgnoredExportsToAnalysis(resolved, analysis);
|
|
1155
|
+
} catch {
|
|
1156
|
+
continue;
|
|
1157
|
+
}
|
|
1158
|
+
this.modules.set(resolved, {
|
|
1159
|
+
filename: resolved,
|
|
1160
|
+
source,
|
|
1161
|
+
analysis
|
|
1162
|
+
});
|
|
1163
|
+
this.queue.push({
|
|
1164
|
+
filename: resolved,
|
|
1165
|
+
depth: depth + 1
|
|
1166
|
+
});
|
|
1167
|
+
}
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
};
|
|
1171
|
+
//#endregion
|
|
1172
|
+
//#region src/js/node-path-walker/export-handlers.ts
|
|
1173
|
+
function walkExportDeclaration(ctx, path) {
|
|
1174
|
+
if (path.isExportDeclaration()) {
|
|
1175
|
+
if (path.isExportNamedDeclaration()) walkExportNamedDeclaration(ctx, path);
|
|
1176
|
+
else if (path.isExportDefaultDeclaration()) walkExportDefaultDeclaration(ctx, path);
|
|
1177
|
+
else if (path.isExportAllDeclaration()) walkExportAllDeclaration(ctx, path);
|
|
1178
|
+
}
|
|
1179
|
+
}
|
|
1180
|
+
function walkExportNamedDeclaration(ctx, path) {
|
|
1181
|
+
const declaration = path.get("declaration");
|
|
1182
|
+
if (declaration.isVariableDeclaration()) for (const decl of declaration.get("declarations")) ctx.walkNode(decl);
|
|
1183
|
+
const specifiers = path.get("specifiers");
|
|
1184
|
+
for (const spec of specifiers) if (spec.isExportSpecifier()) {
|
|
1185
|
+
const local = spec.get("local");
|
|
1186
|
+
if (local.isIdentifier()) ctx.walkNode(local);
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
function walkExportDefaultDeclaration(ctx, path) {
|
|
1190
|
+
const decl = path.get("declaration");
|
|
1191
|
+
if (decl.isIdentifier()) ctx.walkNode(decl);
|
|
1192
|
+
else ctx.walkNode(decl);
|
|
1193
|
+
}
|
|
1194
|
+
function walkExportAllDeclaration(ctx, path) {
|
|
1195
|
+
const source = path.get("source");
|
|
1196
|
+
if (source.isStringLiteral()) ctx.addImportToken({
|
|
1197
|
+
declaration: path,
|
|
1198
|
+
source: source.node.value,
|
|
1199
|
+
type: "ExportAllDeclaration"
|
|
1200
|
+
});
|
|
1201
|
+
}
|
|
1202
|
+
//#endregion
|
|
1203
|
+
//#region src/js/node-path-walker/import-tokens.ts
|
|
1204
|
+
function maybeAddImportToken(imports, arg) {
|
|
1205
|
+
if (!(arg.isImportSpecifier() && arg.node.importKind !== "type" || arg.isImportDefaultSpecifier())) return false;
|
|
1206
|
+
const importDeclaration = arg.parentPath;
|
|
1207
|
+
if (!importDeclaration.isImportDeclaration() || importDeclaration.node.importKind === "type") return false;
|
|
1208
|
+
if (arg.isImportSpecifier()) {
|
|
1209
|
+
const imported = arg.get("imported");
|
|
1210
|
+
if (imported.isIdentifier()) imports.add({
|
|
1211
|
+
declaration: importDeclaration,
|
|
1212
|
+
specifier: arg,
|
|
1213
|
+
imported: imported.node.name,
|
|
1214
|
+
local: arg.node.local.name,
|
|
1215
|
+
source: importDeclaration.node.source.value,
|
|
1216
|
+
type: "ImportSpecifier"
|
|
1217
|
+
});
|
|
1218
|
+
return true;
|
|
1219
|
+
}
|
|
1220
|
+
imports.add({
|
|
1221
|
+
declaration: importDeclaration,
|
|
1222
|
+
specifier: arg,
|
|
1223
|
+
local: arg.node.local.name,
|
|
1224
|
+
source: importDeclaration.node.source.value,
|
|
1225
|
+
type: "ImportDefaultSpecifier"
|
|
1226
|
+
});
|
|
1227
|
+
return true;
|
|
1228
|
+
}
|
|
1229
|
+
//#endregion
|
|
1230
|
+
//#region src/js/NodePathWalker.ts
|
|
1231
|
+
const EMPTY_IGNORE_CALL_EXPRESSION_IDENTIFIERS = [];
|
|
1232
|
+
const EMPTY_IMPORT_TOKENS = /* @__PURE__ */ new Set();
|
|
1233
|
+
function NOOP_STRING_PATH_CALLBACK() {}
|
|
1234
|
+
const NEVER_MATCH_NAME = () => false;
|
|
1235
|
+
/**
|
|
1236
|
+
* 遍历我们关注的调用表达式所关联的绑定,收集后续需要转换的字符串节点。
|
|
1237
|
+
*/
|
|
1238
|
+
var NodePathWalker = class {
|
|
1239
|
+
constructor({ ignoreCallExpressionIdentifiers, callback } = {}) {
|
|
1240
|
+
this.hasIgnoredCallIdentifiers = Boolean(ignoreCallExpressionIdentifiers && ignoreCallExpressionIdentifiers.length > 0);
|
|
1241
|
+
this.ignoreCallExpressionIdentifiers = ignoreCallExpressionIdentifiers ?? EMPTY_IGNORE_CALL_EXPRESSION_IDENTIFIERS;
|
|
1242
|
+
this.callback = callback ?? NOOP_STRING_PATH_CALLBACK;
|
|
1243
|
+
this.isIgnoredCallIdentifier = this.hasIgnoredCallIdentifiers ? createNameMatcher(this.ignoreCallExpressionIdentifiers, { exact: true }) : NEVER_MATCH_NAME;
|
|
1244
|
+
}
|
|
1245
|
+
get imports() {
|
|
1246
|
+
return this.importsStore ?? EMPTY_IMPORT_TOKENS;
|
|
1247
|
+
}
|
|
1248
|
+
getWritableImports() {
|
|
1249
|
+
if (!this.importsStore) this.importsStore = /* @__PURE__ */ new Set();
|
|
1250
|
+
return this.importsStore;
|
|
1251
|
+
}
|
|
1252
|
+
addImportToken(token) {
|
|
1253
|
+
this.getWritableImports().add(token);
|
|
1254
|
+
}
|
|
1255
|
+
getVisited() {
|
|
1256
|
+
if (!this.visitedStore) this.visitedStore = /* @__PURE__ */ new WeakSet();
|
|
1257
|
+
return this.visitedStore;
|
|
1258
|
+
}
|
|
1259
|
+
walkVariableDeclarator(path) {
|
|
1260
|
+
const init = path.get("init");
|
|
1261
|
+
this.walkNode(init);
|
|
1262
|
+
}
|
|
1263
|
+
walkTemplateLiteral(path) {
|
|
1264
|
+
for (const exp of path.get("expressions")) this.walkNode(exp);
|
|
1265
|
+
for (const quasis of path.get("quasis")) this.callback(quasis);
|
|
1266
|
+
}
|
|
1267
|
+
walkStringLiteral(path) {
|
|
1268
|
+
this.callback(path);
|
|
1269
|
+
}
|
|
1270
|
+
walkBinaryExpression(path) {
|
|
1271
|
+
const left = path.get("left");
|
|
1272
|
+
this.walkNode(left);
|
|
1273
|
+
const right = path.get("right");
|
|
1274
|
+
this.walkNode(right);
|
|
1275
|
+
}
|
|
1276
|
+
walkLogicalExpression(path) {
|
|
1277
|
+
const left = path.get("left");
|
|
1278
|
+
this.walkNode(left);
|
|
1279
|
+
const right = path.get("right");
|
|
1280
|
+
this.walkNode(right);
|
|
1281
|
+
}
|
|
1282
|
+
walkObjectExpression(path) {
|
|
1283
|
+
const props = path.get("properties");
|
|
1284
|
+
for (const prop of props) if (prop.isObjectProperty()) {
|
|
1285
|
+
const key = prop.get("key");
|
|
1286
|
+
this.walkNode(key);
|
|
1287
|
+
const value = prop.get("value");
|
|
1288
|
+
this.walkNode(value);
|
|
1289
|
+
}
|
|
1290
|
+
}
|
|
1291
|
+
walkArrayExpression(path) {
|
|
1292
|
+
const elements = path.get("elements");
|
|
1293
|
+
for (const element of elements) this.walkNode(element);
|
|
1294
|
+
}
|
|
1295
|
+
walkNode(arg) {
|
|
1296
|
+
const visited = this.getVisited();
|
|
1297
|
+
if (visited.has(arg)) return;
|
|
1298
|
+
visited.add(arg);
|
|
1299
|
+
if (arg.isIdentifier()) {
|
|
1300
|
+
const binding = arg?.scope?.getBinding?.(arg.node.name);
|
|
1301
|
+
if (binding) this.walkNode(binding.path);
|
|
1302
|
+
} else if (arg.isMemberExpression()) {
|
|
1303
|
+
const objectPath = arg.get("object");
|
|
1304
|
+
if (objectPath.isIdentifier()) {
|
|
1305
|
+
const binding = arg?.scope?.getBinding?.(objectPath.node.name);
|
|
1306
|
+
if (binding) {
|
|
1307
|
+
if (binding.path.isVariableDeclarator()) this.walkVariableDeclarator(binding.path);
|
|
1308
|
+
}
|
|
1309
|
+
}
|
|
1310
|
+
} else if (arg.isTemplateLiteral()) this.walkTemplateLiteral(arg);
|
|
1311
|
+
else if (arg.isStringLiteral()) this.walkStringLiteral(arg);
|
|
1312
|
+
else if (arg.isBinaryExpression()) this.walkBinaryExpression(arg);
|
|
1313
|
+
else if (arg.isLogicalExpression()) this.walkLogicalExpression(arg);
|
|
1314
|
+
else if (arg.isObjectExpression()) this.walkObjectExpression(arg);
|
|
1315
|
+
else if (arg.isArrayExpression()) this.walkArrayExpression(arg);
|
|
1316
|
+
else if (arg.isVariableDeclarator()) this.walkVariableDeclarator(arg);
|
|
1317
|
+
else if (maybeAddImportToken(this.getWritableImports(), arg)) {}
|
|
1318
|
+
}
|
|
1319
|
+
/**
|
|
1320
|
+
* Walk the arguments of a desired call expression so their bindings can be analysed.
|
|
1321
|
+
*/
|
|
1322
|
+
walkCallExpression(path) {
|
|
1323
|
+
if (!this.hasIgnoredCallIdentifiers) return;
|
|
1324
|
+
const calleePath = path.get("callee");
|
|
1325
|
+
if (calleePath.isIdentifier() && this.isIgnoredCallIdentifier(calleePath.node.name)) for (const arg of path.get("arguments")) this.walkNode(arg);
|
|
1326
|
+
}
|
|
1327
|
+
walkExportDeclaration(path) {
|
|
1328
|
+
walkExportDeclaration(this, path);
|
|
1329
|
+
}
|
|
1330
|
+
walkExportNamedDeclaration(path) {
|
|
1331
|
+
walkExportNamedDeclaration(this, path);
|
|
1332
|
+
}
|
|
1333
|
+
walkExportDefaultDeclaration(path) {
|
|
1334
|
+
walkExportDefaultDeclaration(this, path);
|
|
1335
|
+
}
|
|
1336
|
+
walkExportAllDeclaration(path) {
|
|
1337
|
+
walkExportAllDeclaration(this, path);
|
|
1338
|
+
}
|
|
1339
|
+
};
|
|
1340
|
+
//#endregion
|
|
1341
|
+
//#region src/js/taggedTemplateIgnore.ts
|
|
1342
|
+
function createTaggedTemplateIgnore({ matcher, names }) {
|
|
1343
|
+
const bindingIgnoreCache = /* @__PURE__ */ new Map();
|
|
1344
|
+
const taggedTemplateIgnoreCache = /* @__PURE__ */ new WeakMap();
|
|
1345
|
+
const seenBindings = /* @__PURE__ */ new Set();
|
|
1346
|
+
let singleCanonicalIgnoreName;
|
|
1347
|
+
let canonicalIgnoreNames;
|
|
1348
|
+
for (const item of names ?? []) {
|
|
1349
|
+
if (typeof item !== "string") continue;
|
|
1350
|
+
if (singleCanonicalIgnoreName === void 0) {
|
|
1351
|
+
singleCanonicalIgnoreName = item;
|
|
1352
|
+
continue;
|
|
1353
|
+
}
|
|
1354
|
+
if (item === singleCanonicalIgnoreName) continue;
|
|
1355
|
+
if (!canonicalIgnoreNames) {
|
|
1356
|
+
canonicalIgnoreNames = new Set([singleCanonicalIgnoreName, item]);
|
|
1357
|
+
continue;
|
|
1358
|
+
}
|
|
1359
|
+
canonicalIgnoreNames.add(item);
|
|
1360
|
+
}
|
|
1361
|
+
const hasCanonicalIgnoreNames = singleCanonicalIgnoreName !== void 0;
|
|
1362
|
+
const matchesIgnoreName = (value) => {
|
|
1363
|
+
if (hasCanonicalIgnoreNames) {
|
|
1364
|
+
if (canonicalIgnoreNames) {
|
|
1365
|
+
if (canonicalIgnoreNames.has(value)) return true;
|
|
1366
|
+
} else if (value === singleCanonicalIgnoreName) return true;
|
|
1367
|
+
}
|
|
1368
|
+
return matcher(value);
|
|
1369
|
+
};
|
|
1370
|
+
const propertyMatches = (propertyPath) => {
|
|
1371
|
+
if (!propertyPath) return false;
|
|
1372
|
+
if (propertyPath.isIdentifier()) return matchesIgnoreName(propertyPath.node.name);
|
|
1373
|
+
if (propertyPath.isStringLiteral()) return matchesIgnoreName(propertyPath.node.value);
|
|
1374
|
+
return false;
|
|
1375
|
+
};
|
|
1376
|
+
const resolvesMemberExpressionToIgnore = (path, seen) => {
|
|
1377
|
+
if (propertyMatches(path.get("property"))) return true;
|
|
1378
|
+
const objectPath = path.get("object");
|
|
1379
|
+
if (objectPath.isIdentifier()) {
|
|
1380
|
+
const binding = (objectPath?.scope)?.getBinding?.(objectPath.node.name);
|
|
1381
|
+
if (binding) return resolvesToWeappTwIgnore(binding, seen);
|
|
1382
|
+
}
|
|
1383
|
+
return false;
|
|
1384
|
+
};
|
|
1385
|
+
const resolvesToWeappTwIgnore = (binding, seen) => {
|
|
1386
|
+
const cached = bindingIgnoreCache.get(binding);
|
|
1387
|
+
if (cached !== void 0) return cached;
|
|
1388
|
+
if (seen.has(binding)) return false;
|
|
1389
|
+
seen.add(binding);
|
|
1390
|
+
let result = false;
|
|
1391
|
+
const bindingPath = binding.path;
|
|
1392
|
+
if (bindingPath.isImportSpecifier()) {
|
|
1393
|
+
const imported = bindingPath.node.imported;
|
|
1394
|
+
if (imported.type === "Identifier" && matchesIgnoreName(imported.name)) result = true;
|
|
1395
|
+
else if (imported.type === "StringLiteral" && matchesIgnoreName(imported.value)) result = true;
|
|
1396
|
+
} else if (bindingPath.isVariableDeclarator()) {
|
|
1397
|
+
const init = bindingPath.get("init");
|
|
1398
|
+
if (init && init.node) {
|
|
1399
|
+
if (init.isIdentifier()) {
|
|
1400
|
+
const target = binding?.scope?.getBinding?.(init.node.name);
|
|
1401
|
+
if (target) result = resolvesToWeappTwIgnore(target, seen);
|
|
1402
|
+
} else if (init.isMemberExpression()) result = resolvesMemberExpressionToIgnore(init, seen);
|
|
1403
|
+
}
|
|
1404
|
+
}
|
|
1405
|
+
bindingIgnoreCache.set(binding, result);
|
|
1406
|
+
seen.delete(binding);
|
|
1407
|
+
return result;
|
|
1408
|
+
};
|
|
1409
|
+
const getEffectiveTagPath = (tagPath) => {
|
|
1410
|
+
let current = tagPath;
|
|
1411
|
+
while (true) {
|
|
1412
|
+
if (current.isParenthesizedExpression?.() || current.node.type === "ParenthesizedExpression") {
|
|
1413
|
+
current = current.get("expression");
|
|
1414
|
+
continue;
|
|
1415
|
+
}
|
|
1416
|
+
if (current.isTSAsExpression() || current.isTSTypeAssertion()) {
|
|
1417
|
+
current = current.get("expression");
|
|
1418
|
+
continue;
|
|
1419
|
+
}
|
|
1420
|
+
if (current.isTSNonNullExpression()) {
|
|
1421
|
+
current = current.get("expression");
|
|
1422
|
+
continue;
|
|
1423
|
+
}
|
|
1424
|
+
if (current.isTypeCastExpression?.()) {
|
|
1425
|
+
current = current.get("expression");
|
|
1426
|
+
continue;
|
|
1427
|
+
}
|
|
1428
|
+
if (current.isSequenceExpression()) {
|
|
1429
|
+
const last = current.get("expressions").at(-1);
|
|
1430
|
+
if (last) {
|
|
1431
|
+
current = last;
|
|
1432
|
+
continue;
|
|
1433
|
+
}
|
|
1434
|
+
}
|
|
1435
|
+
if (current.isCallExpression?.() || current.node.type === "CallExpression") {
|
|
1436
|
+
current = current.get("callee");
|
|
1437
|
+
continue;
|
|
1438
|
+
}
|
|
1439
|
+
break;
|
|
1440
|
+
}
|
|
1441
|
+
return current;
|
|
1442
|
+
};
|
|
1443
|
+
const evaluateTagPath = (tagPath, seen) => {
|
|
1444
|
+
if (tagPath.isCallExpression?.() || tagPath.node.type === "CallExpression") return evaluateTagPath(tagPath.get("callee"), seen);
|
|
1445
|
+
if (tagPath.isIdentifier()) {
|
|
1446
|
+
if (matchesIgnoreName(tagPath.node.name)) return true;
|
|
1447
|
+
const binding = tagPath?.scope?.getBinding?.(tagPath.node.name);
|
|
1448
|
+
if (binding) return resolvesToWeappTwIgnore(binding, seen);
|
|
1449
|
+
return false;
|
|
1450
|
+
}
|
|
1451
|
+
if (tagPath.isMemberExpression()) return resolvesMemberExpressionToIgnore(tagPath, seen);
|
|
1452
|
+
return false;
|
|
1453
|
+
};
|
|
1454
|
+
const computeIgnore = (tagPath) => {
|
|
1455
|
+
const cached = taggedTemplateIgnoreCache.get(tagPath.node);
|
|
1456
|
+
if (cached !== void 0) return cached;
|
|
1457
|
+
const effectiveTagPath = getEffectiveTagPath(tagPath);
|
|
1458
|
+
const effectiveCached = taggedTemplateIgnoreCache.get(effectiveTagPath.node);
|
|
1459
|
+
if (effectiveCached !== void 0) {
|
|
1460
|
+
taggedTemplateIgnoreCache.set(tagPath.node, effectiveCached);
|
|
1461
|
+
return effectiveCached;
|
|
1462
|
+
}
|
|
1463
|
+
seenBindings.clear();
|
|
1464
|
+
const result = evaluateTagPath(effectiveTagPath, seenBindings);
|
|
1465
|
+
taggedTemplateIgnoreCache.set(effectiveTagPath.node, result);
|
|
1466
|
+
taggedTemplateIgnoreCache.set(tagPath.node, result);
|
|
1467
|
+
return result;
|
|
1468
|
+
};
|
|
1469
|
+
return {
|
|
1470
|
+
shouldIgnore(tagPath) {
|
|
1471
|
+
return computeIgnore(tagPath);
|
|
1472
|
+
},
|
|
1473
|
+
getEffectiveTagPath
|
|
1474
|
+
};
|
|
1475
|
+
}
|
|
1476
|
+
//#endregion
|
|
1477
|
+
//#region src/js/babel.ts
|
|
1478
|
+
const EXPRESSION_WRAPPER_PREFIX = "(\n";
|
|
1479
|
+
const EXPRESSION_WRAPPER_SUFFIX = "\n)";
|
|
1480
|
+
const EMPTY_IGNORED_PATHS = /* @__PURE__ */ new WeakSet();
|
|
1481
|
+
const EMPTY_IMPORT_DECLARATIONS = /* @__PURE__ */ new Set();
|
|
1482
|
+
const EMPTY_EXPORT_DECLARATIONS = /* @__PURE__ */ new Set();
|
|
1483
|
+
const EMPTY_REQUIRE_CALL_PATHS = [];
|
|
1484
|
+
const ignoredTaggedTemplateMatcherCache = /* @__PURE__ */ new WeakMap();
|
|
1485
|
+
let defaultEvalHandler;
|
|
1486
|
+
function getIgnoredTaggedTemplateMatcher(options) {
|
|
1487
|
+
const cached = ignoredTaggedTemplateMatcherCache.get(options);
|
|
1488
|
+
if (cached) return cached;
|
|
1489
|
+
const created = createNameMatcher(options.ignoreTaggedTemplateExpressionIdentifiers, { exact: true });
|
|
1490
|
+
ignoredTaggedTemplateMatcherCache.set(options, created);
|
|
1491
|
+
return created;
|
|
1492
|
+
}
|
|
1493
|
+
function getDefaultEvalHandler() {
|
|
1494
|
+
if (!defaultEvalHandler) throw new Error("Default JS eval handler is not initialized.");
|
|
1495
|
+
return defaultEvalHandler;
|
|
1496
|
+
}
|
|
1497
|
+
function analyzeSource(ast, options, handler, collectModuleMetadata = true) {
|
|
1498
|
+
const jsTokenUpdater = new JsTokenUpdater();
|
|
1499
|
+
const needScope = Boolean(options.ignoreCallExpressionIdentifiers && options.ignoreCallExpressionIdentifiers.length > 0);
|
|
1500
|
+
const ignoredPaths = needScope ? /* @__PURE__ */ new WeakSet() : EMPTY_IGNORED_PATHS;
|
|
1501
|
+
const walker = needScope ? new NodePathWalker({
|
|
1502
|
+
ignoreCallExpressionIdentifiers: options.ignoreCallExpressionIdentifiers,
|
|
1503
|
+
callback(path) {
|
|
1504
|
+
ignoredPaths.add(path);
|
|
1505
|
+
}
|
|
1506
|
+
}) : new NodePathWalker();
|
|
1507
|
+
let taggedTemplateIgnore;
|
|
1508
|
+
const hasTaggedTemplateIgnoreIdentifiers = Boolean(options.ignoreTaggedTemplateExpressionIdentifiers && options.ignoreTaggedTemplateExpressionIdentifiers.length > 0);
|
|
1509
|
+
function getTaggedTemplateIgnore() {
|
|
1510
|
+
if (!taggedTemplateIgnore) taggedTemplateIgnore = createTaggedTemplateIgnore({
|
|
1511
|
+
matcher: getIgnoredTaggedTemplateMatcher(options),
|
|
1512
|
+
names: options.ignoreTaggedTemplateExpressionIdentifiers
|
|
1513
|
+
});
|
|
1514
|
+
return taggedTemplateIgnore;
|
|
1515
|
+
}
|
|
1516
|
+
const targetPaths = [];
|
|
1517
|
+
const importDeclarations = collectModuleMetadata ? /* @__PURE__ */ new Set() : EMPTY_IMPORT_DECLARATIONS;
|
|
1518
|
+
const exportDeclarations = collectModuleMetadata ? /* @__PURE__ */ new Set() : EMPTY_EXPORT_DECLARATIONS;
|
|
1519
|
+
const requireCallPaths = collectModuleMetadata ? [] : EMPTY_REQUIRE_CALL_PATHS;
|
|
1520
|
+
const evalHandler = handler ?? getDefaultEvalHandler();
|
|
1521
|
+
traverse(ast, {
|
|
1522
|
+
StringLiteral: { enter(p) {
|
|
1523
|
+
if (isEvalPath(p.parentPath)) return;
|
|
1524
|
+
targetPaths.push(p);
|
|
1525
|
+
} },
|
|
1526
|
+
TemplateElement: { enter: hasTaggedTemplateIgnoreIdentifiers ? (p) => {
|
|
1527
|
+
const pp = p.parentPath;
|
|
1528
|
+
if (pp.isTemplateLiteral()) {
|
|
1529
|
+
const ppp = pp.parentPath;
|
|
1530
|
+
if (isEvalPath(ppp)) return;
|
|
1531
|
+
if (ppp.isTaggedTemplateExpression()) {
|
|
1532
|
+
const tagPath = ppp.get("tag");
|
|
1533
|
+
if (getTaggedTemplateIgnore().shouldIgnore(tagPath)) return;
|
|
1534
|
+
}
|
|
1535
|
+
}
|
|
1536
|
+
targetPaths.push(p);
|
|
1537
|
+
} : (p) => {
|
|
1538
|
+
const pp = p.parentPath;
|
|
1539
|
+
if (pp.isTemplateLiteral()) {
|
|
1540
|
+
const ppp = pp.parentPath;
|
|
1541
|
+
if (isEvalPath(ppp)) return;
|
|
1542
|
+
}
|
|
1543
|
+
targetPaths.push(p);
|
|
1544
|
+
} },
|
|
1545
|
+
CallExpression: { enter: !collectModuleMetadata && !needScope ? (p) => {
|
|
1546
|
+
if (isEvalPath(p)) walkEvalExpression(p, options, jsTokenUpdater, evalHandler);
|
|
1547
|
+
} : (p) => {
|
|
1548
|
+
if (isEvalPath(p)) {
|
|
1549
|
+
walkEvalExpression(p, options, jsTokenUpdater, evalHandler);
|
|
1550
|
+
return;
|
|
1551
|
+
}
|
|
1552
|
+
const calleePath = p.get("callee");
|
|
1553
|
+
if (collectModuleMetadata && calleePath.isIdentifier({ name: "require" }) && !p?.scope?.hasBinding?.("require")) {
|
|
1554
|
+
const args = p.get("arguments");
|
|
1555
|
+
if (Array.isArray(args) && args.length > 0) {
|
|
1556
|
+
const first = args[0];
|
|
1557
|
+
if (first?.isStringLiteral()) requireCallPaths.push(first);
|
|
1558
|
+
}
|
|
1559
|
+
}
|
|
1560
|
+
if (needScope) walker.walkCallExpression(p);
|
|
1561
|
+
} },
|
|
1562
|
+
...collectModuleMetadata ? {
|
|
1563
|
+
ImportDeclaration: { enter(p) {
|
|
1564
|
+
importDeclarations.add(p);
|
|
1565
|
+
} },
|
|
1566
|
+
ExportDeclaration: { enter(p) {
|
|
1567
|
+
exportDeclarations.add(p);
|
|
1568
|
+
} }
|
|
1569
|
+
} : {},
|
|
1570
|
+
noScope: !needScope
|
|
1571
|
+
});
|
|
1572
|
+
return {
|
|
1573
|
+
walker,
|
|
1574
|
+
jsTokenUpdater,
|
|
1575
|
+
ast,
|
|
1576
|
+
targetPaths,
|
|
1577
|
+
importDeclarations,
|
|
1578
|
+
exportDeclarations,
|
|
1579
|
+
requireCallPaths,
|
|
1580
|
+
ignoredPaths
|
|
1581
|
+
};
|
|
1582
|
+
}
|
|
1583
|
+
function jsHandler(rawSource, options) {
|
|
1584
|
+
const shouldWrapExpression = Boolean(options.wrapExpression);
|
|
1585
|
+
const source = shouldWrapExpression ? `${EXPRESSION_WRAPPER_PREFIX}${rawSource}${EXPRESSION_WRAPPER_SUFFIX}` : rawSource;
|
|
1586
|
+
let ast;
|
|
1587
|
+
try {
|
|
1588
|
+
ast = babelParse(source, options.babelParserOptions);
|
|
1589
|
+
} catch (error) {
|
|
1590
|
+
return {
|
|
1591
|
+
code: rawSource,
|
|
1592
|
+
error
|
|
1593
|
+
};
|
|
1594
|
+
}
|
|
1595
|
+
const needsModuleMetadata = Boolean(options.moduleSpecifierReplacements || options.moduleGraph && options.filename);
|
|
1596
|
+
const analysis = analyzeSource(ast, options, jsHandler, needsModuleMetadata);
|
|
1597
|
+
const ms = processUpdatedSource(source, options, analysis);
|
|
1598
|
+
if (shouldWrapExpression) {
|
|
1599
|
+
const start = 0;
|
|
1600
|
+
const end = source.length;
|
|
1601
|
+
const prefixLength = 2;
|
|
1602
|
+
const suffixLength = 2;
|
|
1603
|
+
ms.remove(start, start + prefixLength);
|
|
1604
|
+
ms.remove(end - suffixLength, end);
|
|
1605
|
+
}
|
|
1606
|
+
const result = { code: ms.toString() };
|
|
1607
|
+
if (options.generateMap) Object.defineProperty(result, "map", {
|
|
1608
|
+
configurable: true,
|
|
1609
|
+
enumerable: true,
|
|
1610
|
+
get() {
|
|
1611
|
+
return ms.generateMap();
|
|
1612
|
+
}
|
|
1613
|
+
});
|
|
1614
|
+
if (options.moduleGraph && options.filename) {
|
|
1615
|
+
const linked = new JsModuleGraph({
|
|
1616
|
+
filename: options.filename,
|
|
1617
|
+
source: rawSource,
|
|
1618
|
+
analysis,
|
|
1619
|
+
handlerOptions: options
|
|
1620
|
+
}, options.moduleGraph).build();
|
|
1621
|
+
if (linked) result.linked = linked;
|
|
1622
|
+
}
|
|
1623
|
+
return result;
|
|
1624
|
+
}
|
|
1625
|
+
defaultEvalHandler = jsHandler;
|
|
1626
|
+
Object.freeze({ wrapExpression: true });
|
|
1627
|
+
//#endregion
|
|
1628
|
+
//#region src/wxml/whitespace.ts
|
|
1629
|
+
const WHITESPACE_CODES = new Set([
|
|
1630
|
+
9,
|
|
1631
|
+
10,
|
|
1632
|
+
11,
|
|
1633
|
+
12,
|
|
1634
|
+
13,
|
|
1635
|
+
32,
|
|
1636
|
+
160,
|
|
1637
|
+
65279
|
|
702
1638
|
]);
|
|
703
1639
|
function isWhitespace(char) {
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
}
|
|
707
|
-
return WHITESPACE_CODES.has(char.charCodeAt(0));
|
|
1640
|
+
if (char.length === 0) return false;
|
|
1641
|
+
return WHITESPACE_CODES.has(char.charCodeAt(0));
|
|
708
1642
|
}
|
|
709
|
-
|
|
710
|
-
|
|
1643
|
+
//#endregion
|
|
1644
|
+
//#region src/wxml/Tokenizer.ts
|
|
711
1645
|
var Tokenizer = class {
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
}
|
|
1646
|
+
constructor() {
|
|
1647
|
+
this.reset();
|
|
1648
|
+
}
|
|
1649
|
+
processChar(char, index) {
|
|
1650
|
+
switch (this.state) {
|
|
1651
|
+
case 0:
|
|
1652
|
+
if (isWhitespace(char)) {} else if (char === "{") {
|
|
1653
|
+
this.state = 2;
|
|
1654
|
+
this.bufferStartIndex = index;
|
|
1655
|
+
this.buffer += char;
|
|
1656
|
+
this.expressionBuffer = char;
|
|
1657
|
+
this.expressionStartIndex = index;
|
|
1658
|
+
} else {
|
|
1659
|
+
this.state = 1;
|
|
1660
|
+
this.bufferStartIndex = index;
|
|
1661
|
+
this.buffer += char;
|
|
1662
|
+
}
|
|
1663
|
+
break;
|
|
1664
|
+
case 1:
|
|
1665
|
+
if (isWhitespace(char)) {
|
|
1666
|
+
this.tokens.push({
|
|
1667
|
+
start: this.bufferStartIndex,
|
|
1668
|
+
end: index,
|
|
1669
|
+
value: this.buffer,
|
|
1670
|
+
expressions: this.expressions
|
|
1671
|
+
});
|
|
1672
|
+
this.buffer = "";
|
|
1673
|
+
this.expressions = [];
|
|
1674
|
+
this.state = 0;
|
|
1675
|
+
} else if (char === "{") {
|
|
1676
|
+
this.buffer += char;
|
|
1677
|
+
this.expressionBuffer = char;
|
|
1678
|
+
this.expressionStartIndex = index;
|
|
1679
|
+
this.state = 2;
|
|
1680
|
+
} else this.buffer += char;
|
|
1681
|
+
break;
|
|
1682
|
+
case 2:
|
|
1683
|
+
if (char === "}") {
|
|
1684
|
+
this.buffer += char;
|
|
1685
|
+
this.expressionBuffer += char;
|
|
1686
|
+
this.state = 3;
|
|
1687
|
+
} else {
|
|
1688
|
+
this.buffer += char;
|
|
1689
|
+
this.expressionBuffer += char;
|
|
1690
|
+
}
|
|
1691
|
+
break;
|
|
1692
|
+
case 3:
|
|
1693
|
+
if (char === "}") {
|
|
1694
|
+
this.buffer += char;
|
|
1695
|
+
this.expressionBuffer += char;
|
|
1696
|
+
this.expressions.push({
|
|
1697
|
+
start: this.expressionStartIndex,
|
|
1698
|
+
end: index + 1,
|
|
1699
|
+
value: this.expressionBuffer
|
|
1700
|
+
});
|
|
1701
|
+
this.expressionBuffer = "";
|
|
1702
|
+
this.state = 4;
|
|
1703
|
+
} else {
|
|
1704
|
+
this.buffer += char;
|
|
1705
|
+
this.expressionBuffer += char;
|
|
1706
|
+
this.state = 2;
|
|
1707
|
+
}
|
|
1708
|
+
break;
|
|
1709
|
+
case 4:
|
|
1710
|
+
if (isWhitespace(char)) {
|
|
1711
|
+
this.tokens.push({
|
|
1712
|
+
start: this.bufferStartIndex,
|
|
1713
|
+
end: index,
|
|
1714
|
+
value: this.buffer,
|
|
1715
|
+
expressions: this.expressions
|
|
1716
|
+
});
|
|
1717
|
+
this.buffer = "";
|
|
1718
|
+
this.expressions = [];
|
|
1719
|
+
this.state = 0;
|
|
1720
|
+
} else if (char === "{") {
|
|
1721
|
+
this.expressionStartIndex = index;
|
|
1722
|
+
this.expressionBuffer = char;
|
|
1723
|
+
this.buffer += char;
|
|
1724
|
+
this.state = 2;
|
|
1725
|
+
} else {
|
|
1726
|
+
this.buffer += char;
|
|
1727
|
+
this.state = 1;
|
|
1728
|
+
}
|
|
1729
|
+
break;
|
|
1730
|
+
default: throw new Error("Unexpected state");
|
|
1731
|
+
}
|
|
1732
|
+
}
|
|
1733
|
+
run(input) {
|
|
1734
|
+
this.reset();
|
|
1735
|
+
for (let i = 0; i < input.length; i++) {
|
|
1736
|
+
const char = input[i];
|
|
1737
|
+
this.processChar(char, i);
|
|
1738
|
+
}
|
|
1739
|
+
if (this.buffer.length > 0) this.tokens.push({
|
|
1740
|
+
start: this.bufferStartIndex,
|
|
1741
|
+
end: input.length,
|
|
1742
|
+
value: this.buffer,
|
|
1743
|
+
expressions: this.expressions
|
|
1744
|
+
});
|
|
1745
|
+
const tokens = this.tokens;
|
|
1746
|
+
this.reset();
|
|
1747
|
+
return tokens;
|
|
1748
|
+
}
|
|
1749
|
+
reset() {
|
|
1750
|
+
this.state = 0;
|
|
1751
|
+
this.buffer = "";
|
|
1752
|
+
this.tokens = [];
|
|
1753
|
+
this.bufferStartIndex = 0;
|
|
1754
|
+
this.expressionBuffer = "";
|
|
1755
|
+
this.expressionStartIndex = 0;
|
|
1756
|
+
this.expressions = [];
|
|
1757
|
+
}
|
|
825
1758
|
};
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
// src/context/logger.ts
|
|
831
|
-
import { logger as logger8 } from "@weapp-tailwindcss/logger";
|
|
832
|
-
|
|
833
|
-
// src/context/tailwindcss.ts
|
|
834
|
-
import { logger as logger10 } from "@weapp-tailwindcss/logger";
|
|
835
|
-
|
|
836
|
-
// src/context/tailwindcss/basedir.ts
|
|
837
|
-
import { createRequire as createRequire2 } from "module";
|
|
838
|
-
import path10 from "path";
|
|
839
|
-
import process10 from "process";
|
|
840
|
-
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
841
|
-
import { logger as logger9 } from "@weapp-tailwindcss/logger";
|
|
842
|
-
|
|
843
|
-
// src/context/tailwindcss/rax.ts
|
|
844
|
-
import { existsSync as existsSync5, readFileSync as readFileSync3 } from "fs";
|
|
845
|
-
import path11 from "path";
|
|
846
|
-
import process11 from "process";
|
|
847
|
-
|
|
848
|
-
// src/context/index.ts
|
|
1759
|
+
new Tokenizer();
|
|
1760
|
+
//#endregion
|
|
1761
|
+
//#region src/context/index.ts
|
|
849
1762
|
async function clearTailwindcssPatcherCache(patcher, options) {
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
if (!cachePaths.size) {
|
|
880
|
-
return;
|
|
881
|
-
}
|
|
882
|
-
for (const [cachePath, recursive] of cachePaths.entries()) {
|
|
883
|
-
try {
|
|
884
|
-
await rm(cachePath, { force: true, recursive });
|
|
885
|
-
} catch (error) {
|
|
886
|
-
const err = error;
|
|
887
|
-
if (err?.code === "ENOENT") {
|
|
888
|
-
continue;
|
|
889
|
-
}
|
|
890
|
-
logger11.debug("failed to clear tailwindcss patcher cache: %s %O", cachePath, err);
|
|
891
|
-
}
|
|
892
|
-
}
|
|
893
|
-
}
|
|
894
|
-
|
|
895
|
-
// src/cli/context.ts
|
|
1763
|
+
if (!patcher) return;
|
|
1764
|
+
const cacheOptions = patcher.options?.cache;
|
|
1765
|
+
if (cacheOptions == null || typeof cacheOptions === "object" && cacheOptions.enabled === false) return;
|
|
1766
|
+
if (typeof patcher.clearCache === "function") try {
|
|
1767
|
+
await patcher.clearCache({ scope: "all" });
|
|
1768
|
+
} catch (error) {
|
|
1769
|
+
logger.debug("failed to clear tailwindcss patcher cache via clearCache(): %O", error);
|
|
1770
|
+
}
|
|
1771
|
+
if (!options?.removeDirectory) return;
|
|
1772
|
+
const cachePaths = /* @__PURE__ */ new Map();
|
|
1773
|
+
const normalizedCacheOptions = typeof cacheOptions === "object" ? cacheOptions : void 0;
|
|
1774
|
+
if (normalizedCacheOptions?.path) cachePaths.set(normalizedCacheOptions.path, false);
|
|
1775
|
+
const privateCachePath = patcher?.cacheStore?.options?.path;
|
|
1776
|
+
if (privateCachePath) cachePaths.set(privateCachePath, false);
|
|
1777
|
+
if (options?.removeDirectory && normalizedCacheOptions?.dir) cachePaths.set(normalizedCacheOptions.dir, true);
|
|
1778
|
+
if (!cachePaths.size) return;
|
|
1779
|
+
for (const [cachePath, recursive] of cachePaths.entries()) try {
|
|
1780
|
+
await rm(cachePath, {
|
|
1781
|
+
force: true,
|
|
1782
|
+
recursive
|
|
1783
|
+
});
|
|
1784
|
+
} catch (error) {
|
|
1785
|
+
const err = error;
|
|
1786
|
+
if (err?.code === "ENOENT") continue;
|
|
1787
|
+
logger.debug("failed to clear tailwindcss patcher cache: %s %O", cachePath, err);
|
|
1788
|
+
}
|
|
1789
|
+
}
|
|
1790
|
+
//#endregion
|
|
1791
|
+
//#region src/cli/context.ts
|
|
896
1792
|
function formatOutputPath(target, baseDir) {
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
1793
|
+
const root = baseDir ?? process.cwd();
|
|
1794
|
+
const relative = path.relative(root, target);
|
|
1795
|
+
if (!relative) return ".";
|
|
1796
|
+
if (relative.startsWith("..")) return path.normalize(target);
|
|
1797
|
+
return relative.startsWith(".") ? relative : `.${path.sep}${relative}`;
|
|
1798
|
+
}
|
|
1799
|
+
//#endregion
|
|
1800
|
+
//#region src/cli/doctor/constants.ts
|
|
1801
|
+
const CONFIG_FILES = {
|
|
1802
|
+
tailwind: [
|
|
1803
|
+
"tailwind.config.js",
|
|
1804
|
+
"tailwind.config.cjs",
|
|
1805
|
+
"tailwind.config.mjs",
|
|
1806
|
+
"tailwind.config.ts"
|
|
1807
|
+
],
|
|
1808
|
+
postcss: [
|
|
1809
|
+
"postcss.config.js",
|
|
1810
|
+
"postcss.config.cjs",
|
|
1811
|
+
"postcss.config.mjs",
|
|
1812
|
+
"postcss.config.ts"
|
|
1813
|
+
],
|
|
1814
|
+
vite: [
|
|
1815
|
+
"vite.config.js",
|
|
1816
|
+
"vite.config.mjs",
|
|
1817
|
+
"vite.config.ts"
|
|
1818
|
+
],
|
|
1819
|
+
webpack: [
|
|
1820
|
+
"webpack.config.js",
|
|
1821
|
+
"webpack.config.cjs",
|
|
1822
|
+
"webpack.config.ts"
|
|
1823
|
+
]
|
|
1824
|
+
};
|
|
1825
|
+
const FRAMEWORK_DEPS = [
|
|
1826
|
+
["@tarojs/taro", "Taro"],
|
|
1827
|
+
["@dcloudio/uni-app", "uni-app"],
|
|
1828
|
+
["@mpxjs/core", "MPX"],
|
|
1829
|
+
["remax", "Remax"],
|
|
1830
|
+
["rax", "Rax"]
|
|
1831
|
+
];
|
|
1832
|
+
//#endregion
|
|
1833
|
+
//#region src/cli/doctor.ts
|
|
1834
|
+
function tryReadJson$1(file) {
|
|
1835
|
+
try {
|
|
1836
|
+
return JSON.parse(readFileSync(file, "utf8"));
|
|
1837
|
+
} catch {
|
|
1838
|
+
return;
|
|
1839
|
+
}
|
|
1840
|
+
}
|
|
1841
|
+
function findFirstExisting(cwd, files) {
|
|
1842
|
+
return files.find((file) => existsSync(path.join(cwd, file)));
|
|
1843
|
+
}
|
|
1844
|
+
function readProjectPackageJson(cwd) {
|
|
1845
|
+
return tryReadJson$1(path.join(cwd, "package.json"));
|
|
1846
|
+
}
|
|
1847
|
+
function readDependencyVersion(cwd, packageName) {
|
|
1848
|
+
try {
|
|
1849
|
+
return tryReadJson$1(createRequire(path.join(cwd, "package.json")).resolve(`${packageName}/package.json`))?.version;
|
|
1850
|
+
} catch {
|
|
1851
|
+
return;
|
|
1852
|
+
}
|
|
1853
|
+
}
|
|
1854
|
+
function collectDependencySpecs(pkg) {
|
|
1855
|
+
return {
|
|
1856
|
+
...pkg?.dependencies ?? {},
|
|
1857
|
+
...pkg?.devDependencies ?? {},
|
|
1858
|
+
...pkg?.optionalDependencies ?? {},
|
|
1859
|
+
...pkg?.peerDependencies ?? {}
|
|
1860
|
+
};
|
|
1861
|
+
}
|
|
1862
|
+
function detectPackageManager(cwd, pkg) {
|
|
1863
|
+
if (pkg?.packageManager) return pkg.packageManager;
|
|
1864
|
+
if (existsSync(path.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
|
|
1865
|
+
if (existsSync(path.join(cwd, "package-lock.json"))) return "npm";
|
|
1866
|
+
if (existsSync(path.join(cwd, "yarn.lock"))) return "yarn";
|
|
1867
|
+
}
|
|
1868
|
+
function detectFrameworks(deps) {
|
|
1869
|
+
return FRAMEWORK_DEPS.filter(([dependency]) => dependency in deps).map(([, label]) => label);
|
|
1870
|
+
}
|
|
1871
|
+
function addCheck(checks, check) {
|
|
1872
|
+
checks.push(check);
|
|
1873
|
+
}
|
|
1874
|
+
function summarizeChecks(checks) {
|
|
1875
|
+
return checks.reduce((summary, check) => {
|
|
1876
|
+
summary[check.status] += 1;
|
|
1877
|
+
return summary;
|
|
1878
|
+
}, {
|
|
1879
|
+
ok: 0,
|
|
1880
|
+
warn: 0,
|
|
1881
|
+
error: 0,
|
|
1882
|
+
info: 0
|
|
1883
|
+
});
|
|
1884
|
+
}
|
|
1885
|
+
function hasDependency(deps, packageName) {
|
|
1886
|
+
return packageName in deps;
|
|
1887
|
+
}
|
|
1888
|
+
function getMajorVersion(version) {
|
|
1889
|
+
if (!version) return;
|
|
1890
|
+
return semver.parse(version)?.major;
|
|
1891
|
+
}
|
|
1892
|
+
function getDependencyMajor(deps, packageName) {
|
|
1893
|
+
const spec = deps[packageName];
|
|
1894
|
+
return spec ? semver.minVersion(spec)?.major : void 0;
|
|
1895
|
+
}
|
|
1896
|
+
function createDoctorReport(options = {}) {
|
|
1897
|
+
const cwd = path.resolve(options.cwd ?? process.cwd());
|
|
1898
|
+
const nodeVersion = options.nodeVersion ?? process.versions.node;
|
|
1899
|
+
const pkg = readProjectPackageJson(cwd);
|
|
1900
|
+
const deps = collectDependencySpecs(pkg);
|
|
1901
|
+
const checks = [];
|
|
1902
|
+
const packageManager = detectPackageManager(cwd, pkg);
|
|
1903
|
+
const frameworks = detectFrameworks(deps);
|
|
1904
|
+
const tailwindcssVersion = readDependencyVersion(cwd, "tailwindcss");
|
|
1905
|
+
const weappTailwindcssVersion = readDependencyVersion(cwd, "weapp-tailwindcss");
|
|
1906
|
+
const tailwindMajor = getMajorVersion(tailwindcssVersion) ?? getDependencyMajor(deps, "tailwindcss");
|
|
1907
|
+
const tailwindConfig = findFirstExisting(cwd, CONFIG_FILES.tailwind);
|
|
1908
|
+
const postcssConfig = findFirstExisting(cwd, CONFIG_FILES.postcss);
|
|
1909
|
+
const viteConfig = findFirstExisting(cwd, CONFIG_FILES.vite);
|
|
1910
|
+
const webpackConfig = findFirstExisting(cwd, CONFIG_FILES.webpack);
|
|
1911
|
+
addCheck(checks, pkg ? {
|
|
1912
|
+
id: "package-json",
|
|
1913
|
+
title: "package.json",
|
|
1914
|
+
status: "ok",
|
|
1915
|
+
message: "已找到项目 package.json。"
|
|
1916
|
+
} : {
|
|
1917
|
+
id: "package-json",
|
|
1918
|
+
title: "package.json",
|
|
1919
|
+
status: "error",
|
|
1920
|
+
message: "当前目录没有 package.json。",
|
|
1921
|
+
suggestion: "请在项目根目录运行 doctor,或通过 --cwd 指向项目根目录。"
|
|
1922
|
+
});
|
|
1923
|
+
addCheck(checks, semver.satisfies(nodeVersion, "^20.19.0 || >=22.12.0") ? {
|
|
1924
|
+
id: "node-version",
|
|
1925
|
+
title: "Node.js",
|
|
1926
|
+
status: "ok",
|
|
1927
|
+
message: `当前 Node.js ${nodeVersion} 满足版本要求 ${WEAPP_TW_REQUIRED_NODE_VERSION_RANGE}。`
|
|
1928
|
+
} : {
|
|
1929
|
+
id: "node-version",
|
|
1930
|
+
title: "Node.js",
|
|
1931
|
+
status: "error",
|
|
1932
|
+
message: `当前 Node.js ${nodeVersion} 不满足版本要求 ${WEAPP_TW_REQUIRED_NODE_VERSION_RANGE}。`,
|
|
1933
|
+
suggestion: "请升级 Node.js 后再安装或构建 weapp-tailwindcss 项目。"
|
|
1934
|
+
});
|
|
1935
|
+
addCheck(checks, packageManager ? {
|
|
1936
|
+
id: "package-manager",
|
|
1937
|
+
title: "包管理器",
|
|
1938
|
+
status: packageManager.startsWith("pnpm") ? "ok" : "info",
|
|
1939
|
+
message: `检测到 ${packageManager}。`
|
|
1940
|
+
} : {
|
|
1941
|
+
id: "package-manager",
|
|
1942
|
+
title: "包管理器",
|
|
1943
|
+
status: "info",
|
|
1944
|
+
message: "未检测到 lockfile 或 packageManager 字段。"
|
|
1945
|
+
});
|
|
1946
|
+
addCheck(checks, hasDependency(deps, "weapp-tailwindcss") || Boolean(weappTailwindcssVersion) ? {
|
|
1947
|
+
id: "weapp-tailwindcss",
|
|
1948
|
+
title: "weapp-tailwindcss",
|
|
1949
|
+
status: "ok",
|
|
1950
|
+
message: `检测到 weapp-tailwindcss${weappTailwindcssVersion ? `@${weappTailwindcssVersion}` : ""}。`
|
|
1951
|
+
} : {
|
|
1952
|
+
id: "weapp-tailwindcss",
|
|
1953
|
+
title: "weapp-tailwindcss",
|
|
1954
|
+
status: "warn",
|
|
1955
|
+
message: "未在当前项目依赖中检测到 weapp-tailwindcss。",
|
|
1956
|
+
suggestion: "如果这是业务项目,请安装 weapp-tailwindcss 并确认命令运行在项目根目录。"
|
|
1957
|
+
});
|
|
1958
|
+
addCheck(checks, hasDependency(deps, "tailwindcss") || Boolean(tailwindcssVersion) ? {
|
|
1959
|
+
id: "tailwindcss",
|
|
1960
|
+
title: "Tailwind CSS",
|
|
1961
|
+
status: "ok",
|
|
1962
|
+
message: `检测到 tailwindcss${tailwindcssVersion ? `@${tailwindcssVersion}` : ""}。`
|
|
1963
|
+
} : {
|
|
1964
|
+
id: "tailwindcss",
|
|
1965
|
+
title: "Tailwind CSS",
|
|
1966
|
+
status: "error",
|
|
1967
|
+
message: "未检测到 tailwindcss。",
|
|
1968
|
+
suggestion: "请安装 tailwindcss,并确认依赖可以从当前项目解析。"
|
|
1969
|
+
});
|
|
1970
|
+
addCheck(checks, tailwindConfig ? {
|
|
1971
|
+
id: "tailwind-config",
|
|
1972
|
+
title: "Tailwind 配置",
|
|
1973
|
+
status: "ok",
|
|
1974
|
+
message: `检测到 ${tailwindConfig}。`
|
|
1975
|
+
} : {
|
|
1976
|
+
id: "tailwind-config",
|
|
1977
|
+
title: "Tailwind 配置",
|
|
1978
|
+
status: tailwindMajor === 4 ? "info" : "warn",
|
|
1979
|
+
message: "未检测到 tailwind.config.*。",
|
|
1980
|
+
suggestion: tailwindMajor === 4 ? "Tailwind CSS v4 可以采用 CSS-first 配置;如果使用 v3 或复杂 content/source,请补充配置文件。" : "请确认 Tailwind content/source 配置能够覆盖小程序页面、组件和脚本文件。"
|
|
1981
|
+
});
|
|
1982
|
+
addCheck(checks, postcssConfig ? {
|
|
1983
|
+
id: "postcss-config",
|
|
1984
|
+
title: "PostCSS 配置",
|
|
1985
|
+
status: "ok",
|
|
1986
|
+
message: `检测到 ${postcssConfig}。`
|
|
1987
|
+
} : {
|
|
1988
|
+
id: "postcss-config",
|
|
1989
|
+
title: "PostCSS 配置",
|
|
1990
|
+
status: viteConfig ? "info" : "warn",
|
|
1991
|
+
message: "未检测到 postcss.config.*。",
|
|
1992
|
+
suggestion: "如果通过 PostCSS 接入,请补充 postcss.config.*;如果通过 Vite/Taro 插件接入,可忽略此项。"
|
|
1993
|
+
});
|
|
1994
|
+
if (tailwindMajor === 4 && postcssConfig && !hasDependency(deps, "@tailwindcss/postcss")) addCheck(checks, {
|
|
1995
|
+
id: "tailwindcss-v4-postcss",
|
|
1996
|
+
title: "Tailwind v4 PostCSS",
|
|
1997
|
+
status: "warn",
|
|
1998
|
+
message: "Tailwind CSS v4 项目存在 PostCSS 配置,但未检测到 @tailwindcss/postcss。",
|
|
1999
|
+
suggestion: "如果 PostCSS 配置中仍直接使用 tailwindcss,请迁移到 @tailwindcss/postcss。"
|
|
2000
|
+
});
|
|
2001
|
+
addCheck(checks, frameworks.length > 0 ? {
|
|
2002
|
+
id: "framework",
|
|
2003
|
+
title: "框架识别",
|
|
2004
|
+
status: "ok",
|
|
2005
|
+
message: `检测到 ${frameworks.join(", ")}。`
|
|
2006
|
+
} : {
|
|
2007
|
+
id: "framework",
|
|
2008
|
+
title: "框架识别",
|
|
2009
|
+
status: "info",
|
|
2010
|
+
message: "未从依赖中识别出 Taro、uni-app、MPX、Remax 或 Rax。"
|
|
2011
|
+
});
|
|
2012
|
+
addCheck(checks, viteConfig || webpackConfig ? {
|
|
2013
|
+
id: "bundler-config",
|
|
2014
|
+
title: "构建器配置",
|
|
2015
|
+
status: "ok",
|
|
2016
|
+
message: `检测到 ${[viteConfig, webpackConfig].filter(Boolean).join(", ")}。`
|
|
2017
|
+
} : {
|
|
2018
|
+
id: "bundler-config",
|
|
2019
|
+
title: "构建器配置",
|
|
2020
|
+
status: "info",
|
|
2021
|
+
message: "未检测到 vite.config.* 或 webpack.config.*。"
|
|
2022
|
+
});
|
|
2023
|
+
return {
|
|
2024
|
+
cwd,
|
|
2025
|
+
nodeVersion,
|
|
2026
|
+
detected: {
|
|
2027
|
+
packageManager,
|
|
2028
|
+
frameworks,
|
|
2029
|
+
tailwindcssVersion,
|
|
2030
|
+
weappTailwindcssVersion
|
|
2031
|
+
},
|
|
2032
|
+
summary: summarizeChecks(checks),
|
|
2033
|
+
checks
|
|
2034
|
+
};
|
|
2035
|
+
}
|
|
2036
|
+
function hasDoctorFailure(report, strict = false) {
|
|
2037
|
+
return report.summary.error > 0 || strict && report.summary.warn > 0;
|
|
2038
|
+
}
|
|
2039
|
+
function formatDoctorReport(report) {
|
|
2040
|
+
const lines = [
|
|
2041
|
+
`weapp-tailwindcss doctor`,
|
|
2042
|
+
`cwd: ${report.cwd}`,
|
|
2043
|
+
`summary: ${report.summary.error} error, ${report.summary.warn} warn, ${report.summary.ok} ok, ${report.summary.info} info`,
|
|
2044
|
+
""
|
|
2045
|
+
];
|
|
2046
|
+
for (const check of report.checks) {
|
|
2047
|
+
lines.push(`[${check.status}] ${check.title}: ${check.message}`);
|
|
2048
|
+
if (check.suggestion) lines.push(` -> ${check.suggestion}`);
|
|
2049
|
+
}
|
|
2050
|
+
return lines.join("\n");
|
|
2051
|
+
}
|
|
2052
|
+
//#endregion
|
|
2053
|
+
//#region src/cli/helpers/options/parse.ts
|
|
916
2054
|
function readStringOption(flag, value) {
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
}
|
|
923
|
-
const trimmed = value.trim();
|
|
924
|
-
if (trimmed.length === 0) {
|
|
925
|
-
throw new TypeError(`Option "--${flag}" expects a non-empty value.`);
|
|
926
|
-
}
|
|
927
|
-
return trimmed;
|
|
2055
|
+
if (value == null) return;
|
|
2056
|
+
if (typeof value !== "string") throw new TypeError(`Option "--${flag}" expects a string value.`);
|
|
2057
|
+
const trimmed = value.trim();
|
|
2058
|
+
if (trimmed.length === 0) throw new TypeError(`Option "--${flag}" expects a non-empty value.`);
|
|
2059
|
+
return trimmed;
|
|
928
2060
|
}
|
|
929
2061
|
function readStringArrayOption(flag, value) {
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
return trimmed;
|
|
943
|
-
});
|
|
944
|
-
return normalized2.length > 0 ? normalized2 : void 0;
|
|
945
|
-
}
|
|
946
|
-
const normalized = readStringOption(flag, value);
|
|
947
|
-
return normalized ? [normalized] : void 0;
|
|
2062
|
+
if (value == null) return;
|
|
2063
|
+
if (Array.isArray(value)) {
|
|
2064
|
+
const normalized = value.filter((entry) => entry != null).map((entry) => {
|
|
2065
|
+
if (typeof entry !== "string") throw new TypeError(`Option "--${flag}" expects string values.`);
|
|
2066
|
+
const trimmed = entry.trim();
|
|
2067
|
+
if (!trimmed) throw new TypeError(`Option "--${flag}" expects non-empty values.`);
|
|
2068
|
+
return trimmed;
|
|
2069
|
+
});
|
|
2070
|
+
return normalized.length > 0 ? normalized : void 0;
|
|
2071
|
+
}
|
|
2072
|
+
const normalized = readStringOption(flag, value);
|
|
2073
|
+
return normalized ? [normalized] : void 0;
|
|
948
2074
|
}
|
|
949
2075
|
function toBoolean(value, fallback) {
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
}
|
|
961
|
-
if (value == null) {
|
|
962
|
-
return fallback;
|
|
963
|
-
}
|
|
964
|
-
return Boolean(value);
|
|
965
|
-
}
|
|
966
|
-
|
|
967
|
-
// src/cli/helpers/options/resolve.ts
|
|
968
|
-
import path13 from "path";
|
|
969
|
-
import process13 from "process";
|
|
2076
|
+
if (typeof value === "boolean") return value;
|
|
2077
|
+
if (typeof value === "string") {
|
|
2078
|
+
if (value === "true") return true;
|
|
2079
|
+
if (value === "false") return false;
|
|
2080
|
+
}
|
|
2081
|
+
if (value == null) return fallback;
|
|
2082
|
+
return Boolean(value);
|
|
2083
|
+
}
|
|
2084
|
+
//#endregion
|
|
2085
|
+
//#region src/cli/helpers/options/resolve.ts
|
|
970
2086
|
function resolveCliCwd(value) {
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
// src/cli/helpers/patch-cwd.ts
|
|
979
|
-
import path14 from "path";
|
|
980
|
-
import process14 from "process";
|
|
981
|
-
|
|
982
|
-
// src/tailwindcss/index.ts
|
|
983
|
-
import { getPackageInfoSync } from "local-pkg";
|
|
2087
|
+
const raw = readStringOption("cwd", value);
|
|
2088
|
+
if (!raw) return;
|
|
2089
|
+
return path.isAbsolute(raw) ? path.normalize(raw) : path.resolve(process.cwd(), raw);
|
|
2090
|
+
}
|
|
2091
|
+
//#endregion
|
|
2092
|
+
//#region src/tailwindcss/index.ts
|
|
984
2093
|
function getTailwindcssPackageInfo(options) {
|
|
985
|
-
|
|
2094
|
+
return getPackageInfoSync("tailwindcss", options);
|
|
986
2095
|
}
|
|
987
|
-
|
|
988
|
-
|
|
2096
|
+
//#endregion
|
|
2097
|
+
//#region src/cli/helpers/patch-cwd.ts
|
|
2098
|
+
/**
|
|
2099
|
+
* Resolve default working directory for `weapp-tw patch`.
|
|
2100
|
+
* Prefer explicit env overrides to avoid cross-package INIT_CWD pollution.
|
|
2101
|
+
*/
|
|
989
2102
|
function normalizeCandidatePath(baseDir, candidate) {
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
}
|
|
993
|
-
return path14.isAbsolute(candidate) ? path14.normalize(candidate) : path14.resolve(baseDir, candidate);
|
|
2103
|
+
if (!candidate) return;
|
|
2104
|
+
return path.isAbsolute(candidate) ? path.normalize(candidate) : path.resolve(baseDir, candidate);
|
|
994
2105
|
}
|
|
995
2106
|
function detectTailwindWorkspace(paths) {
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
initCwd,
|
|
1020
|
-
localPrefix
|
|
1021
|
-
].filter(Boolean);
|
|
1022
|
-
const detected = detectTailwindWorkspace([...new Set(candidates)]);
|
|
1023
|
-
if (detected) {
|
|
1024
|
-
return detected;
|
|
1025
|
-
}
|
|
1026
|
-
return initCwd ?? localPrefix ?? workspaceRoot ?? baseDir;
|
|
1027
|
-
}
|
|
1028
|
-
|
|
1029
|
-
// src/cli/helpers.ts
|
|
2107
|
+
for (const candidate of paths) try {
|
|
2108
|
+
if (getTailwindcssPackageInfo({ paths: [candidate] })?.rootPath) return candidate;
|
|
2109
|
+
} catch {}
|
|
2110
|
+
}
|
|
2111
|
+
function resolvePatchDefaultCwd(currentCwd = process.cwd()) {
|
|
2112
|
+
const baseDir = path.normalize(currentCwd);
|
|
2113
|
+
const explicitCwd = normalizeCandidatePath(baseDir, process.env.WEAPP_TW_PATCH_CWD);
|
|
2114
|
+
if (explicitCwd) return explicitCwd;
|
|
2115
|
+
const workspaceRoot = findWorkspaceRoot(baseDir);
|
|
2116
|
+
const initCwd = normalizeCandidatePath(baseDir, process.env.INIT_CWD);
|
|
2117
|
+
const localPrefix = normalizeCandidatePath(baseDir, process.env.npm_config_local_prefix);
|
|
2118
|
+
const candidates = [
|
|
2119
|
+
baseDir,
|
|
2120
|
+
workspaceRoot,
|
|
2121
|
+
initCwd,
|
|
2122
|
+
localPrefix
|
|
2123
|
+
].filter(Boolean);
|
|
2124
|
+
const detected = detectTailwindWorkspace([...new Set(candidates)]);
|
|
2125
|
+
if (detected) return detected;
|
|
2126
|
+
return initCwd ?? localPrefix ?? workspaceRoot ?? baseDir;
|
|
2127
|
+
}
|
|
2128
|
+
//#endregion
|
|
2129
|
+
//#region src/cli/helpers.ts
|
|
1030
2130
|
async function ensureDir(dir) {
|
|
1031
|
-
|
|
2131
|
+
await mkdir(dir, { recursive: true });
|
|
1032
2132
|
}
|
|
1033
|
-
function handleCliError(error) {
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
}
|
|
1039
|
-
} else {
|
|
1040
|
-
logger12.error(String(error));
|
|
1041
|
-
}
|
|
2133
|
+
function handleCliError$1(error) {
|
|
2134
|
+
if (error instanceof Error) {
|
|
2135
|
+
logger$1.error(error.message);
|
|
2136
|
+
if (error.stack && process.env.WEAPP_TW_DEBUG === "1") logger$1.error(error.stack);
|
|
2137
|
+
} else logger$1.error(String(error));
|
|
1042
2138
|
}
|
|
1043
2139
|
function commandAction(handler) {
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
}
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
import process17 from "process";
|
|
1056
|
-
|
|
1057
|
-
// src/cli/mount-options/patch-status.ts
|
|
2140
|
+
return async (...args) => {
|
|
2141
|
+
try {
|
|
2142
|
+
await handler(...args);
|
|
2143
|
+
} catch (error) {
|
|
2144
|
+
handleCliError$1(error);
|
|
2145
|
+
process.exitCode = 1;
|
|
2146
|
+
}
|
|
2147
|
+
};
|
|
2148
|
+
}
|
|
2149
|
+
//#endregion
|
|
2150
|
+
//#region src/cli/mount-options/patch-status.ts
|
|
1058
2151
|
function formatStatusFilesHint(files) {
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
}
|
|
1062
|
-
return ` (${files.join(", ")})`;
|
|
2152
|
+
if (!files?.length) return "";
|
|
2153
|
+
return ` (${files.join(", ")})`;
|
|
1063
2154
|
}
|
|
1064
2155
|
function logPatchStatusReport(report) {
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
var DEFAULT_EXTEND_LENGTH_UNITS_FEATURE = {
|
|
1098
|
-
enabled: true,
|
|
1099
|
-
units: ["rpx"],
|
|
1100
|
-
overwrite: true
|
|
2156
|
+
const applied = report.entries.filter((entry) => entry.status === "applied");
|
|
2157
|
+
const pending = report.entries.filter((entry) => entry.status === "not-applied");
|
|
2158
|
+
const skipped = report.entries.filter((entry) => entry.status === "skipped" || entry.status === "unsupported");
|
|
2159
|
+
const packageLabel = `${report.package.name ?? "tailwindcss"}@${report.package.version ?? "unknown"}`;
|
|
2160
|
+
logger$1.info(`Patch status for ${packageLabel} (v${report.majorVersion})`);
|
|
2161
|
+
if (applied.length) {
|
|
2162
|
+
logger$1.success("Applied:");
|
|
2163
|
+
applied.forEach((entry) => {
|
|
2164
|
+
logger$1.success(` - ${entry.name}${formatStatusFilesHint(entry.files)}`);
|
|
2165
|
+
});
|
|
2166
|
+
}
|
|
2167
|
+
if (pending.length) {
|
|
2168
|
+
logger$1.warn("Needs attention:");
|
|
2169
|
+
pending.forEach((entry) => {
|
|
2170
|
+
const details = entry.reason ? ` - ${entry.reason}` : "";
|
|
2171
|
+
logger$1.warn(` - ${entry.name}${formatStatusFilesHint(entry.files)}${details}`);
|
|
2172
|
+
});
|
|
2173
|
+
} else logger$1.success("All applicable patches are applied.");
|
|
2174
|
+
if (skipped.length) {
|
|
2175
|
+
logger$1.info("Skipped:");
|
|
2176
|
+
skipped.forEach((entry) => {
|
|
2177
|
+
const details = entry.reason ? ` - ${entry.reason}` : "";
|
|
2178
|
+
logger$1.info(` - ${entry.name}${details}`);
|
|
2179
|
+
});
|
|
2180
|
+
}
|
|
2181
|
+
}
|
|
2182
|
+
//#endregion
|
|
2183
|
+
//#region src/cli/patch-options.ts
|
|
2184
|
+
const DEFAULT_EXTEND_LENGTH_UNITS_FEATURE = {
|
|
2185
|
+
enabled: true,
|
|
2186
|
+
units: ["rpx"],
|
|
2187
|
+
overwrite: true
|
|
1101
2188
|
};
|
|
1102
2189
|
function withDefaultExtendLengthUnits(options) {
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
};
|
|
1113
|
-
}
|
|
1114
|
-
return normalized;
|
|
2190
|
+
const normalized = options ?? {};
|
|
2191
|
+
if (normalized.apply?.extendLengthUnits == null) return {
|
|
2192
|
+
...normalized,
|
|
2193
|
+
apply: {
|
|
2194
|
+
...normalized.apply ?? {},
|
|
2195
|
+
extendLengthUnits: DEFAULT_EXTEND_LENGTH_UNITS_FEATURE
|
|
2196
|
+
}
|
|
2197
|
+
};
|
|
2198
|
+
return normalized;
|
|
1115
2199
|
}
|
|
1116
2200
|
function buildExtendLengthUnitsOverride(options) {
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
};
|
|
1125
|
-
}
|
|
1126
|
-
return void 0;
|
|
1127
|
-
}
|
|
1128
|
-
|
|
1129
|
-
// src/cli/workspace.ts
|
|
1130
|
-
import path19 from "path";
|
|
1131
|
-
import process16 from "process";
|
|
1132
|
-
|
|
1133
|
-
// src/cli/workspace/package-dirs.ts
|
|
1134
|
-
import { existsSync as existsSync8 } from "fs";
|
|
1135
|
-
import path17 from "path";
|
|
1136
|
-
import fg from "fast-glob";
|
|
1137
|
-
|
|
1138
|
-
// src/cli/workspace/workspace-globs.ts
|
|
1139
|
-
import { existsSync as existsSync6, readFileSync as readFileSync5 } from "fs";
|
|
1140
|
-
import path15 from "path";
|
|
1141
|
-
import { parse as parseYaml } from "yaml";
|
|
1142
|
-
|
|
1143
|
-
// src/cli/workspace/workspace-io.ts
|
|
1144
|
-
import { readFileSync as readFileSync4 } from "fs";
|
|
2201
|
+
if (options?.apply?.extendLengthUnits == null) return { apply: {
|
|
2202
|
+
...options?.apply ?? {},
|
|
2203
|
+
extendLengthUnits: DEFAULT_EXTEND_LENGTH_UNITS_FEATURE
|
|
2204
|
+
} };
|
|
2205
|
+
}
|
|
2206
|
+
//#endregion
|
|
2207
|
+
//#region src/cli/workspace/workspace-io.ts
|
|
1145
2208
|
function tryReadJson(file) {
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
}
|
|
1153
|
-
|
|
1154
|
-
|
|
2209
|
+
try {
|
|
2210
|
+
const content = readFileSync(file, "utf8");
|
|
2211
|
+
return JSON.parse(content);
|
|
2212
|
+
} catch {
|
|
2213
|
+
return;
|
|
2214
|
+
}
|
|
2215
|
+
}
|
|
2216
|
+
//#endregion
|
|
2217
|
+
//#region src/cli/workspace/workspace-globs.ts
|
|
1155
2218
|
function parseWorkspaceGlobsFromPackageJson(workspaceRoot) {
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
if (Array.isArray(pkg.workspaces)) {
|
|
1162
|
-
return pkg.workspaces.filter(Boolean);
|
|
1163
|
-
}
|
|
1164
|
-
if (Array.isArray(pkg.workspaces.packages)) {
|
|
1165
|
-
return pkg.workspaces.packages.filter(Boolean);
|
|
1166
|
-
}
|
|
1167
|
-
return [];
|
|
2219
|
+
const pkg = tryReadJson(path.join(workspaceRoot, "package.json"));
|
|
2220
|
+
if (!pkg?.workspaces) return [];
|
|
2221
|
+
if (Array.isArray(pkg.workspaces)) return pkg.workspaces.filter(Boolean);
|
|
2222
|
+
if (Array.isArray(pkg.workspaces.packages)) return pkg.workspaces.packages.filter(Boolean);
|
|
2223
|
+
return [];
|
|
1168
2224
|
}
|
|
1169
2225
|
function parseWorkspaceGlobsFromWorkspaceFile(workspaceRoot) {
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
// src/cli/workspace/workspace-lock.ts
|
|
1183
|
-
import { existsSync as existsSync7, readFileSync as readFileSync6 } from "fs";
|
|
1184
|
-
import path16 from "path";
|
|
1185
|
-
import { parse as parseYaml2 } from "yaml";
|
|
2226
|
+
const workspaceFile = path.join(workspaceRoot, "pnpm-workspace.yaml");
|
|
2227
|
+
if (!existsSync(workspaceFile)) return [];
|
|
2228
|
+
try {
|
|
2229
|
+
const parsed = parse(readFileSync(workspaceFile, "utf8"));
|
|
2230
|
+
return Array.isArray(parsed?.packages) ? parsed.packages.filter(Boolean) : [];
|
|
2231
|
+
} catch {
|
|
2232
|
+
return [];
|
|
2233
|
+
}
|
|
2234
|
+
}
|
|
2235
|
+
//#endregion
|
|
2236
|
+
//#region src/cli/workspace/workspace-lock.ts
|
|
1186
2237
|
function parseImportersFromLock(workspaceRoot) {
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
return [];
|
|
1205
|
-
}
|
|
1206
|
-
}
|
|
1207
|
-
|
|
1208
|
-
// src/cli/workspace/package-dirs.ts
|
|
1209
|
-
var BACKSLASH_RE = /\\/g;
|
|
1210
|
-
var TRAILING_SLASH_RE = /\/+$/;
|
|
2238
|
+
const lockPath = path.join(workspaceRoot, "pnpm-lock.yaml");
|
|
2239
|
+
if (!existsSync(lockPath)) return [];
|
|
2240
|
+
try {
|
|
2241
|
+
const importers = parse(readFileSync(lockPath, "utf8"))?.importers;
|
|
2242
|
+
if (!importers) return [];
|
|
2243
|
+
return Object.keys(importers).map((key) => {
|
|
2244
|
+
if (!key || key === ".") return workspaceRoot;
|
|
2245
|
+
return path.join(workspaceRoot, key);
|
|
2246
|
+
});
|
|
2247
|
+
} catch {
|
|
2248
|
+
return [];
|
|
2249
|
+
}
|
|
2250
|
+
}
|
|
2251
|
+
//#endregion
|
|
2252
|
+
//#region src/cli/workspace/package-dirs.ts
|
|
2253
|
+
const BACKSLASH_RE$1 = /\\/g;
|
|
2254
|
+
const TRAILING_SLASH_RE = /\/+$/;
|
|
1211
2255
|
async function resolveWorkspacePackageDirs(workspaceRoot) {
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
}
|
|
1237
|
-
}
|
|
1238
|
-
const rootPkg = path17.join(workspaceRoot, "package.json");
|
|
1239
|
-
if (existsSync8(rootPkg)) {
|
|
1240
|
-
dirs.add(path17.normalize(workspaceRoot));
|
|
1241
|
-
}
|
|
1242
|
-
return [...dirs];
|
|
1243
|
-
}
|
|
1244
|
-
|
|
1245
|
-
// src/cli/workspace/patch-package.ts
|
|
1246
|
-
import { normalizeOptions, TailwindcssPatcher as TailwindcssPatcher2 } from "tailwindcss-patch";
|
|
1247
|
-
|
|
1248
|
-
// src/cli/workspace/patch-utils.ts
|
|
1249
|
-
import path18 from "path";
|
|
2256
|
+
const dirs = /* @__PURE__ */ new Set();
|
|
2257
|
+
for (const importerDir of parseImportersFromLock(workspaceRoot)) dirs.add(path.normalize(importerDir));
|
|
2258
|
+
if (!dirs.size) {
|
|
2259
|
+
let globs = parseWorkspaceGlobsFromWorkspaceFile(workspaceRoot);
|
|
2260
|
+
if (!globs.length) globs = parseWorkspaceGlobsFromPackageJson(workspaceRoot);
|
|
2261
|
+
if (globs.length > 0) {
|
|
2262
|
+
const packageJsonFiles = await fg(globs.map((pattern) => {
|
|
2263
|
+
const normalized = pattern.replace(BACKSLASH_RE$1, "/").replace(TRAILING_SLASH_RE, "");
|
|
2264
|
+
return normalized.endsWith("package.json") ? normalized : `${normalized}/package.json`;
|
|
2265
|
+
}), {
|
|
2266
|
+
cwd: workspaceRoot,
|
|
2267
|
+
absolute: true,
|
|
2268
|
+
onlyFiles: true,
|
|
2269
|
+
unique: true,
|
|
2270
|
+
ignore: ["**/node_modules/**", "**/.git/**"]
|
|
2271
|
+
});
|
|
2272
|
+
for (const file of packageJsonFiles) dirs.add(path.normalize(path.dirname(file)));
|
|
2273
|
+
}
|
|
2274
|
+
}
|
|
2275
|
+
if (existsSync(path.join(workspaceRoot, "package.json"))) dirs.add(path.normalize(workspaceRoot));
|
|
2276
|
+
return [...dirs];
|
|
2277
|
+
}
|
|
2278
|
+
//#endregion
|
|
2279
|
+
//#region src/cli/workspace/patch-utils.ts
|
|
1250
2280
|
function formatDisplayName(workspaceRoot, dir, name) {
|
|
1251
|
-
|
|
1252
|
-
|
|
2281
|
+
const relative = path.relative(workspaceRoot, dir) || ".";
|
|
2282
|
+
return name ? `${name} (${relative})` : relative;
|
|
1253
2283
|
}
|
|
1254
2284
|
function summarizeWorkspaceResults(results) {
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
2285
|
+
const patched = results.filter((result) => result.status === "patched").length;
|
|
2286
|
+
const skipped = results.filter((result) => result.status === "skipped").length;
|
|
2287
|
+
const failed = results.filter((result) => result.status === "failed").length;
|
|
2288
|
+
logger$1.info("[workspace] 汇总:已补丁 %d,跳过 %d,失败 %d", patched, skipped, failed);
|
|
1259
2289
|
}
|
|
1260
|
-
|
|
1261
|
-
|
|
2290
|
+
//#endregion
|
|
2291
|
+
//#region src/cli/workspace/patch-package.ts
|
|
1262
2292
|
function createWorkspacePatcher(cwd) {
|
|
1263
|
-
|
|
1264
|
-
withDefaultExtendLengthUnits({
|
|
1265
|
-
projectRoot: cwd
|
|
1266
|
-
})
|
|
1267
|
-
);
|
|
1268
|
-
return new TailwindcssPatcher2(normalized);
|
|
2293
|
+
return new TailwindcssPatcher(normalizeOptions(withDefaultExtendLengthUnits({ projectRoot: cwd })));
|
|
1269
2294
|
}
|
|
1270
2295
|
async function patchWorkspacePackage(workspaceRoot, dir, pkgName, options) {
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
dir,
|
|
1315
|
-
name: pkgName,
|
|
1316
|
-
status: "failed",
|
|
1317
|
-
message
|
|
1318
|
-
};
|
|
1319
|
-
}
|
|
1320
|
-
}
|
|
1321
|
-
|
|
1322
|
-
// src/cli/workspace.ts
|
|
2296
|
+
const displayName = formatDisplayName(workspaceRoot, dir, pkgName);
|
|
2297
|
+
if (!getTailwindcssPackageInfo({ paths: [dir] })?.rootPath) {
|
|
2298
|
+
logger$1.info("[workspace] 跳过 %s(tailwindcss 未安装)。", displayName);
|
|
2299
|
+
return {
|
|
2300
|
+
dir,
|
|
2301
|
+
name: pkgName,
|
|
2302
|
+
status: "skipped",
|
|
2303
|
+
message: "tailwindcss 未安装,已跳过。"
|
|
2304
|
+
};
|
|
2305
|
+
}
|
|
2306
|
+
try {
|
|
2307
|
+
const patcher = createWorkspacePatcher(dir);
|
|
2308
|
+
if (options.clearCache) await clearTailwindcssPatcherCache(patcher, { removeDirectory: true });
|
|
2309
|
+
const recorder = createPatchTargetRecorder(dir, patcher, {
|
|
2310
|
+
source: "cli",
|
|
2311
|
+
cwd: dir,
|
|
2312
|
+
recordTarget: options.recordTarget !== false,
|
|
2313
|
+
alwaysRecord: true
|
|
2314
|
+
});
|
|
2315
|
+
if (recorder?.message) logger$1.info("[workspace] %s %s", displayName, recorder.message);
|
|
2316
|
+
logTailwindcssTarget("cli", patcher, dir);
|
|
2317
|
+
await patcher.patch();
|
|
2318
|
+
if (recorder?.onPatched) await recorder.onPatched();
|
|
2319
|
+
logger$1.success("[workspace] 已补丁 %s", displayName);
|
|
2320
|
+
return {
|
|
2321
|
+
dir,
|
|
2322
|
+
name: pkgName,
|
|
2323
|
+
status: "patched",
|
|
2324
|
+
message: "已完成 patch。"
|
|
2325
|
+
};
|
|
2326
|
+
} catch (error) {
|
|
2327
|
+
const message = `${error instanceof Error ? error.message : String(error)},${`请在 ${dir} 运行 "weapp-tw patch --cwd ${dir}".`}`;
|
|
2328
|
+
logger$1.error("[workspace] 补丁失败 %s:%s", displayName, message);
|
|
2329
|
+
return {
|
|
2330
|
+
dir,
|
|
2331
|
+
name: pkgName,
|
|
2332
|
+
status: "failed",
|
|
2333
|
+
message
|
|
2334
|
+
};
|
|
2335
|
+
}
|
|
2336
|
+
}
|
|
2337
|
+
//#endregion
|
|
2338
|
+
//#region src/cli/workspace.ts
|
|
1323
2339
|
async function patchWorkspace(options) {
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
logger12.error(error.stack);
|
|
1346
|
-
}
|
|
1347
|
-
} else {
|
|
1348
|
-
logger12.error(String(error));
|
|
1349
|
-
}
|
|
2340
|
+
const cwd = options.cwd ?? process.cwd();
|
|
2341
|
+
const workspaceRoot = findWorkspaceRoot(cwd) ?? cwd;
|
|
2342
|
+
const packageDirs = await resolveWorkspacePackageDirs(workspaceRoot);
|
|
2343
|
+
if (packageDirs.length === 0) {
|
|
2344
|
+
logger$1.warn("未在 %s 检测到 workspace 包,已跳过批量 patch。", workspaceRoot);
|
|
2345
|
+
return;
|
|
2346
|
+
}
|
|
2347
|
+
const results = [];
|
|
2348
|
+
for (const dir of packageDirs) {
|
|
2349
|
+
const pkgJson = tryReadJson(path.join(dir, "package.json"));
|
|
2350
|
+
results.push(await patchWorkspacePackage(workspaceRoot, dir, pkgJson?.name, options));
|
|
2351
|
+
}
|
|
2352
|
+
summarizeWorkspaceResults(results);
|
|
2353
|
+
}
|
|
2354
|
+
//#endregion
|
|
2355
|
+
//#region src/cli/mount-options.ts
|
|
2356
|
+
function handleCliError(error) {
|
|
2357
|
+
if (error instanceof Error) {
|
|
2358
|
+
logger$1.error(error.message);
|
|
2359
|
+
if (error.stack && process.env.WEAPP_TW_DEBUG === "1") logger$1.error(error.stack);
|
|
2360
|
+
} else logger$1.error(String(error));
|
|
1350
2361
|
}
|
|
1351
2362
|
function withCommandErrorHandling(handler) {
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
2363
|
+
return (async (ctx, next) => {
|
|
2364
|
+
try {
|
|
2365
|
+
return await handler(ctx, next);
|
|
2366
|
+
} catch (error) {
|
|
2367
|
+
handleCliError(error);
|
|
2368
|
+
process.exitCode = 1;
|
|
2369
|
+
return;
|
|
2370
|
+
}
|
|
2371
|
+
});
|
|
1361
2372
|
}
|
|
1362
2373
|
async function createPatcherWithDefaultExtendLengthUnits(ctx) {
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
extract: withCommandErrorHandling(async (_ctx, next) => next()),
|
|
1449
|
-
tokens: withCommandErrorHandling(async (_ctx, next) => next()),
|
|
1450
|
-
init: withCommandErrorHandling(async (_ctx, next) => next()),
|
|
1451
|
-
status: withCommandErrorHandling(async (ctx) => {
|
|
1452
|
-
const patcher = await createPatcherWithDefaultExtendLengthUnits(ctx);
|
|
1453
|
-
const report = await patcher.getPatchStatus();
|
|
1454
|
-
if (ctx.args.json) {
|
|
1455
|
-
logger12.log(JSON.stringify(report, null, 2));
|
|
1456
|
-
return report;
|
|
1457
|
-
}
|
|
1458
|
-
logPatchStatusReport(report);
|
|
1459
|
-
return report;
|
|
1460
|
-
})
|
|
1461
|
-
}
|
|
2374
|
+
const extendLengthUnitsOverride = buildExtendLengthUnitsOverride(await ctx.loadPatchOptions());
|
|
2375
|
+
if (extendLengthUnitsOverride) return ctx.createPatcher(extendLengthUnitsOverride);
|
|
2376
|
+
return ctx.createPatcher();
|
|
2377
|
+
}
|
|
2378
|
+
const mountOptions = {
|
|
2379
|
+
commandOptions: {
|
|
2380
|
+
install: {
|
|
2381
|
+
name: "patch",
|
|
2382
|
+
aliases: ["install"],
|
|
2383
|
+
appendDefaultOptions: false,
|
|
2384
|
+
optionDefs: [
|
|
2385
|
+
{
|
|
2386
|
+
flags: "--cwd <dir>",
|
|
2387
|
+
description: "Working directory",
|
|
2388
|
+
config: { default: resolvePatchDefaultCwd() }
|
|
2389
|
+
},
|
|
2390
|
+
{
|
|
2391
|
+
flags: "--record-target",
|
|
2392
|
+
description: "Write tailwindcss target metadata (node_modules/.cache/weapp-tailwindcss/tailwindcss-target.json). Pass \"--record-target false\" to skip.",
|
|
2393
|
+
config: { default: true }
|
|
2394
|
+
},
|
|
2395
|
+
{
|
|
2396
|
+
flags: "--clear-cache",
|
|
2397
|
+
description: "Clear tailwindcss-patch cache before patch (opt-in)"
|
|
2398
|
+
},
|
|
2399
|
+
{
|
|
2400
|
+
flags: "--workspace",
|
|
2401
|
+
description: "Scan pnpm workspace packages and patch each Tailwind CSS dependency"
|
|
2402
|
+
}
|
|
2403
|
+
]
|
|
2404
|
+
},
|
|
2405
|
+
status: {
|
|
2406
|
+
appendDefaultOptions: false,
|
|
2407
|
+
optionDefs: [{
|
|
2408
|
+
flags: "--cwd <dir>",
|
|
2409
|
+
description: "Working directory",
|
|
2410
|
+
config: { default: resolvePatchDefaultCwd() }
|
|
2411
|
+
}, {
|
|
2412
|
+
flags: "--json",
|
|
2413
|
+
description: "Print a JSON report of patch status"
|
|
2414
|
+
}]
|
|
2415
|
+
}
|
|
2416
|
+
},
|
|
2417
|
+
commandHandlers: {
|
|
2418
|
+
install: withCommandErrorHandling(async (ctx) => {
|
|
2419
|
+
const shouldClearCache = toBoolean(ctx.args.clearCache, false);
|
|
2420
|
+
const shouldRecordTarget = toBoolean(ctx.args.recordTarget, true);
|
|
2421
|
+
if (toBoolean(ctx.args.workspace, false)) {
|
|
2422
|
+
await patchWorkspace({
|
|
2423
|
+
cwd: ctx.cwd,
|
|
2424
|
+
clearCache: shouldClearCache,
|
|
2425
|
+
recordTarget: shouldRecordTarget
|
|
2426
|
+
});
|
|
2427
|
+
return;
|
|
2428
|
+
}
|
|
2429
|
+
const patcher = await createPatcherWithDefaultExtendLengthUnits(ctx);
|
|
2430
|
+
if (shouldClearCache) await clearTailwindcssPatcherCache(patcher, { removeDirectory: true });
|
|
2431
|
+
const recorder = createPatchTargetRecorder(ctx.cwd, patcher, {
|
|
2432
|
+
source: "cli",
|
|
2433
|
+
cwd: ctx.cwd,
|
|
2434
|
+
recordTarget: shouldRecordTarget,
|
|
2435
|
+
alwaysRecord: true
|
|
2436
|
+
});
|
|
2437
|
+
if (recorder?.message) logger$1.info(recorder.message);
|
|
2438
|
+
logTailwindcssTarget("cli", patcher, ctx.cwd);
|
|
2439
|
+
await patcher.patch();
|
|
2440
|
+
if (recorder?.onPatched) {
|
|
2441
|
+
const recordPath = await recorder.onPatched();
|
|
2442
|
+
if (recordPath) logger$1.info(`记录 weapp-tw patch 目标 -> ${formatOutputPath(recordPath, ctx.cwd)}`);
|
|
2443
|
+
}
|
|
2444
|
+
logger$1.success("Tailwind CSS 运行时补丁已完成。");
|
|
2445
|
+
}),
|
|
2446
|
+
extract: withCommandErrorHandling(async (_ctx, next) => next()),
|
|
2447
|
+
tokens: withCommandErrorHandling(async (_ctx, next) => next()),
|
|
2448
|
+
init: withCommandErrorHandling(async (_ctx, next) => next()),
|
|
2449
|
+
status: withCommandErrorHandling(async (ctx) => {
|
|
2450
|
+
const report = await (await createPatcherWithDefaultExtendLengthUnits(ctx)).getPatchStatus();
|
|
2451
|
+
if (ctx.args.json) {
|
|
2452
|
+
logger$1.log(JSON.stringify(report, null, 2));
|
|
2453
|
+
return report;
|
|
2454
|
+
}
|
|
2455
|
+
logPatchStatusReport(report);
|
|
2456
|
+
return report;
|
|
2457
|
+
})
|
|
2458
|
+
}
|
|
1462
2459
|
};
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
"./src/**/*.{wxml,axml,swan,qml,ttml,ux,uts}",
|
|
1473
|
-
"./src/**/*.{js,jsx,ts,tsx}",
|
|
1474
|
-
"./src/**/*.{vue,svelte,html,md,mdx}"
|
|
2460
|
+
//#endregion
|
|
2461
|
+
//#region src/cli/vscode-entry.ts
|
|
2462
|
+
const DEFAULT_VSCODE_ENTRY_OUTPUT = ".vscode/weapp-tailwindcss.intellisense.css";
|
|
2463
|
+
const DEFAULT_VSCODE_SOURCES = [
|
|
2464
|
+
"not \"./dist\"",
|
|
2465
|
+
"not \"./unpackage\"",
|
|
2466
|
+
"./src/**/*.{wxml,axml,swan,qml,ttml,ux,uts}",
|
|
2467
|
+
"./src/**/*.{js,jsx,ts,tsx,mjs,cjs,wxs,sjs}",
|
|
2468
|
+
"./src/**/*.{vue,svelte,mpx,html,md,mdx}"
|
|
1475
2469
|
];
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
2470
|
+
const SINGLE_QUOTE = "'";
|
|
2471
|
+
const DOUBLE_QUOTE = "\"";
|
|
2472
|
+
const BACKSLASH_RE = /\\/g;
|
|
1479
2473
|
function toPosixPath(filepath) {
|
|
1480
|
-
|
|
2474
|
+
return filepath.replace(BACKSLASH_RE, "/");
|
|
1481
2475
|
}
|
|
1482
2476
|
async function assertFileExists(filepath) {
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
throw err;
|
|
1491
|
-
}
|
|
2477
|
+
try {
|
|
2478
|
+
await access(filepath, constants.F_OK);
|
|
2479
|
+
} catch (error) {
|
|
2480
|
+
const err = error;
|
|
2481
|
+
if (err?.code === "ENOENT") throw new Error(`CSS entry file not found: ${filepath}`);
|
|
2482
|
+
throw err;
|
|
2483
|
+
}
|
|
1492
2484
|
}
|
|
1493
2485
|
async function assertCanWrite(filepath, force) {
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
const err = error;
|
|
1503
|
-
if (err?.code === "ENOENT") {
|
|
1504
|
-
return;
|
|
1505
|
-
}
|
|
1506
|
-
throw err;
|
|
1507
|
-
}
|
|
2486
|
+
try {
|
|
2487
|
+
await access(filepath, constants.F_OK);
|
|
2488
|
+
if (!force) throw new Error(`VS Code helper already exists at ${filepath}. Re-run with --force to overwrite it.`);
|
|
2489
|
+
} catch (error) {
|
|
2490
|
+
const err = error;
|
|
2491
|
+
if (err?.code === "ENOENT") return;
|
|
2492
|
+
throw err;
|
|
2493
|
+
}
|
|
1508
2494
|
}
|
|
1509
2495
|
function toCssLiteral(value) {
|
|
1510
|
-
|
|
1511
|
-
|
|
2496
|
+
const normalized = toPosixPath(value);
|
|
2497
|
+
return JSON.stringify(normalized);
|
|
1512
2498
|
}
|
|
1513
2499
|
function formatSource(pattern) {
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
}
|
|
1530
|
-
if (!body) {
|
|
1531
|
-
throw new Error("Invalid @source pattern: empty body.");
|
|
1532
|
-
}
|
|
1533
|
-
if (!body.startsWith(SINGLE_QUOTE) && !body.startsWith(DOUBLE_QUOTE)) {
|
|
1534
|
-
body = toCssLiteral(body);
|
|
1535
|
-
}
|
|
1536
|
-
return `@source ${keyword}${body};`;
|
|
2500
|
+
const trimmed = pattern.trim();
|
|
2501
|
+
if (!trimmed) return null;
|
|
2502
|
+
if (trimmed.startsWith("@source ")) return trimmed.endsWith(";") ? trimmed : `${trimmed};`;
|
|
2503
|
+
let body = trimmed;
|
|
2504
|
+
let keyword = "";
|
|
2505
|
+
if (body.startsWith("not ")) {
|
|
2506
|
+
keyword = "not ";
|
|
2507
|
+
body = body.slice(4).trim();
|
|
2508
|
+
} else if (body.startsWith("!")) {
|
|
2509
|
+
keyword = "not ";
|
|
2510
|
+
body = body.slice(1).trim();
|
|
2511
|
+
}
|
|
2512
|
+
if (!body) throw new Error("Invalid @source pattern: empty body.");
|
|
2513
|
+
if (!body.startsWith(SINGLE_QUOTE) && !body.startsWith(DOUBLE_QUOTE)) body = toCssLiteral(body);
|
|
2514
|
+
return `@source ${keyword}${body};`;
|
|
1537
2515
|
}
|
|
1538
2516
|
function resolveOutputPath(baseDir, output) {
|
|
1539
|
-
|
|
1540
|
-
|
|
2517
|
+
const target = output ?? ".vscode/weapp-tailwindcss.intellisense.css";
|
|
2518
|
+
return path.isAbsolute(target) ? path.normalize(target) : path.resolve(baseDir, target);
|
|
1541
2519
|
}
|
|
1542
2520
|
function resolveCssEntry(baseDir, entry) {
|
|
1543
|
-
|
|
2521
|
+
return path.isAbsolute(entry) ? path.normalize(entry) : path.resolve(baseDir, entry);
|
|
1544
2522
|
}
|
|
1545
2523
|
function toRelativeImport(fromFile, targetFile) {
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
if (!relative.startsWith(".")) {
|
|
1552
|
-
relative = `./${relative}`;
|
|
1553
|
-
}
|
|
1554
|
-
return toPosixPath(relative);
|
|
2524
|
+
const fromDir = path.dirname(fromFile);
|
|
2525
|
+
let relative = path.relative(fromDir, targetFile);
|
|
2526
|
+
if (!relative) relative = path.basename(targetFile);
|
|
2527
|
+
if (!relative.startsWith(".")) relative = `./${relative}`;
|
|
2528
|
+
return toPosixPath(relative);
|
|
1555
2529
|
}
|
|
1556
2530
|
async function generateVscodeIntellisenseEntry(options) {
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
}
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
if (semver.
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
}
|
|
1592
|
-
var cli = createTailwindcssPatchCli({
|
|
1593
|
-
name: "weapp-tailwindcss",
|
|
1594
|
-
mountOptions
|
|
2531
|
+
const baseDir = options.baseDir;
|
|
2532
|
+
const cssEntryPath = resolveCssEntry(baseDir, options.cssEntry);
|
|
2533
|
+
await assertFileExists(cssEntryPath);
|
|
2534
|
+
const outputPath = resolveOutputPath(baseDir, options.output);
|
|
2535
|
+
await ensureDir(path.dirname(outputPath));
|
|
2536
|
+
await assertCanWrite(outputPath, options.force);
|
|
2537
|
+
const formattedSources = (options.sources && options.sources.length > 0 ? options.sources : DEFAULT_VSCODE_SOURCES).map(formatSource).filter((statement) => Boolean(statement));
|
|
2538
|
+
const cssImport = toRelativeImport(outputPath, cssEntryPath);
|
|
2539
|
+
const separator = formattedSources.length > 0 ? [""] : [];
|
|
2540
|
+
await writeFile(outputPath, `${[
|
|
2541
|
+
"/*",
|
|
2542
|
+
" * Auto-generated by weapp-tailwindcss.",
|
|
2543
|
+
" * This file exists solely to activate Tailwind CSS IntelliSense in VS Code.",
|
|
2544
|
+
" * Do not import it in your actual mini-program bundles.",
|
|
2545
|
+
" */",
|
|
2546
|
+
"@import 'tailwindcss';",
|
|
2547
|
+
"",
|
|
2548
|
+
...formattedSources,
|
|
2549
|
+
...separator,
|
|
2550
|
+
`@import '${cssImport}';`,
|
|
2551
|
+
""
|
|
2552
|
+
].filter((line, idx, arr) => !(line === "" && arr[idx - 1] === "")).join("\n")}\n`, "utf8");
|
|
2553
|
+
return {
|
|
2554
|
+
outputPath,
|
|
2555
|
+
cssEntryPath
|
|
2556
|
+
};
|
|
2557
|
+
}
|
|
2558
|
+
//#endregion
|
|
2559
|
+
//#region src/cli.ts
|
|
2560
|
+
process.title = "node (weapp-tailwindcss)";
|
|
2561
|
+
if (!semver.satisfies(process.versions.node, "^20.19.0 || >=22.12.0")) logger$1.warn(`You are using Node.js ${process.versions.node}. For weapp-tailwindcss, Node.js version ${WEAPP_TW_REQUIRED_NODE_VERSION_RANGE} is required.`);
|
|
2562
|
+
const cli = createTailwindcssPatchCli({
|
|
2563
|
+
name: "weapp-tailwindcss",
|
|
2564
|
+
mountOptions
|
|
1595
2565
|
});
|
|
1596
|
-
cli.command("vscode-entry", "Generate a VS Code helper CSS for Tailwind IntelliSense").option("--cwd <dir>", "Working directory").option("--css <file>", "Path to the CSS file that imports weapp-tailwindcss (required)").option("--output <file>", `Helper output path. Defaults to ${DEFAULT_VSCODE_ENTRY_OUTPUT}`).option("--source <pattern>", "Additional @source glob (can be repeated)").option("--force", "Overwrite the helper file when it already exists").action(
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
);
|
|
1617
|
-
})
|
|
1618
|
-
);
|
|
2566
|
+
cli.command("vscode-entry", "Generate a VS Code helper CSS for Tailwind IntelliSense").option("--cwd <dir>", "Working directory").option("--css <file>", "Path to the CSS file that imports weapp-tailwindcss (required)").option("--output <file>", `Helper output path. Defaults to ${DEFAULT_VSCODE_ENTRY_OUTPUT}`).option("--source <pattern>", "Additional @source glob (can be repeated)").option("--force", "Overwrite the helper file when it already exists").action(commandAction(async (options) => {
|
|
2567
|
+
const resolvedCwd = resolveCliCwd(options.cwd);
|
|
2568
|
+
const baseDir = resolvedCwd ?? process.cwd();
|
|
2569
|
+
const cssEntry = readStringOption("css", options.css);
|
|
2570
|
+
if (!cssEntry) throw new Error("Option \"--css\" is required.");
|
|
2571
|
+
const result = await generateVscodeIntellisenseEntry({
|
|
2572
|
+
baseDir,
|
|
2573
|
+
cssEntry,
|
|
2574
|
+
output: readStringOption("output", options.output),
|
|
2575
|
+
sources: readStringArrayOption("source", options.source),
|
|
2576
|
+
force: toBoolean(options.force, false)
|
|
2577
|
+
});
|
|
2578
|
+
logger$1.success(`VS Code helper generated -> ${formatOutputPath(result.outputPath, resolvedCwd)}`);
|
|
2579
|
+
}));
|
|
2580
|
+
cli.command("doctor", "Check project setup for weapp-tailwindcss").option("--cwd <dir>", "Working directory").option("--json", "Print a JSON report").option("--strict", "Exit with code 1 when warnings are found").action(commandAction(async (options) => {
|
|
2581
|
+
const report = createDoctorReport({ cwd: resolveCliCwd(options.cwd) });
|
|
2582
|
+
if (toBoolean(options.json, false)) logger$1.log(JSON.stringify(report, null, 2));
|
|
2583
|
+
else logger$1.log(formatDoctorReport(report));
|
|
2584
|
+
if (hasDoctorFailure(report, toBoolean(options.strict, false))) process.exitCode = 1;
|
|
2585
|
+
}));
|
|
1619
2586
|
cli.help();
|
|
1620
|
-
cli.version(
|
|
2587
|
+
cli.version(process.env.npm_package_version ?? "0.0.0");
|
|
1621
2588
|
cli.parse();
|
|
2589
|
+
//#endregion
|
|
2590
|
+
export {};
|