@dimina/compiler 1.0.17 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,33 +1,16 @@
1
- //#region \0rolldown/runtime.js
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __copyProps = (to, from, except, desc) => {
9
- if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
10
- key = keys[i];
11
- if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
12
- get: ((k) => from[k]).bind(null, key),
13
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
14
- });
15
- }
16
- return to;
17
- };
18
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
19
- value: mod,
20
- enumerable: true
21
- }) : target, mod));
22
- //#endregion
1
+ const require_rolldown_runtime = require("./rolldown-runtime-D6vf50IK.cjs");
23
2
  let node_path = require("node:path");
24
- node_path = __toESM(node_path, 1);
3
+ node_path = require_rolldown_runtime.__toESM(node_path, 1);
25
4
  let node_process = require("node:process");
26
- node_process = __toESM(node_process, 1);
5
+ node_process = require_rolldown_runtime.__toESM(node_process, 1);
27
6
  let node_fs = require("node:fs");
28
- node_fs = __toESM(node_fs, 1);
7
+ node_fs = require_rolldown_runtime.__toESM(node_fs, 1);
29
8
  let node_os = require("node:os");
30
- node_os = __toESM(node_os, 1);
9
+ node_os = require_rolldown_runtime.__toESM(node_os, 1);
10
+ let oxc_parser = require("oxc-parser");
11
+ let oxc_walker = require("oxc-walker");
12
+ let node_crypto = require("node:crypto");
13
+ node_crypto = require_rolldown_runtime.__toESM(node_crypto, 1);
31
14
  //#region src/common/path-utils.js
32
15
  var WINDOWS_FS_PATH_RE = /^(?:[a-zA-Z]:[\\/]|\\\\)/;
33
16
  function isWindowsFsPath(targetPath) {
@@ -55,19 +38,6 @@ function getRelativePosixPath(targetPath, rootPath) {
55
38
  return normalizeToPosixPath(targetPath).replace(normalizeToPosixPath(rootPath), "").replace(/^\//, "");
56
39
  }
57
40
  //#endregion
58
- //#region src/common/art.js
59
- var artCode = `
60
- ██████╗ ██╗███╗ ███╗██╗███╗ ██╗ █████╗
61
- ██╔══██╗██║████╗ ████║██║████╗ ██║██╔══██╗
62
- ██║ ██║██║██╔████╔██║██║██╔██╗ ██║███████║
63
- ██║ ██║██║██║╚██╔╝██║██║██║╚██╗██║██╔══██║
64
- ██████╔╝██║██║ ╚═╝ ██║██║██║ ╚████║██║ ██║
65
- ╚═════╝ ╚═╝╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝╚═╝ ╚═╝
66
- `;
67
- function art_default() {
68
- console.log(artCode);
69
- }
70
- //#endregion
71
41
  //#region src/common/utils.js
72
42
  function hasCompileInfo(modulePath, list, preList) {
73
43
  const mergeList = Array.isArray(preList) ? [...preList, ...list] : list;
@@ -84,19 +54,31 @@ function getAbsolutePath(workPath, pagePath, src) {
84
54
  return node_path.default.resolve(workPath, relativePath, src);
85
55
  }
86
56
  var assetsMap = {};
57
+ function isPathInside(rootPath, targetPath) {
58
+ const relativePath = node_path.default.relative(rootPath, targetPath);
59
+ return relativePath === "" || !relativePath.startsWith(`..${node_path.default.sep}`) && relativePath !== ".." && !node_path.default.isAbsolute(relativePath);
60
+ }
61
+ function resolveAssetSourcePath(workPath, pagePath, src) {
62
+ const projectRoot = node_path.default.resolve(workPath);
63
+ if (src.startsWith("/")) return node_path.default.resolve(projectRoot, `.${src}`);
64
+ const normalizedPagePath = node_path.default.resolve(pagePath);
65
+ const pageDirectory = node_path.default.isAbsolute(pagePath) && isPathInside(projectRoot, normalizedPagePath) ? node_path.default.dirname(normalizedPagePath) : node_path.default.resolve(projectRoot, node_path.default.dirname(pagePath.replace(/^[/\\]+/, "")));
66
+ const resolvedPath = node_path.default.resolve(pageDirectory, src);
67
+ if (isPathInside(projectRoot, resolvedPath)) return resolvedPath;
68
+ return node_path.default.resolve(projectRoot, src.replace(/^(?:\.\.[/\\])+/, ""));
69
+ }
87
70
  /**
88
71
  * 将静态资源存储到 static 文件夹
89
72
  */
90
73
  function collectAssets(workPath, pagePath, src, targetPath, appId) {
91
74
  if (src.startsWith("http") || src.startsWith("//")) return src;
92
75
  if (!/\.(?:png|jpe?g|gif|svg)(?:\?.*)?$/.test(src)) return src;
93
- const relativePath = pagePath.split("/").slice(0, -1).join("/");
94
- const absolutePath = src.startsWith("/") ? workPath + src : node_path.default.resolve(workPath, relativePath, src);
76
+ const absolutePath = resolveAssetSourcePath(workPath, pagePath, src);
95
77
  if (assetsMap[absolutePath]) return assetsMap[absolutePath];
96
78
  try {
97
79
  const ext = `.${src.split(".").pop()}`;
98
80
  const dirPath = absolutePath.split(node_path.default.sep).slice(0, -1).join("/");
99
- const prefix = uuid();
81
+ const prefix = uuid(dirPath);
100
82
  const targetStatic = `${targetPath}/main/static`;
101
83
  if (!node_fs.default.existsSync(targetStatic)) node_fs.default.mkdirSync(targetStatic, { recursive: true });
102
84
  getFilesWithExtension(dirPath, ext).forEach((file) => {
@@ -122,15 +104,16 @@ function isString(o) {
122
104
  function transformRpx(styleText) {
123
105
  if (!isString(styleText)) return styleText;
124
106
  return styleText.replace(/([+-]?\d+(?:\.\d+)?)rpx/g, (_, pixel) => {
125
- return `${Number(pixel)}rem`;
107
+ const viewportWidth = Number((Number(pixel) / 7.5).toFixed(6));
108
+ return `${Object.is(viewportWidth, -0) ? 0 : viewportWidth}vw`;
126
109
  });
127
110
  }
128
- function uuid() {
129
- return Math.random().toString(36).slice(2, 7);
111
+ function uuid(str) {
112
+ return node_crypto.default.createHash("sha256").update(str).digest().readBigUInt64BE(0).toString(36);
130
113
  }
131
114
  var tagWhiteList = [
132
115
  "page",
133
- "wrapper",
116
+ "component-host",
134
117
  "block",
135
118
  "button",
136
119
  "camera",
@@ -171,6 +154,24 @@ var tagWhiteList = [
171
154
  "view",
172
155
  "web-view"
173
156
  ];
157
+ var miniProgramBuiltinTags = /* @__PURE__ */ new Set([
158
+ ...tagWhiteList,
159
+ "canvas",
160
+ "match-media",
161
+ "page-container",
162
+ "share-element",
163
+ "editor",
164
+ "audio",
165
+ "channel-live",
166
+ "channel-video",
167
+ "live-player",
168
+ "live-pusher",
169
+ "voip-room",
170
+ "ad",
171
+ "ad-custom",
172
+ "official-account",
173
+ "xr-frame"
174
+ ]);
174
175
  //#endregion
175
176
  //#region src/common/npm-resolver.js
176
177
  /**
@@ -353,6 +354,12 @@ var DEFAULT_STYLE_EXTS = [
353
354
  ];
354
355
  var DEFAULT_VIEW_SCRIPT_EXTS = [".wxs"];
355
356
  var DEFAULT_VIEW_SCRIPT_TAGS = ["wxs", "dds"];
357
+ var CUSTOM_TAB_BAR_COMPONENT_PATH = "/custom-tab-bar/index";
358
+ var STYLE_ISOLATION_VALUES = /* @__PURE__ */ new Set([
359
+ "isolated",
360
+ "apply-shared",
361
+ "shared"
362
+ ]);
356
363
  var RESERVED_EXTS = /* @__PURE__ */ new Set([
357
364
  ...DEFAULT_TEMPLATE_EXTS,
358
365
  ...DEFAULT_STYLE_EXTS,
@@ -509,6 +516,43 @@ function storePageConfig() {
509
516
  if (subPackages) subPackages.forEach((subPkg) => {
510
517
  collectionPageJson(subPkg.pages, subPkg.root);
511
518
  });
519
+ storeCustomTabBarConfig();
520
+ }
521
+ /**
522
+ * 微信会把 custom-tab-bar/index 作为每个 tab 页的直属组件创建。业务页面
523
+ * 不需要在 usingComponents 中显式声明它,因此编译阶段补一个内部组件引用,
524
+ * 让逻辑、视图和样式三个编译器都能沿现有依赖图收集该组件。
525
+ */
526
+ function storeCustomTabBarConfig() {
527
+ const tabBar = configInfo.appInfo?.tabBar;
528
+ if (tabBar?.custom !== true || !Array.isArray(tabBar.list)) return;
529
+ const componentJsonPath = node_path.default.join(pathInfo.workPath, "custom-tab-bar/index.json");
530
+ if (!node_fs.default.existsSync(componentJsonPath)) {
531
+ console.warn("[env] tabBar.custom 已启用,但找不到 custom-tab-bar/index.json");
532
+ return;
533
+ }
534
+ const dependencyName = `dimina-${uuid(CUSTOM_TAB_BAR_COMPONENT_PATH)}`;
535
+ storeComponentConfig({ usingComponents: { [dependencyName]: CUSTOM_TAB_BAR_COMPONENT_PATH } }, node_path.default.join(pathInfo.workPath, "app.json"));
536
+ const componentConfig = configInfo.componentInfo[CUSTOM_TAB_BAR_COMPONENT_PATH];
537
+ if (componentConfig) componentConfig.customTabBar = true;
538
+ for (const item of tabBar.list) {
539
+ const pagePath = typeof item?.pagePath === "string" ? item.pagePath.replace(/^\/+/, "") : "";
540
+ if (!pagePath || !configInfo.appInfo.pages?.includes(pagePath)) continue;
541
+ const pageConfig = configInfo.pageInfo[pagePath] ||= {};
542
+ pageConfig.usingComponents ||= {};
543
+ const declaredComponents = {
544
+ ...configInfo.appInfo.usingComponents || {},
545
+ ...pageConfig.usingComponents
546
+ };
547
+ let componentName = Object.entries(declaredComponents).find(([, componentPath]) => componentPath === CUSTOM_TAB_BAR_COMPONENT_PATH)?.[0] || dependencyName;
548
+ let suffix = 0;
549
+ while (declaredComponents[componentName] && declaredComponents[componentName] !== CUSTOM_TAB_BAR_COMPONENT_PATH) {
550
+ suffix++;
551
+ componentName = `${dependencyName}-${suffix}`;
552
+ }
553
+ pageConfig.usingComponents[componentName] = CUSTOM_TAB_BAR_COMPONENT_PATH;
554
+ pageConfig.customTabBar = { componentName };
555
+ }
512
556
  }
513
557
  /**
514
558
  * 匹配页面和对应的配置信息
@@ -562,19 +606,65 @@ function storeComponentConfig(pageJsonContent, pageFilePath) {
562
606
  }
563
607
  const cUsing = cContent.usingComponents || {};
564
608
  const isComponent = cContent.component || false;
609
+ const styleIsolation = resolveComponentStyleIsolation(cContent, componentFilePath);
565
610
  const cComponents = Object.keys(cUsing).reduce((acc, key) => {
566
611
  acc[key] = getModuleId(cUsing[key], componentFilePath);
567
612
  return acc;
568
613
  }, {});
569
614
  configInfo.componentInfo[moduleId] = {
570
- id: uuid(),
615
+ id: uuid(moduleId),
571
616
  path: moduleId,
572
617
  component: isComponent,
618
+ styleIsolation,
573
619
  usingComponents: cComponents
574
620
  };
575
621
  if (cContent.usingComponents && Object.keys(cContent.usingComponents).length > 0) storeComponentConfig(configInfo.componentInfo[moduleId], componentFilePath);
576
622
  }
577
623
  }
624
+ function getStaticProperty(objectExpression, propertyName) {
625
+ if (objectExpression?.type !== "ObjectExpression") return;
626
+ return objectExpression.properties?.find((property) => {
627
+ if (property.type !== "Property" || property.computed) return false;
628
+ return property.key?.name === propertyName || property.key?.value === propertyName;
629
+ })?.value;
630
+ }
631
+ function normalizeStyleIsolation(value) {
632
+ return STYLE_ISOLATION_VALUES.has(value) ? value : void 0;
633
+ }
634
+ /**
635
+ * styleIsolation can be declared either in component.json or in
636
+ * Component({ options }). The style compiler must know it before service
637
+ * runtime starts, so only statically-declared literal options participate.
638
+ * addGlobalClass is the legacy equivalent of apply-shared.
639
+ */
640
+ function resolveComponentStyleIsolation(componentConfig, componentJsonPath) {
641
+ const jsonValue = normalizeStyleIsolation(componentConfig?.styleIsolation);
642
+ if (jsonValue) return jsonValue;
643
+ const basePath = componentJsonPath.replace(/\.json$/i, "");
644
+ const scriptPath = [".js", ".ts"].map((ext) => `${basePath}${ext}`).find((candidate) => node_fs.default.existsSync(candidate));
645
+ if (!scriptPath) return "isolated";
646
+ try {
647
+ const { program } = (0, oxc_parser.parseSync)(scriptPath, getContentByPath(scriptPath), { sourceType: "unambiguous" });
648
+ let extractedValue;
649
+ (0, oxc_walker.walk)(program, { enter(expression) {
650
+ if (extractedValue) return;
651
+ if (expression?.type !== "CallExpression" || expression.callee?.type !== "Identifier" || expression.callee.name !== "Component") return;
652
+ const definition = expression.arguments?.[0];
653
+ const options = getStaticProperty(definition, "options");
654
+ const styleIsolation = getStaticProperty(options, "styleIsolation")?.value;
655
+ const normalized = normalizeStyleIsolation(styleIsolation);
656
+ if (normalized) {
657
+ extractedValue = normalized;
658
+ return;
659
+ }
660
+ if (getStaticProperty(options, "addGlobalClass")?.value === true) extractedValue = "apply-shared";
661
+ } });
662
+ if (extractedValue) return extractedValue;
663
+ } catch (error) {
664
+ console.warn(`[env] 无法解析组件样式隔离配置 ${scriptPath}: ${error.message}`);
665
+ }
666
+ return "isolated";
667
+ }
578
668
  /**
579
669
  * 转化为相对小程序根目录的绝对路径,作为模块唯一性 id
580
670
  * 支持 npm 组件解析
@@ -640,9 +730,12 @@ function getPages() {
640
730
  ...pageComponents
641
731
  };
642
732
  return {
643
- id: uuid(),
733
+ id: uuid(path),
644
734
  path,
645
- usingComponents: mergedComponents
735
+ appStyleScopeId: getAppStyleScopeId(),
736
+ sharedStyleScopeIds: collectSharedStyleScopeIds(mergedComponents),
737
+ usingComponents: mergedComponents,
738
+ customTabBar: pageInfo[path]?.customTabBar
646
739
  };
647
740
  });
648
741
  const subPages = {};
@@ -659,9 +752,12 @@ function getPages() {
659
752
  ...pageComponents
660
753
  };
661
754
  return {
662
- id: uuid(),
755
+ id: uuid(fullPath),
663
756
  path: fullPath,
664
- usingComponents: mergedComponents
757
+ appStyleScopeId: getAppStyleScopeId(),
758
+ sharedStyleScopeIds: collectSharedStyleScopeIds(mergedComponents),
759
+ usingComponents: mergedComponents,
760
+ customTabBar: pageInfo[fullPath]?.customTabBar
665
761
  };
666
762
  })
667
763
  };
@@ -671,19 +767,24 @@ function getPages() {
671
767
  subPages
672
768
  };
673
769
  }
770
+ function collectSharedStyleScopeIds(usingComponents) {
771
+ const result = [];
772
+ const visited = /* @__PURE__ */ new Set();
773
+ const visit = (componentPath) => {
774
+ if (visited.has(componentPath)) return;
775
+ visited.add(componentPath);
776
+ const component = configInfo.componentInfo[componentPath];
777
+ if (!component) return;
778
+ if (component.styleIsolation === "shared") result.push(component.id);
779
+ for (const childPath of Object.values(component.usingComponents || {})) visit(childPath);
780
+ };
781
+ for (const componentPath of Object.values(usingComponents || {})) visit(componentPath);
782
+ return result;
783
+ }
784
+ function getAppStyleScopeId() {
785
+ return uuid("app");
786
+ }
674
787
  //#endregion
675
- Object.defineProperty(exports, "__toESM", {
676
- enumerable: true,
677
- get: function() {
678
- return __toESM;
679
- }
680
- });
681
- Object.defineProperty(exports, "art_default", {
682
- enumerable: true,
683
- get: function() {
684
- return art_default;
685
- }
686
- });
687
788
  Object.defineProperty(exports, "collectAssets", {
688
789
  enumerable: true,
689
790
  get: function() {
@@ -714,6 +815,12 @@ Object.defineProperty(exports, "getAppName", {
714
815
  return getAppName;
715
816
  }
716
817
  });
818
+ Object.defineProperty(exports, "getAppStyleScopeId", {
819
+ enumerable: true,
820
+ get: function() {
821
+ return getAppStyleScopeId;
822
+ }
823
+ });
717
824
  Object.defineProperty(exports, "getComponent", {
718
825
  enumerable: true,
719
826
  get: function() {
@@ -786,6 +893,12 @@ Object.defineProperty(exports, "hasCompileInfo", {
786
893
  return hasCompileInfo;
787
894
  }
788
895
  });
896
+ Object.defineProperty(exports, "miniProgramBuiltinTags", {
897
+ enumerable: true,
898
+ get: function() {
899
+ return miniProgramBuiltinTags;
900
+ }
901
+ });
789
902
  Object.defineProperty(exports, "resetStoreInfo", {
790
903
  enumerable: true,
791
904
  get: function() {
@@ -810,6 +923,12 @@ Object.defineProperty(exports, "tagWhiteList", {
810
923
  return tagWhiteList;
811
924
  }
812
925
  });
926
+ Object.defineProperty(exports, "toMiniProgramModuleId", {
927
+ enumerable: true,
928
+ get: function() {
929
+ return toMiniProgramModuleId;
930
+ }
931
+ });
813
932
  Object.defineProperty(exports, "transformRpx", {
814
933
  enumerable: true,
815
934
  get: function() {
@@ -2,6 +2,9 @@ import path from "node:path";
2
2
  import process from "node:process";
3
3
  import fs from "node:fs";
4
4
  import os from "node:os";
5
+ import { parseSync } from "oxc-parser";
6
+ import { walk } from "oxc-walker";
7
+ import crypto from "node:crypto";
5
8
  //#region src/common/path-utils.js
6
9
  var WINDOWS_FS_PATH_RE = /^(?:[a-zA-Z]:[\\/]|\\\\)/;
7
10
  function isWindowsFsPath(targetPath) {
@@ -29,19 +32,6 @@ function getRelativePosixPath(targetPath, rootPath) {
29
32
  return normalizeToPosixPath(targetPath).replace(normalizeToPosixPath(rootPath), "").replace(/^\//, "");
30
33
  }
31
34
  //#endregion
32
- //#region src/common/art.js
33
- var artCode = `
34
- ██████╗ ██╗███╗ ███╗██╗███╗ ██╗ █████╗
35
- ██╔══██╗██║████╗ ████║██║████╗ ██║██╔══██╗
36
- ██║ ██║██║██╔████╔██║██║██╔██╗ ██║███████║
37
- ██║ ██║██║██║╚██╔╝██║██║██║╚██╗██║██╔══██║
38
- ██████╔╝██║██║ ╚═╝ ██║██║██║ ╚████║██║ ██║
39
- ╚═════╝ ╚═╝╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝╚═╝ ╚═╝
40
- `;
41
- function art_default() {
42
- console.log(artCode);
43
- }
44
- //#endregion
45
35
  //#region src/common/utils.js
46
36
  function hasCompileInfo(modulePath, list, preList) {
47
37
  const mergeList = Array.isArray(preList) ? [...preList, ...list] : list;
@@ -58,19 +48,31 @@ function getAbsolutePath(workPath, pagePath, src) {
58
48
  return path.resolve(workPath, relativePath, src);
59
49
  }
60
50
  var assetsMap = {};
51
+ function isPathInside(rootPath, targetPath) {
52
+ const relativePath = path.relative(rootPath, targetPath);
53
+ return relativePath === "" || !relativePath.startsWith(`..${path.sep}`) && relativePath !== ".." && !path.isAbsolute(relativePath);
54
+ }
55
+ function resolveAssetSourcePath(workPath, pagePath, src) {
56
+ const projectRoot = path.resolve(workPath);
57
+ if (src.startsWith("/")) return path.resolve(projectRoot, `.${src}`);
58
+ const normalizedPagePath = path.resolve(pagePath);
59
+ const pageDirectory = path.isAbsolute(pagePath) && isPathInside(projectRoot, normalizedPagePath) ? path.dirname(normalizedPagePath) : path.resolve(projectRoot, path.dirname(pagePath.replace(/^[/\\]+/, "")));
60
+ const resolvedPath = path.resolve(pageDirectory, src);
61
+ if (isPathInside(projectRoot, resolvedPath)) return resolvedPath;
62
+ return path.resolve(projectRoot, src.replace(/^(?:\.\.[/\\])+/, ""));
63
+ }
61
64
  /**
62
65
  * 将静态资源存储到 static 文件夹
63
66
  */
64
67
  function collectAssets(workPath, pagePath, src, targetPath, appId) {
65
68
  if (src.startsWith("http") || src.startsWith("//")) return src;
66
69
  if (!/\.(?:png|jpe?g|gif|svg)(?:\?.*)?$/.test(src)) return src;
67
- const relativePath = pagePath.split("/").slice(0, -1).join("/");
68
- const absolutePath = src.startsWith("/") ? workPath + src : path.resolve(workPath, relativePath, src);
70
+ const absolutePath = resolveAssetSourcePath(workPath, pagePath, src);
69
71
  if (assetsMap[absolutePath]) return assetsMap[absolutePath];
70
72
  try {
71
73
  const ext = `.${src.split(".").pop()}`;
72
74
  const dirPath = absolutePath.split(path.sep).slice(0, -1).join("/");
73
- const prefix = uuid();
75
+ const prefix = uuid(dirPath);
74
76
  const targetStatic = `${targetPath}/main/static`;
75
77
  if (!fs.existsSync(targetStatic)) fs.mkdirSync(targetStatic, { recursive: true });
76
78
  getFilesWithExtension(dirPath, ext).forEach((file) => {
@@ -96,15 +98,16 @@ function isString(o) {
96
98
  function transformRpx(styleText) {
97
99
  if (!isString(styleText)) return styleText;
98
100
  return styleText.replace(/([+-]?\d+(?:\.\d+)?)rpx/g, (_, pixel) => {
99
- return `${Number(pixel)}rem`;
101
+ const viewportWidth = Number((Number(pixel) / 7.5).toFixed(6));
102
+ return `${Object.is(viewportWidth, -0) ? 0 : viewportWidth}vw`;
100
103
  });
101
104
  }
102
- function uuid() {
103
- return Math.random().toString(36).slice(2, 7);
105
+ function uuid(str) {
106
+ return crypto.createHash("sha256").update(str).digest().readBigUInt64BE(0).toString(36);
104
107
  }
105
108
  var tagWhiteList = [
106
109
  "page",
107
- "wrapper",
110
+ "component-host",
108
111
  "block",
109
112
  "button",
110
113
  "camera",
@@ -145,6 +148,24 @@ var tagWhiteList = [
145
148
  "view",
146
149
  "web-view"
147
150
  ];
151
+ var miniProgramBuiltinTags = /* @__PURE__ */ new Set([
152
+ ...tagWhiteList,
153
+ "canvas",
154
+ "match-media",
155
+ "page-container",
156
+ "share-element",
157
+ "editor",
158
+ "audio",
159
+ "channel-live",
160
+ "channel-video",
161
+ "live-player",
162
+ "live-pusher",
163
+ "voip-room",
164
+ "ad",
165
+ "ad-custom",
166
+ "official-account",
167
+ "xr-frame"
168
+ ]);
148
169
  //#endregion
149
170
  //#region src/common/npm-resolver.js
150
171
  /**
@@ -327,6 +348,12 @@ var DEFAULT_STYLE_EXTS = [
327
348
  ];
328
349
  var DEFAULT_VIEW_SCRIPT_EXTS = [".wxs"];
329
350
  var DEFAULT_VIEW_SCRIPT_TAGS = ["wxs", "dds"];
351
+ var CUSTOM_TAB_BAR_COMPONENT_PATH = "/custom-tab-bar/index";
352
+ var STYLE_ISOLATION_VALUES = /* @__PURE__ */ new Set([
353
+ "isolated",
354
+ "apply-shared",
355
+ "shared"
356
+ ]);
330
357
  var RESERVED_EXTS = /* @__PURE__ */ new Set([
331
358
  ...DEFAULT_TEMPLATE_EXTS,
332
359
  ...DEFAULT_STYLE_EXTS,
@@ -483,6 +510,43 @@ function storePageConfig() {
483
510
  if (subPackages) subPackages.forEach((subPkg) => {
484
511
  collectionPageJson(subPkg.pages, subPkg.root);
485
512
  });
513
+ storeCustomTabBarConfig();
514
+ }
515
+ /**
516
+ * 微信会把 custom-tab-bar/index 作为每个 tab 页的直属组件创建。业务页面
517
+ * 不需要在 usingComponents 中显式声明它,因此编译阶段补一个内部组件引用,
518
+ * 让逻辑、视图和样式三个编译器都能沿现有依赖图收集该组件。
519
+ */
520
+ function storeCustomTabBarConfig() {
521
+ const tabBar = configInfo.appInfo?.tabBar;
522
+ if (tabBar?.custom !== true || !Array.isArray(tabBar.list)) return;
523
+ const componentJsonPath = path.join(pathInfo.workPath, "custom-tab-bar/index.json");
524
+ if (!fs.existsSync(componentJsonPath)) {
525
+ console.warn("[env] tabBar.custom 已启用,但找不到 custom-tab-bar/index.json");
526
+ return;
527
+ }
528
+ const dependencyName = `dimina-${uuid(CUSTOM_TAB_BAR_COMPONENT_PATH)}`;
529
+ storeComponentConfig({ usingComponents: { [dependencyName]: CUSTOM_TAB_BAR_COMPONENT_PATH } }, path.join(pathInfo.workPath, "app.json"));
530
+ const componentConfig = configInfo.componentInfo[CUSTOM_TAB_BAR_COMPONENT_PATH];
531
+ if (componentConfig) componentConfig.customTabBar = true;
532
+ for (const item of tabBar.list) {
533
+ const pagePath = typeof item?.pagePath === "string" ? item.pagePath.replace(/^\/+/, "") : "";
534
+ if (!pagePath || !configInfo.appInfo.pages?.includes(pagePath)) continue;
535
+ const pageConfig = configInfo.pageInfo[pagePath] ||= {};
536
+ pageConfig.usingComponents ||= {};
537
+ const declaredComponents = {
538
+ ...configInfo.appInfo.usingComponents || {},
539
+ ...pageConfig.usingComponents
540
+ };
541
+ let componentName = Object.entries(declaredComponents).find(([, componentPath]) => componentPath === CUSTOM_TAB_BAR_COMPONENT_PATH)?.[0] || dependencyName;
542
+ let suffix = 0;
543
+ while (declaredComponents[componentName] && declaredComponents[componentName] !== CUSTOM_TAB_BAR_COMPONENT_PATH) {
544
+ suffix++;
545
+ componentName = `${dependencyName}-${suffix}`;
546
+ }
547
+ pageConfig.usingComponents[componentName] = CUSTOM_TAB_BAR_COMPONENT_PATH;
548
+ pageConfig.customTabBar = { componentName };
549
+ }
486
550
  }
487
551
  /**
488
552
  * 匹配页面和对应的配置信息
@@ -536,19 +600,65 @@ function storeComponentConfig(pageJsonContent, pageFilePath) {
536
600
  }
537
601
  const cUsing = cContent.usingComponents || {};
538
602
  const isComponent = cContent.component || false;
603
+ const styleIsolation = resolveComponentStyleIsolation(cContent, componentFilePath);
539
604
  const cComponents = Object.keys(cUsing).reduce((acc, key) => {
540
605
  acc[key] = getModuleId(cUsing[key], componentFilePath);
541
606
  return acc;
542
607
  }, {});
543
608
  configInfo.componentInfo[moduleId] = {
544
- id: uuid(),
609
+ id: uuid(moduleId),
545
610
  path: moduleId,
546
611
  component: isComponent,
612
+ styleIsolation,
547
613
  usingComponents: cComponents
548
614
  };
549
615
  if (cContent.usingComponents && Object.keys(cContent.usingComponents).length > 0) storeComponentConfig(configInfo.componentInfo[moduleId], componentFilePath);
550
616
  }
551
617
  }
618
+ function getStaticProperty(objectExpression, propertyName) {
619
+ if (objectExpression?.type !== "ObjectExpression") return;
620
+ return objectExpression.properties?.find((property) => {
621
+ if (property.type !== "Property" || property.computed) return false;
622
+ return property.key?.name === propertyName || property.key?.value === propertyName;
623
+ })?.value;
624
+ }
625
+ function normalizeStyleIsolation(value) {
626
+ return STYLE_ISOLATION_VALUES.has(value) ? value : void 0;
627
+ }
628
+ /**
629
+ * styleIsolation can be declared either in component.json or in
630
+ * Component({ options }). The style compiler must know it before service
631
+ * runtime starts, so only statically-declared literal options participate.
632
+ * addGlobalClass is the legacy equivalent of apply-shared.
633
+ */
634
+ function resolveComponentStyleIsolation(componentConfig, componentJsonPath) {
635
+ const jsonValue = normalizeStyleIsolation(componentConfig?.styleIsolation);
636
+ if (jsonValue) return jsonValue;
637
+ const basePath = componentJsonPath.replace(/\.json$/i, "");
638
+ const scriptPath = [".js", ".ts"].map((ext) => `${basePath}${ext}`).find((candidate) => fs.existsSync(candidate));
639
+ if (!scriptPath) return "isolated";
640
+ try {
641
+ const { program } = parseSync(scriptPath, getContentByPath(scriptPath), { sourceType: "unambiguous" });
642
+ let extractedValue;
643
+ walk(program, { enter(expression) {
644
+ if (extractedValue) return;
645
+ if (expression?.type !== "CallExpression" || expression.callee?.type !== "Identifier" || expression.callee.name !== "Component") return;
646
+ const definition = expression.arguments?.[0];
647
+ const options = getStaticProperty(definition, "options");
648
+ const styleIsolation = getStaticProperty(options, "styleIsolation")?.value;
649
+ const normalized = normalizeStyleIsolation(styleIsolation);
650
+ if (normalized) {
651
+ extractedValue = normalized;
652
+ return;
653
+ }
654
+ if (getStaticProperty(options, "addGlobalClass")?.value === true) extractedValue = "apply-shared";
655
+ } });
656
+ if (extractedValue) return extractedValue;
657
+ } catch (error) {
658
+ console.warn(`[env] 无法解析组件样式隔离配置 ${scriptPath}: ${error.message}`);
659
+ }
660
+ return "isolated";
661
+ }
552
662
  /**
553
663
  * 转化为相对小程序根目录的绝对路径,作为模块唯一性 id
554
664
  * 支持 npm 组件解析
@@ -614,9 +724,12 @@ function getPages() {
614
724
  ...pageComponents
615
725
  };
616
726
  return {
617
- id: uuid(),
727
+ id: uuid(path),
618
728
  path,
619
- usingComponents: mergedComponents
729
+ appStyleScopeId: getAppStyleScopeId(),
730
+ sharedStyleScopeIds: collectSharedStyleScopeIds(mergedComponents),
731
+ usingComponents: mergedComponents,
732
+ customTabBar: pageInfo[path]?.customTabBar
620
733
  };
621
734
  });
622
735
  const subPages = {};
@@ -633,9 +746,12 @@ function getPages() {
633
746
  ...pageComponents
634
747
  };
635
748
  return {
636
- id: uuid(),
749
+ id: uuid(fullPath),
637
750
  path: fullPath,
638
- usingComponents: mergedComponents
751
+ appStyleScopeId: getAppStyleScopeId(),
752
+ sharedStyleScopeIds: collectSharedStyleScopeIds(mergedComponents),
753
+ usingComponents: mergedComponents,
754
+ customTabBar: pageInfo[fullPath]?.customTabBar
639
755
  };
640
756
  })
641
757
  };
@@ -645,5 +761,22 @@ function getPages() {
645
761
  subPages
646
762
  };
647
763
  }
764
+ function collectSharedStyleScopeIds(usingComponents) {
765
+ const result = [];
766
+ const visited = /* @__PURE__ */ new Set();
767
+ const visit = (componentPath) => {
768
+ if (visited.has(componentPath)) return;
769
+ visited.add(componentPath);
770
+ const component = configInfo.componentInfo[componentPath];
771
+ if (!component) return;
772
+ if (component.styleIsolation === "shared") result.push(component.id);
773
+ for (const childPath of Object.values(component.usingComponents || {})) visit(childPath);
774
+ };
775
+ for (const componentPath of Object.values(usingComponents || {})) visit(componentPath);
776
+ return result;
777
+ }
778
+ function getAppStyleScopeId() {
779
+ return uuid("app");
780
+ }
648
781
  //#endregion
649
- export { art_default as C, transformRpx as S, storeInfo as _, getContentByPath as a, hasCompileInfo as b, getPages as c, getTemplateExts as d, getViewScriptExts as f, resolveAppAlias as g, resetStoreInfo as h, getComponent as i, getStyleExts as l, getWorkPath as m, getAppId as n, getNpmResolver as o, getViewScriptTags as p, getAppName as r, getPageConfigInfo as s, getAppConfigInfo as t, getTargetPath as u, collectAssets as v, tagWhiteList as x, getAbsolutePath as y };
782
+ export { tagWhiteList as C, miniProgramBuiltinTags as S, toMiniProgramModuleId as T, resolveAppAlias as _, getComponent as a, getAbsolutePath as b, getPageConfigInfo as c, getTargetPath as d, getTemplateExts as f, resetStoreInfo as g, getWorkPath as h, getAppStyleScopeId as i, getPages as l, getViewScriptTags as m, getAppId as n, getContentByPath as o, getViewScriptExts as p, getAppName as r, getNpmResolver as s, getAppConfigInfo as t, getStyleExts as u, storeInfo as v, transformRpx as w, hasCompileInfo as x, collectAssets as y };