babel-plugin-hylid-bridge 0.0.1 → 0.0.2-dev.10

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.
@@ -0,0 +1 @@
1
+ export default function combieExports(index1Path: string, index2Path: string): string;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.default = combieExports;
8
+ var _path = _interopRequireDefault(require("path"));
9
+ var _fsExtra = _interopRequireDefault(require("fs-extra"));
10
+ var _hashIt = _interopRequireDefault(require("hash-it"));
11
+ var isTest = process.env.NODE_ENV === 'test';
12
+ function combieExports(index1Path, index2Path) {
13
+ var indexPath = _path.default.resolve(__dirname, '..', '.temp', (isTest ? 'test' : (0, _hashIt.default)("".concat(index1Path).concat(index2Path))) + '.js');
14
+ _fsExtra.default.ensureFileSync(indexPath);
15
+ _fsExtra.default.writeFileSync(indexPath, "\n import index1 from '".concat(index1Path, "';\n import index2 from '").concat(index2Path, "';\n\n export default {\n ...index1,\n ...index2,\n };\n "));
16
+ return indexPath;
17
+ }
@@ -0,0 +1,2 @@
1
+ export default function (targets: string[], libraryDir: string): void;
2
+ export declare function filterWhichCanIUseJsapi(apiList: string[]): void;
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.default = _default;
8
+ exports.filterWhichCanIUseJsapi = filterWhichCanIUseJsapi;
9
+ var _path = _interopRequireDefault(require("path"));
10
+ var _fsExtra = _interopRequireDefault(require("fs-extra"));
11
+ var _getLibraryDir = _interopRequireDefault(require("./getLibraryDir"));
12
+ var _helper = require("./helper");
13
+ // 筛选 hylid-bridge 兼容度信息
14
+ function _default(targets, libraryDir) {
15
+ var lib = libraryDir || (0, _getLibraryDir.default)();
16
+ targets = targets.map(function (item) {
17
+ return item.toLowerCase();
18
+ });
19
+ // 获取 lib 下的 bridge.js 文件
20
+ var bridgeFile = _path.default.join(lib, 'lib', 'whichCanIUse', 'compatibilities.json');
21
+ var compatibilities = JSON.parse(_fsExtra.default.readFileSync(bridgeFile, 'utf-8'));
22
+ // 获取 hylid-bridge 版本
23
+ var packageJsonFile = _path.default.join(lib, 'package.json');
24
+ var _JSON$parse = JSON.parse(_fsExtra.default.readFileSync(packageJsonFile, 'utf-8')),
25
+ version = _JSON$parse.version;
26
+ for (var api in compatibilities) {
27
+ compatibilities[api] = compatibilities[api].filter(function (item) {
28
+ // 标记删除的数据不要
29
+ if (item.deleteAt) return false;
30
+ // 比当前 hylid-bridge 版本低的不要
31
+ if (item.hylidBridgeVersion && (0, _helper.compareVersion)(version, item.hylidBridgeVersion) < 0) return false;
32
+ // babel 配置中没有的平台和客户端不要
33
+ if (!targets.includes((item.platformType + item.clientName).toLowerCase())) return false;
34
+ return true;
35
+ });
36
+ compatibilities[api] = compatibilities[api].map(function (item) {
37
+ return {
38
+ clientName: item.clientName,
39
+ platformType: item.platformType,
40
+ clientVersion: item.clientVersion,
41
+ osType: item.osType,
42
+ supported: item.supported
43
+ };
44
+ });
45
+ }
46
+ _fsExtra.default.writeFileSync(bridgeFile, JSON.stringify(compatibilities));
47
+ }
48
+ // 从 api 维度筛除数据
49
+ function filterWhichCanIUseJsapi(apiList) {
50
+ var lib = (0, _getLibraryDir.default)();
51
+ // 获取 lib 下的 bridge.js 文件
52
+ var bridgeFile = _path.default.join(lib, 'lib', 'whichCanIUse', 'compatibilities.json');
53
+ var compatibilities = JSON.parse(_fsExtra.default.readFileSync(bridgeFile, 'utf-8'));
54
+ Object.keys(compatibilities).forEach(function (api) {
55
+ if (!apiList.includes(api)) {
56
+ delete compatibilities[api];
57
+ }
58
+ });
59
+ _fsExtra.default.writeFileSync(bridgeFile, JSON.stringify(compatibilities));
60
+ }
@@ -0,0 +1 @@
1
+ export default function generateJSAPIs(targets: string[], libraryDir: string): void;
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.default = generateJSAPIs;
8
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
9
+ var _path = _interopRequireDefault(require("path"));
10
+ var _fsExtra = _interopRequireDefault(require("fs-extra"));
11
+ var _parser = require("@babel/parser");
12
+ var _traverse = _interopRequireDefault(require("@babel/traverse"));
13
+ var _generator = _interopRequireDefault(require("@babel/generator"));
14
+ var _getLibraryDir = _interopRequireDefault(require("./getLibraryDir"));
15
+ var _helper = require("./helper");
16
+ function generateJSAPIs(targets, libraryDir) {
17
+ var lib = libraryDir || (0, _getLibraryDir.default)();
18
+ // 获取当前配置的环境信息
19
+ var appEnvList = targets.reduce(function (acc, target) {
20
+ var _splitTarget = (0, _helper.splitTarget)(target),
21
+ _splitTarget2 = (0, _slicedToArray2.default)(_splitTarget, 2),
22
+ platform = _splitTarget2[0],
23
+ client = _splitTarget2[1];
24
+ acc.push("".concat((0, _helper.camelCase)("is_".concat(platform, "_").concat(client))));
25
+ return acc;
26
+ }, []);
27
+ // 获取 lib 下的 bridge.js 文件
28
+ var bridgeFile = _path.default.join(lib, 'lib', 'bridges.js');
29
+ var ast = (0, _parser.parse)(_fsExtra.default.readFileSync(bridgeFile, 'utf-8'), {
30
+ sourceType: 'module'
31
+ });
32
+ (0, _traverse.default)(ast, {
33
+ IfStatement: function IfStatement(path) {
34
+ /**
35
+ * if 条件里有 n 多种写法,test 对应 n 多中类型。
36
+ * 下面为了方便,直接尝试访问 object.name 是否是 appEnv,在 bridge.js 中,符合这个条件的,一定是 jsapi 函数中 if 判断条件
37
+ */
38
+ var _ref = path.node.test || {},
39
+ object = _ref.object,
40
+ property = _ref.property;
41
+ if ((object === null || object === void 0 ? void 0 : object.name) === 'appEnv') {
42
+ var env = property.name;
43
+ // 删除不是目标的 appEnv 判断代码
44
+ if (!appEnvList.includes(env)) {
45
+ path.remove();
46
+ }
47
+ }
48
+ }
49
+ });
50
+ // 生成文件
51
+ var outInnerPath = _path.default.join(lib, 'lib', 'babel-compact-inner.js');
52
+ var outExportPath = _path.default.join(lib, 'lib', 'babel-compact.js');
53
+ var codes = ['// auto generated', "export * from './index'", (0, _generator.default)(ast).code];
54
+ var exportCodes = ['// auto generated', "export * from './babel-compact-inner'", "export * as default from './babel-compact-inner'"];
55
+ _fsExtra.default.writeFileSync(outExportPath, exportCodes.join('\n'));
56
+ _fsExtra.default.writeFileSync(outInnerPath, codes.join('\n'));
57
+ }
@@ -4,24 +4,30 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = getLibraryDir;
7
-
8
7
  var _utils = require("./utils");
9
-
10
8
  var libraryDir;
11
-
12
9
  function getLibraryDir() {
13
10
  if (!libraryDir) {
14
11
  var cwd = process.cwd();
15
-
16
12
  try {
17
- libraryDir = process.env.HYLID_BRIDGE_PACKAGE_DIR || require.resolve('hylid-bridge/package.json', {
13
+ // 找到依赖的 hylid-bridge,内外网版本同时找
14
+ var pathInternal = require.resolve('@alipay/hylid-bridge/package.json', {
18
15
  paths: [cwd]
19
16
  }).replace('package.json', '');
17
+ var path = require.resolve('hylid-bridge/package.json', {
18
+ paths: [cwd]
19
+ }).replace('package.json', '');
20
+ // 本地开发时,只安装了内网版本的包,外网的的包会找到 packages 目录下的开发包,需要忽略该情况
21
+ if (!pathInternal.includes('hylid-bridge/packages')) {
22
+ libraryDir = pathInternal;
23
+ }
24
+ if (!path.includes('hylid-bridge/packages')) {
25
+ libraryDir = path;
26
+ }
27
+ (0, _utils.log)("Find the hylid-bridge package: ".concat(libraryDir));
20
28
  } catch (e) {
21
29
  (0, _utils.error)("Can not resolve the hylid-bridge package from the directory: ".concat(cwd, "."), e);
22
30
  }
23
31
  }
24
-
25
- (0, _utils.log)("Find the hylid-bridge package: ".concat(libraryDir));
26
32
  return libraryDir;
27
33
  }
@@ -0,0 +1,25 @@
1
+ import type babelCore from '@babel/core';
2
+ import { PluginPass } from '@babel/core';
3
+ export declare function snakeCaseTarget(input: string): string;
4
+ export declare function isTargetSupported(target: string, libraryDir: string): boolean;
5
+ export declare function getTargets(libraryDir: string, customTargets?: string[]): string[];
6
+ export declare function isApiExists(name: string, target: string, libraryDir: string, polyfillDir?: string): boolean | "" | undefined;
7
+ export declare function getUserAppEnvPath(appEnvPath?: string): string | undefined;
8
+ export declare function splitTarget(target: string): string[];
9
+ interface IState extends PluginPass {
10
+ usedJSAPIList: 'all' | string[];
11
+ }
12
+ export declare function getNames(node: babelCore.NodePath<babelCore.types.MemberExpression>['node'], scope: babelCore.NodePath<babelCore.types.MemberExpression>['scope'], state: IState, targets: string[]): {
13
+ objectName: string;
14
+ propertyName: undefined;
15
+ } | {
16
+ objectName: string;
17
+ propertyName: string;
18
+ } | {
19
+ objectName: undefined;
20
+ propertyName: undefined;
21
+ };
22
+ export declare function isJSAPIInTargets(jsapiName: string, targets: string[], filename: string, libraryDir: string, polyfillDir?: string): boolean;
23
+ export declare function camelCase(input: string): string;
24
+ export declare function compareVersion(version1: string, version2: string): number;
25
+ export {};
package/lib/helper.js ADDED
@@ -0,0 +1,139 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ var _typeof = require("@babel/runtime/helpers/typeof");
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.camelCase = camelCase;
9
+ exports.compareVersion = compareVersion;
10
+ exports.getNames = getNames;
11
+ exports.getTargets = getTargets;
12
+ exports.getUserAppEnvPath = getUserAppEnvPath;
13
+ exports.isApiExists = isApiExists;
14
+ exports.isJSAPIInTargets = isJSAPIInTargets;
15
+ exports.isTargetSupported = isTargetSupported;
16
+ exports.snakeCaseTarget = snakeCaseTarget;
17
+ exports.splitTarget = splitTarget;
18
+ var _path = _interopRequireDefault(require("path"));
19
+ var _fsExtra = _interopRequireDefault(require("fs-extra"));
20
+ var utils = _interopRequireWildcard(require("./utils"));
21
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
22
+ function snakeCaseTarget(input) {
23
+ var words = input.replace(/[^a-zA-Z0-9]+/g, ' ').trim();
24
+ var wordArray = words.split(' ');
25
+ var snakeCasedWords = wordArray.map(function (word) {
26
+ return word.replace(/[A-Z]/g, function (match, index) {
27
+ return index === 0 ? match.toLowerCase() : "_".concat(match.toLowerCase());
28
+ });
29
+ });
30
+ return snakeCasedWords.join('_');
31
+ }
32
+ function isTargetSupported(target, libraryDir) {
33
+ return ['MpWeb', 'Mp', 'Web'].some(function (prefix) {
34
+ if (target.startsWith(prefix)) {
35
+ var targetClientDir = _path.default.resolve(libraryDir, 'lib/clients', snakeCaseTarget(prefix), snakeCaseTarget(target.replace(prefix, '')));
36
+ return _fsExtra.default.existsSync(targetClientDir);
37
+ }
38
+ return false;
39
+ });
40
+ }
41
+ function getTargets(libraryDir, customTargets) {
42
+ var targets = customTargets || (process.env.HYLID_BRIDGE_TARGETS ? process.env.HYLID_BRIDGE_TARGETS.split(',') : []);
43
+ return targets.filter(function (target) {
44
+ return isTargetSupported(target, libraryDir);
45
+ });
46
+ }
47
+ function isApiExists(name, target, libraryDir, polyfillDir) {
48
+ var targetSplit = splitTarget(target);
49
+ if (targetSplit.length !== 2) {
50
+ throw new Error("Wrong target configuration: ".concat(target, "."));
51
+ }
52
+ return _fsExtra.default.existsSync(_path.default.resolve(libraryDir, "./lib/clients/".concat(targetSplit[0], "/").concat(targetSplit[1], "/").concat(name, ".js"))) || polyfillDir && (_fsExtra.default.existsSync(_path.default.resolve(polyfillDir, "./".concat(targetSplit[0], "/").concat(targetSplit[1], "/").concat(name, ".js"))) || _fsExtra.default.existsSync(_path.default.resolve(polyfillDir, "./".concat(targetSplit[0], "/").concat(targetSplit[1], "/").concat(name, ".ts"))));
53
+ }
54
+ function getUserAppEnvPath(appEnvPath) {
55
+ var realAppEnvPath = appEnvPath !== null && appEnvPath !== void 0 ? appEnvPath : _path.default.resolve(process.cwd(), './src/appEnv.ts');
56
+ if (!_fsExtra.default.existsSync(realAppEnvPath)) {
57
+ utils.log("Can not find the appEnv module at the path: ".concat(realAppEnvPath, "."));
58
+ return;
59
+ }
60
+ return realAppEnvPath;
61
+ }
62
+ function splitTarget(target) {
63
+ var prefixList = ['MpWeb', 'Mp', 'Web'];
64
+ for (var i = 0, il = prefixList.length; i < il; i++) {
65
+ var prefix = prefixList[i];
66
+ if (target.startsWith(prefix)) {
67
+ return [snakeCaseTarget(prefix), snakeCaseTarget(target.replace(prefix, ''))];
68
+ }
69
+ }
70
+ throw new Error("Invalid bridge target: ".concat(target, "."));
71
+ }
72
+ function getNames(node, scope, state, targets) {
73
+ var _state$filename;
74
+ // my.alert || my[a]
75
+ if (node.object.type === 'Identifier' && node.property.type === 'Identifier' &&
76
+ // Remix 中会编译所有 node_modules 下的模块
77
+ !((_state$filename = state.filename) !== null && _state$filename !== void 0 && _state$filename.includes("".concat(_path.default.sep, "node_modules").concat(_path.default.sep, "hylid-bridge").concat(_path.default.sep))) && targets && targets.length && !scope.hasBinding('my')) {
78
+ return node.computed ? {
79
+ objectName: node.object.name,
80
+ propertyName: undefined
81
+ } : {
82
+ objectName: node.object.name,
83
+ propertyName: node.property.name
84
+ };
85
+ }
86
+ // my['alert']
87
+ if (node.object.type === 'Identifier' && node.property.type === 'StringLiteral' && node.computed && targets && targets.length && !scope.hasBinding('my')) {
88
+ return {
89
+ objectName: node.object.name,
90
+ propertyName: node.property.value
91
+ };
92
+ }
93
+ return {
94
+ objectName: undefined,
95
+ propertyName: undefined
96
+ };
97
+ }
98
+ function isJSAPIInTargets(jsapiName, targets, filename, libraryDir, polyfillDir) {
99
+ return targets.every(function (target) {
100
+ var targetSplit = splitTarget(target);
101
+ if (!isApiExists(jsapiName, target, libraryDir, polyfillDir)) {
102
+ utils.warn("Can not find the API `".concat(jsapiName, "` in `").concat(_path.default.resolve(libraryDir, './lib/clients/' + targetSplit[0] + '/' + targetSplit[1]), "`. Fallback to import all API codes of ").concat(target, ". Current file path: `").concat(filename, "`."));
103
+ return false;
104
+ }
105
+ return true;
106
+ });
107
+ }
108
+ // lodash 把数字后面第一个字符变大了,所以这里单独实现下
109
+ function camelCase(input) {
110
+ var words = input.replace(/[^a-zA-Z0-9]+/g, ' ').trim();
111
+ var wordArray = words.split(' ');
112
+ var camelCasedWords = wordArray.map(function (word, index) {
113
+ if (index === 0) {
114
+ return word.toLowerCase();
115
+ }
116
+ return word.charAt(0).toUpperCase() + word.slice(1);
117
+ });
118
+ return camelCasedWords.join('');
119
+ }
120
+ // 用于 babel 插件中比较 hylid-bridge 版本号
121
+ function compareVersion(version1, version2) {
122
+ // 删除 alpha 后缀进行比较,4.0.0-alpha.1 => 4.0.0
123
+ version1 = version1.split('-')[0];
124
+ version2 = version2.split('-')[0];
125
+ var v1Parts = version1.split('.').map(Number);
126
+ var v2Parts = version2.split('.').map(Number);
127
+ var maxLength = Math.max(v1Parts.length, v2Parts.length);
128
+ for (var i = 0; i < maxLength; i++) {
129
+ var v1 = v1Parts[i] || 0;
130
+ var v2 = v2Parts[i] || 0;
131
+ if (v1 > v2) {
132
+ return 1;
133
+ }
134
+ if (v1 < v2) {
135
+ return -1;
136
+ }
137
+ }
138
+ return 0;
139
+ }
package/lib/index.d.ts CHANGED
@@ -2,6 +2,14 @@ import type babelCore from '@babel/core';
2
2
  import { PluginPass } from '@babel/core';
3
3
  interface IState extends PluginPass {
4
4
  usedJSAPIList: 'all' | string[];
5
+ whichCanIUseJsapiList: string[];
5
6
  }
6
- declare const _default: (_: typeof babelCore, opts?: Record<string, any> | undefined) => babelCore.PluginObj<IState>;
7
+ declare const _default: (core: typeof babelCore, opts?: {
8
+ targets?: string[];
9
+ appEnvPath?: string;
10
+ libraryDir?: string;
11
+ polyfillDir?: string;
12
+ transformMy?: boolean;
13
+ compact?: boolean;
14
+ }) => babelCore.PluginObj<IState>;
7
15
  export default _default;
package/lib/index.js CHANGED
@@ -1,184 +1,226 @@
1
1
  "use strict";
2
2
 
3
3
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
-
5
4
  var _typeof = require("@babel/runtime/helpers/typeof");
6
-
7
5
  Object.defineProperty(exports, "__esModule", {
8
6
  value: true
9
7
  });
10
8
  exports.default = void 0;
11
-
12
9
  var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
13
-
14
10
  var _path = _interopRequireDefault(require("path"));
15
-
16
11
  var _fsExtra = _interopRequireDefault(require("fs-extra"));
17
-
18
12
  var _lodash = _interopRequireDefault(require("lodash"));
19
-
20
13
  var babelTypes = _interopRequireWildcard(require("@babel/types"));
21
-
22
14
  var _getLibraryDir = _interopRequireDefault(require("./getLibraryDir"));
23
-
24
- var utils = _interopRequireWildcard(require("./utils"));
25
-
26
- function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
27
-
28
- function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
29
-
15
+ var _utils = _interopRequireWildcard(require("./utils"));
16
+ var utils = _utils;
17
+ var _combineExports = _interopRequireDefault(require("./combineExports"));
18
+ var _helper = require("./helper");
19
+ var _generateJSAPIs = _interopRequireDefault(require("./generateJSAPIs"));
20
+ var _generateCompatibilities = _interopRequireWildcard(require("./generateCompatibilities"));
21
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
30
22
  /**
31
23
  * https://astexplorer.net/
32
24
  */
25
+
33
26
  var identifierPrefix = '__hylid_bridge__';
34
27
  var libraryName = 'hylid-bridge';
35
- var libraryDir = (0, _getLibraryDir.default)();
36
-
37
- function getTargets(customTargets) {
38
- var targets = customTargets || (process.env.HYLID_BRIDGE_TARGETS ? process.env.HYLID_BRIDGE_TARGETS.split(',') : []);
39
- return targets;
40
- }
41
-
42
- function isApiExists(name, target) {
43
- var targetSplit = target.split('|');
44
-
45
- if (targetSplit.length !== 2) {
46
- throw new Error("Wrong target configuration: ".concat(target, "."));
47
- }
48
-
49
- return _fsExtra.default.existsSync(_path.default.resolve(libraryDir, "./lib/clients/".concat(targetSplit[0], "/").concat(targetSplit[1], "/").concat(name, ".js")));
50
- }
51
-
52
- var _default = function _default(_, opts) {
53
- var targets = getTargets(opts === null || opts === void 0 ? void 0 : opts.targets);
28
+ var myLocalName = "".concat(identifierPrefix, "my__");
29
+ var _default = exports.default = function _default(core, opts) {
30
+ var _opts$libraryDir, _opts$transformMy, _opts$compact;
31
+ var libraryDir = (_opts$libraryDir = opts === null || opts === void 0 ? void 0 : opts.libraryDir) !== null && _opts$libraryDir !== void 0 ? _opts$libraryDir : (0, _getLibraryDir.default)();
32
+ var targets = (0, _helper.getTargets)(libraryDir, opts === null || opts === void 0 ? void 0 : opts.targets);
33
+ var userAppEnvPath = (0, _helper.getUserAppEnvPath)(opts === null || opts === void 0 ? void 0 : opts.appEnvPath);
34
+ var polyfillDir = opts === null || opts === void 0 ? void 0 : opts.polyfillDir;
35
+ var transformMy = (_opts$transformMy = opts === null || opts === void 0 ? void 0 : opts.transformMy) !== null && _opts$transformMy !== void 0 ? _opts$transformMy : false;
36
+ var compact = (_opts$compact = opts === null || opts === void 0 ? void 0 : opts.compact) !== null && _opts$compact !== void 0 ? _opts$compact : true;
37
+ // 生成 babel-compact 文件
38
+ compact && (0, _generateJSAPIs.default)(targets, libraryDir);
39
+ (0, _generateCompatibilities.default)(targets, libraryDir);
54
40
  return {
55
41
  name: 'babel-plugin-hylid-bridge',
56
42
  visitor: {
43
+ ImportDeclaration: function ImportDeclaration(path) {
44
+ if (!compact) return;
45
+ if (path.node.source.value === libraryName) {
46
+ path.node.source = core.types.stringLiteral("".concat(libraryName, "/babel-compact"));
47
+ }
48
+ },
49
+ ExportNamedDeclaration: function ExportNamedDeclaration(path) {
50
+ var _path$node$source;
51
+ if (!compact) return;
52
+ if (((_path$node$source = path.node.source) === null || _path$node$source === void 0 ? void 0 : _path$node$source.value) === libraryName) {
53
+ path.node.source = core.types.stringLiteral("".concat(libraryName, "/babel-compact"));
54
+ }
55
+ },
57
56
  MemberExpression: function MemberExpression(path, state) {
58
- var _this = this;
59
-
60
- var objectName = path.node.object.name;
61
- var propertyName = path.node.property.name;
62
-
63
- if (!targets || !targets.length || objectName !== 'my' || path.scope.hasBinding('my')) {
57
+ var _getNames = (0, _helper.getNames)(path.node, path.scope, state, targets),
58
+ objectName = _getNames.objectName,
59
+ propertyName = _getNames.propertyName;
60
+ if (propertyName === 'call' || objectName !== 'my' || !transformMy) {
64
61
  return;
65
62
  }
66
-
63
+ var newNode = core.types.cloneNode(path.node, true, true);
64
+ newNode.object = core.types.identifier(myLocalName);
67
65
  if (state.usedJSAPIList === 'all') {
66
+ path.replaceWith(newNode);
68
67
  return;
69
68
  }
70
-
71
- if (path.node.computed) {
69
+ if (!propertyName && path.node.computed) {
72
70
  state.usedJSAPIList = 'all';
73
- utils.warn("Detect visiting the property of `my` with computed mode: my[".concat(propertyName, "]. Fallback to import all API codes of ").concat(targets.join(','), ". Current file path: `").concat(this.file.opts.filename, "`."));
74
- } else {
71
+ utils.warn("Detect visiting the property of `my` with computed mode. Fallback to import all API codes of ".concat(targets.join(','), ". Current file path: `").concat(state.filename, "`."));
72
+ path.replaceWith(newNode);
73
+ return;
74
+ }
75
+ if (propertyName) {
75
76
  state.usedJSAPIList = state.usedJSAPIList || [];
76
77
  var name = propertyName;
77
-
78
- if (targets.every(function (target) {
79
- var targetSplit = target.split('|');
80
-
81
- if (!isApiExists(name, target)) {
82
- utils.warn("Can not find the API `".concat(name, "` in `").concat(_path.default.resolve(libraryDir, './lib/clients/' + targetSplit[0] + '/' + targetSplit[1]), "`. Fallback to import all API codes of ").concat(target, ". Current file path: `").concat(_this.file.opts.filename, "`."));
83
- return false;
84
- }
85
-
86
- return true;
87
- })) {
78
+ if ((0, _helper.isJSAPIInTargets)(name, targets, state.filename, libraryDir, polyfillDir)) {
88
79
  state.usedJSAPIList.push(name);
89
80
  } else {
90
81
  state.usedJSAPIList = 'all';
91
82
  }
83
+ path.replaceWith(newNode);
84
+ return;
92
85
  }
93
86
  },
87
+ CallExpression: function CallExpression(path, state) {
88
+ if (path.node.callee.type === 'Identifier' && path.node.callee.name === 'whichCanIUse') {
89
+ if (!state.whichCanIUseJsapiList) {
90
+ state.whichCanIUseJsapiList = [];
91
+ }
92
+ if (path.node.arguments[0].type === 'ObjectExpression') {
93
+ path.node.arguments[0].properties.forEach(function (property) {
94
+ if (property.type === 'ObjectProperty' && property.key.type === 'Identifier' && property.key.name === 'apiName') {
95
+ if (property.value.type === 'StringLiteral') {
96
+ state.whichCanIUseJsapiList.push(property.value.value);
97
+ } else {
98
+ // apiName 为非字符串类型,警告开发者
99
+ (0, _utils.warn)('WhichCanIUse warning: apiName must be a string literal and not a variable');
100
+ }
101
+ }
102
+ });
103
+ }
104
+ }
105
+ if (path.node.callee.type !== 'MemberExpression' || !transformMy) {
106
+ return;
107
+ }
108
+ var _getNames2 = (0, _helper.getNames)(path.node.callee, path.scope, state, targets),
109
+ objectName = _getNames2.objectName,
110
+ propertyName = _getNames2.propertyName;
111
+ if (objectName !== 'my' || propertyName !== 'call' || !path.node.arguments[0] || path.node.arguments[0].type !== 'StringLiteral') {
112
+ return;
113
+ }
114
+ var newNode = core.types.callExpression(
115
+ // @ts-ignore
116
+ babelTypes.memberExpression(babelTypes.identifier(myLocalName), babelTypes.identifier(path.node.arguments[0].value)), path.node.arguments.slice(1));
117
+ if (state.usedJSAPIList === 'all') {
118
+ path.replaceWith(newNode);
119
+ return;
120
+ }
121
+ state.usedJSAPIList = state.usedJSAPIList || [];
122
+ var name = path.node.arguments[0].value;
123
+ if ((0, _helper.isJSAPIInTargets)(name, targets, state.filename, libraryDir, polyfillDir)) {
124
+ state.usedJSAPIList.push(name);
125
+ } else {
126
+ state.usedJSAPIList = 'all';
127
+ }
128
+ path.replaceWith(newNode);
129
+ },
94
130
  Program: {
95
131
  exit: function exit(path, state) {
132
+ var _state$whichCanIUseJs;
133
+ if ((_state$whichCanIUseJs = state.whichCanIUseJsapiList) !== null && _state$whichCanIUseJs !== void 0 && _state$whichCanIUseJs.length) {
134
+ (0, _generateCompatibilities.filterWhichCanIUseJsapi)(state.whichCanIUseJsapiList);
135
+ }
96
136
  if (!state.usedJSAPIList) {
97
137
  return;
98
138
  }
99
-
100
139
  var usedJSAPIList = state.usedJSAPIList || [];
101
140
  var appEnvLocalName = "".concat(identifierPrefix, "appEnv__");
102
-
103
141
  if (path.scope.hasBinding(appEnvLocalName)) {
104
142
  return;
105
143
  }
106
-
107
- var nodes = [babelTypes.importDeclaration([babelTypes.importDefaultSpecifier(babelTypes.identifier(appEnvLocalName))], babelTypes.stringLiteral("".concat(libraryName, "/lib/appEnv")))];
108
-
144
+ var innerAppEnvLocalName = "".concat(identifierPrefix, "innerAppEnv__");
145
+ var userAppEnvLocalName = "".concat(identifierPrefix, "userAppEnv__");
146
+ var nodes = [babelTypes.importDeclaration([babelTypes.importDefaultSpecifier(babelTypes.identifier(innerAppEnvLocalName))], babelTypes.stringLiteral("".concat(libraryName, "/lib/appEnv")))];
147
+ if (userAppEnvPath) {
148
+ var relativePath = _path.default.relative(_path.default.dirname(state.filename), userAppEnvPath.replace(/\.ts$/, ''));
149
+ nodes.push(babelTypes.importDeclaration([babelTypes.importDefaultSpecifier(babelTypes.identifier(userAppEnvLocalName))], babelTypes.stringLiteral(relativePath.startsWith('../') ? relativePath : "./".concat(relativePath))));
150
+ } else {
151
+ nodes.push(babelTypes.variableDeclaration('var', [babelTypes.variableDeclarator(babelTypes.identifier(userAppEnvLocalName), babelTypes.objectExpression([]))]));
152
+ }
153
+ var objectSpreadName = "".concat(identifierPrefix, "objectSpread__");
154
+ nodes.push(babelTypes.importDeclaration([babelTypes.importDefaultSpecifier(babelTypes.identifier(objectSpreadName))], babelTypes.stringLiteral("".concat(libraryName, "/lib/objectSpread"))), babelTypes.variableDeclaration('var', [babelTypes.variableDeclarator(babelTypes.identifier(appEnvLocalName), babelTypes.callExpression(babelTypes.identifier(objectSpreadName), [babelTypes.identifier(innerAppEnvLocalName), babelTypes.identifier(userAppEnvLocalName)]))]));
109
155
  if (usedJSAPIList === 'all') {
110
156
  nodes.push.apply(nodes, (0, _toConsumableArray2.default)(targets.map(function (target) {
111
- var targetSplit = target.split('|');
112
- return babelTypes.importDeclaration([babelTypes.importDefaultSpecifier(babelTypes.identifier("".concat(identifierPrefix).concat(targetSplit[0], "_").concat(targetSplit[1], "_my__")))], babelTypes.stringLiteral("".concat(libraryName, "/lib/clients/").concat(targetSplit[0], "/").concat(targetSplit[1], "/index")));
157
+ var targetSplit = (0, _helper.splitTarget)(target);
158
+ var innerIndexPath = "".concat(libraryName, "/lib/clients/").concat(targetSplit[0], "/").concat(targetSplit[1], "/index");
159
+ var polyfillIndexPath = polyfillDir && _path.default.resolve(polyfillDir, targetSplit[0], targetSplit[1], 'index');
160
+ var normalizedIndexPath = polyfillIndexPath && (_fsExtra.default.existsSync("".concat(polyfillIndexPath, ".js")) || _fsExtra.default.existsSync("".concat(polyfillIndexPath, ".ts"))) ? (0, _combineExports.default)(require.resolve(innerIndexPath), polyfillIndexPath) : innerIndexPath;
161
+ return babelTypes.importDeclaration([babelTypes.importDefaultSpecifier(babelTypes.identifier("".concat(identifierPrefix).concat(targetSplit[0], "_").concat(targetSplit[1], "_my__")))], babelTypes.stringLiteral(normalizedIndexPath));
113
162
  })));
114
-
115
- var buildElseIf = function buildElseIf(targetList) {
163
+ var _buildElseIf = function buildElseIf(targetList) {
116
164
  if (!targetList.length) {
117
165
  return;
118
166
  }
119
-
120
167
  var target = targetList[0];
121
- var targetSplit = target.split('|');
122
- return babelTypes.ifStatement(babelTypes.identifier("".concat(appEnvLocalName, ".").concat(_lodash.default.camelCase("is_".concat(targetSplit[0], "_").concat(targetSplit[1])))), babelTypes.blockStatement([babelTypes.expressionStatement(babelTypes.assignmentExpression('=', babelTypes.identifier('my'), babelTypes.identifier("".concat(identifierPrefix).concat(targetSplit[0], "_").concat(targetSplit[1], "_my__"))))]), buildElseIf(targetList.slice(1)));
168
+ var targetSplit = (0, _helper.splitTarget)(target);
169
+ return babelTypes.ifStatement(babelTypes.identifier("".concat(appEnvLocalName, ".").concat((0, _helper.camelCase)("is_".concat(targetSplit[0], "_").concat(targetSplit[1])))), babelTypes.blockStatement([babelTypes.expressionStatement(babelTypes.assignmentExpression('=', babelTypes.identifier(myLocalName), babelTypes.identifier("".concat(identifierPrefix).concat(targetSplit[0], "_").concat(targetSplit[1], "_my__"))))]), _buildElseIf(targetList.slice(1)));
123
170
  };
124
-
125
- nodes.push(babelTypes.variableDeclaration('var', [babelTypes.variableDeclarator(babelTypes.identifier('my'))])); // Do not generate the `if statement` when there is just one target.
126
-
171
+ nodes.push(babelTypes.variableDeclaration('var', [babelTypes.variableDeclarator(babelTypes.identifier(myLocalName))]));
172
+ // Do not generate the `if statement` when there is just one target.
127
173
  if (targets.length === 1) {
128
- var targetSplit = targets[0].split('|');
129
- nodes.push(babelTypes.expressionStatement(babelTypes.assignmentExpression('=', babelTypes.identifier('my'), babelTypes.identifier("".concat(identifierPrefix).concat(targetSplit[0], "_").concat(targetSplit[1], "_my__")))));
174
+ var targetSplit = (0, _helper.splitTarget)(targets[0]);
175
+ nodes.push(babelTypes.expressionStatement(babelTypes.assignmentExpression('=', babelTypes.identifier(myLocalName), babelTypes.identifier("".concat(identifierPrefix).concat(targetSplit[0], "_").concat(targetSplit[1], "_my__")))));
130
176
  } else {
131
- var elseIfNode = buildElseIf(targets);
177
+ var elseIfNode = _buildElseIf(targets);
132
178
  elseIfNode && nodes.push(elseIfNode);
133
179
  }
134
180
  } else if (usedJSAPIList.length) {
135
181
  var normalizedJSAPIList = _lodash.default.uniq(usedJSAPIList);
136
-
137
182
  normalizedJSAPIList.forEach(function (name) {
138
183
  targets.forEach(function (target) {
139
- var localName = "".concat(identifierPrefix).concat(target, "_").concat(name, "__");
140
- var targetSplit = target.split('|');
141
- var n = babelTypes.importDeclaration([babelTypes.importDefaultSpecifier(babelTypes.identifier(localName))], babelTypes.stringLiteral("".concat(libraryName, "/lib/clients/").concat(targetSplit[0], "/").concat(targetSplit[1], "/").concat(name)));
184
+ var targetSplit = (0, _helper.splitTarget)(target);
185
+ var localName = "".concat(identifierPrefix).concat(targetSplit[0], "_").concat(targetSplit[1], "_").concat(name, "__");
186
+ var innerSourcePath = "".concat(libraryName, "/lib/clients/").concat(targetSplit[0], "/").concat(targetSplit[1], "/").concat(name);
187
+ var userSourcePath = polyfillDir ? _path.default.resolve(polyfillDir, targetSplit[0], targetSplit[1], name) : undefined;
188
+ var n = babelTypes.importDeclaration([babelTypes.importDefaultSpecifier(babelTypes.identifier(localName))], babelTypes.stringLiteral(userSourcePath && (_fsExtra.default.existsSync("".concat(userSourcePath, ".js")) || _fsExtra.default.existsSync("".concat(userSourcePath, ".ts"))) ? userSourcePath : innerSourcePath));
142
189
  nodes.push(n);
143
190
  });
144
191
  });
145
-
146
- var _buildElseIf = function _buildElseIf(targetList) {
192
+ var _buildElseIf2 = function buildElseIf(targetList) {
147
193
  if (!targetList.length) {
148
194
  return;
149
195
  }
150
-
151
196
  var target = targetList[0];
152
- var targetSplit = target.split('|');
197
+ var targetSplit = (0, _helper.splitTarget)(target);
153
198
  var propertyList = normalizedJSAPIList.map(function (name) {
154
199
  return babelTypes.objectProperty(babelTypes.identifier(name), babelTypes.identifier("".concat(identifierPrefix).concat(targetSplit[0], "_").concat(targetSplit[1], "_").concat(name, "__")));
155
200
  });
156
- return babelTypes.ifStatement(babelTypes.identifier("".concat(appEnvLocalName, ".").concat(_lodash.default.camelCase("is_".concat(targetSplit[0], "_").concat(targetSplit[1])))), babelTypes.blockStatement([babelTypes.expressionStatement(babelTypes.assignmentExpression('=', babelTypes.identifier('my'), babelTypes.objectExpression(propertyList)))]), _buildElseIf(targetList.slice(1)));
201
+ return babelTypes.ifStatement(babelTypes.identifier("".concat(appEnvLocalName, ".").concat((0, _helper.camelCase)("is_".concat(targetSplit[0], "_").concat(targetSplit[1])))), babelTypes.blockStatement([babelTypes.expressionStatement(babelTypes.assignmentExpression('=', babelTypes.identifier(myLocalName), babelTypes.objectExpression(propertyList)))]), _buildElseIf2(targetList.slice(1)));
157
202
  };
158
-
159
- nodes.push(babelTypes.variableDeclaration('var', [babelTypes.variableDeclarator(babelTypes.identifier('my'))])); // Do not generate the `if statement` when there is just one target.
160
-
203
+ nodes.push(babelTypes.variableDeclaration('var', [babelTypes.variableDeclarator(babelTypes.identifier(myLocalName))]));
204
+ // Do not generate the `if statement` when there is just one target.
161
205
  if (targets.length === 1) {
162
- var _targetSplit = targets[0].split('|');
163
-
206
+ var _targetSplit = (0, _helper.splitTarget)(targets[0]);
164
207
  var propertyList = normalizedJSAPIList.map(function (name) {
165
208
  return babelTypes.objectProperty(babelTypes.identifier(name), babelTypes.identifier("".concat(identifierPrefix).concat(_targetSplit[0], "_").concat(_targetSplit[1], "_").concat(name, "__")));
166
209
  });
167
- nodes.push(babelTypes.expressionStatement(babelTypes.assignmentExpression('=', babelTypes.identifier('my'), babelTypes.objectExpression(propertyList))));
210
+ nodes.push(babelTypes.expressionStatement(babelTypes.assignmentExpression('=', babelTypes.identifier(myLocalName), babelTypes.objectExpression(propertyList))));
168
211
  } else {
169
- var _elseIfNode = _buildElseIf(targets);
170
-
212
+ var _elseIfNode = _buildElseIf2(targets);
171
213
  _elseIfNode && nodes.push(_elseIfNode);
172
214
  }
173
215
  }
174
-
175
216
  if (nodes.length) {
176
217
  path.unshiftContainer('body', nodes);
177
218
  }
219
+ if (targets.length && (usedJSAPIList === 'all' || usedJSAPIList.length)) {
220
+ utils.log("Successfully inject the Hylid-bridge into ".concat(state.filename, " to support the targets: ").concat(targets.join(','), "."));
221
+ }
178
222
  }
179
223
  }
180
224
  }
181
225
  };
182
- };
183
-
184
- exports.default = _default;
226
+ };
package/lib/utils.js CHANGED
@@ -1,42 +1,31 @@
1
1
  "use strict";
2
2
 
3
3
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
-
5
4
  Object.defineProperty(exports, "__esModule", {
6
5
  value: true
7
6
  });
8
7
  exports.error = error;
9
8
  exports.log = log;
10
9
  exports.warn = warn;
11
-
12
10
  var _chalk = _interopRequireDefault(require("chalk"));
13
-
14
11
  function log() {
15
12
  var _console;
16
-
17
13
  for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
18
14
  args[_key] = arguments[_key];
19
15
  }
20
-
21
16
  (_console = console).log.apply(_console, [_chalk.default.bold.green('[LOG]')].concat(args));
22
17
  }
23
-
24
18
  function error() {
25
19
  var _console2;
26
-
27
20
  for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
28
21
  args[_key2] = arguments[_key2];
29
22
  }
30
-
31
23
  (_console2 = console).error.apply(_console2, [_chalk.default.bold.red('[ERROR]')].concat(args));
32
24
  }
33
-
34
25
  function warn() {
35
26
  var _console3;
36
-
37
27
  for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
38
28
  args[_key3] = arguments[_key3];
39
29
  }
40
-
41
30
  (_console3 = console).error.apply(_console3, [_chalk.default.bold.yellow('[WARN]')].concat(args));
42
31
  }
package/package.json CHANGED
@@ -1,31 +1,28 @@
1
1
  {
2
2
  "name": "babel-plugin-hylid-bridge",
3
- "version": "0.0.1",
3
+ "version": "0.0.2-dev.10",
4
4
  "description": "babel-plugin-hylid-bridge",
5
5
  "main": "lib/index.js",
6
- "scripts": {
7
- "build": "gulp build",
8
- "dev": "gulp dev"
9
- },
10
6
  "files": [
11
7
  "lib"
12
8
  ],
13
9
  "keywords": [],
14
10
  "license": "MIT",
15
11
  "dependencies": {
16
- "@babel/core": "^7.15.6",
17
- "@babel/types": "^7.15.6",
18
- "@types/fs-extra": "^9.0.13",
19
- "@types/lodash": "^4.14.176",
20
- "chalk": "^4.1.2",
21
- "fs-extra": "^10.0.0",
22
- "lodash": "^4.17.21"
12
+ "@babel/core": "7.18.2",
13
+ "@babel/runtime": "7.18.9",
14
+ "@babel/types": "7.18.10",
15
+ "@types/fs-extra": "9.0.13",
16
+ "@types/lodash": "4.14.182",
17
+ "chalk": "3.0.0",
18
+ "fs-extra": "10.1.0",
19
+ "hash-it": "^6.0.0",
20
+ "lodash": "4.17.21"
23
21
  },
24
22
  "devDependencies": {
25
- "gulp": "4.0.2",
26
- "gulp-plumber": "^1.2.1",
27
- "gulp-babel": "8.0.0",
28
- "gulp-typescript": "5.0.1"
23
+ "@types/babel-plugin-tester": "^9.0.7",
24
+ "babel-plugin-tester": "^10.1.0",
25
+ "hylid-bridge": "^0.0.2-dev.10"
29
26
  },
30
27
  "sideEffects": false,
31
28
  "registry": "https://registry.npmjs.org/"
package/CHANGELOG.md DELETED
File without changes