描述:
我正在尝试将我的应用程序从 RN 0.55 升级到最新的稳定 RN 版本 0.61.5,一切正常,直到我在我的 RN 项目中添加共享模块。我在项目中使用打字稿。
下面是我的项目的结构
SharedLib
|_dist/
|_src/
RNApp
|_node_modules/
|_src/
|_package.json | metro.config.js | tsconfig.json | etc
错误是“无法从'../SharedLib/dist/Handler/CacheHandler.js'中解析模块'@babel/runtime/helpers/interoprequirewildcard'的行:@babel/runtim/helpers/interopRequireWildcard 无法在其中找到该项目'。
反应原生版本:
System:
OS: macOS 10.15.2
CPU: (4) x64 Intel(R) Core(TM) i5-7267U CPU @ 3.10GHz
Memory: 102.58 MB / 16.00 GB
Shell: 3.2.57 - /bin/bash
Binaries:
Node: 10.6.0 - /usr/local/bin/node
npm: 6.1.0 - /usr/local/bin/npm
SDKs:
iOS SDK:
Platforms: iOS 13.2, DriverKit 19.0, macOS 10.15, tvOS 13.2, watchOS 6.1
Android SDK:
API Levels: 23, 25, 26, 27, 28, 29
Build Tools: 23.0.1, 23.0.3, 25.0.2, 25.0.3, 26.0.0, 26.0.1, 26.0.2, 27.0.0, 27.0.2, 27.0.3, 28.0.3, 29.0.3
System Images: android-29 | Google APIs Intel x86 Atom
IDEs:
Android Studio: 3.5 AI-191.8026.42.35.6010548
Xcode: 11.3.1/11C504 - /usr/bin/xcodebuild
npmPackages:
react: 16.9.0 => 16.9.0
react-native: 0.61.5 => 0.61.5
npmGlobalPackages:
react-native: 0.61.5
下面是我的 package.json (注意:为了便于阅读,我删除了不相关的依赖项)
{
"dependencies": {
"@babel/runtime": "^7.8.7",
"@shared-lib": "file:../SharedLib",
"react": "16.9.0",
"react-native": "0.61.5",
},
"devDependencies": {
"@babel/core": "^7.6.2",
"@babel/plugin-proposal-decorators": "^7.8.3",
"@babel/plugin-transform-runtime": "^7.8.3",
"@react-native-community/eslint-config": "^0.0.5",
"@types/jest": "^25.1.4",
"@types/react": "^16.9.23",
"babel-jest": "^24.9.0",
"eslint": "^6.8.0",
"eslint-plugin-flowtype": "^4.6.0",
"eslint-plugin-import": "^2.20.1",
"eslint-plugin-jsx-a11y": "^6.2.3",
"eslint-plugin-prettier": "^3.1.2",
"eslint-plugin-react": "^7.19.0",
"eslint-plugin-react-native": "^3.8.1",
"jest": "^24.9.0",
"metro-react-native-babel-preset": "^0.56.0",
"react-test-renderer": "16.9.0",
"ts-jest": "^25.2.1",
"tslint": "^6.1.0",
"typescript": "^3.8.3"
},
"jest": {
"preset": "react-native",
"moduleFileExtensions": [
"ts",
"tsx",
"js"
]
},
}
Metro.config.js
const path = require('path');
module.exports = {
transformer: {
getTransformOptions: async () => ({
transform: {
experimentalImportSupport: false,
inlineRequires: false,
},
}),
},
watchFolders: [path.resolve(__dirname, '../SharedLib')],
};
babel.config.js
module.exports = {
presets: [
'module:metro-react-native-babel-preset',
'module:react-native-dotenv',
],
plugins: [
'@babel/plugin-transform-runtime',
['@babel/plugin-proposal-decorators', {legacy: true}],
],
};
从 typescript 转译后的 CacheHandler.js 文件,如果需要会产生错误
import * as tslib_1 from "tslib";
// import RNFetchBlob from 'react-native-fetch-blob';
import { CacheData, ProcessType, Timer, sleep } from '..';
import { Logger } from './Logger';
var CacheHandler = /** @class */ (function () {
function CacheHandler(cacheSystem, store) {
this.cacheSystem = cacheSystem;
this.store = store;
this.cachedData = {};
this.diskLoadCount = {};
this.processing = {};
}
Object.defineProperty(CacheHandler.prototype, "threadHandler", {
get: function () {
return this.store.threadHandler;
},
enumerable: true,
configurable: true
});
CacheHandler.prototype.getCache = function (key, expireMs, _a) {
var _b = _a === void 0 ? {} : _a, onNotFound = _b.onNotFound, onUsedCache = _b.onUsedCache, _c = _b.inMemoryCache, inMemoryCache = _c === void 0 ? true : _c;
return tslib_1.__awaiter(this, void 0, void 0, function () {
var data, isCache, timer;
return tslib_1.__generator(this, function (_d) {
switch (_d.label) {
case 0:
data = this.cachedData[key];
isCache = false;
timer = new Timer(key);
// console.log("### getCache data1: ", data);
if (data) {
isCache = true;
}
if (!!data) return [3 /*break*/, 2];
return [4 /*yield*/, this.loadFromDisk(key, expireMs)];
case 1:
data = _d.sent();
// console.log("### getCache data2: ", data);
if (data) {
// console.log("loaded from disk");
// console.log("### getCache inMemoryCache: ", inMemoryCache);
if (inMemoryCache) {
this.cachedData[key] = data;
}
isCache = true;
}
_d.label = 2;
case 2:
if (!!data) return [3 /*break*/, 4];
Logger.logError("[CACHE_HANDLER]", "[CACHE_NOT_FOUND]", key);
if (!onNotFound) return [3 /*break*/, 4];
return [4 /*yield*/, onNotFound()];
case 3:
data = _d.sent();
// console.log("### getCache data4: ", data);
if (data) {
this.saveToDisk(key, data, { inMemoryCache: inMemoryCache });
}
_d.label = 4;
case 4:
// console.log("### getCache isCache: ", isCache);
// console.log("### getCache onUsedCache: ", onUsedCache);
if (isCache && onUsedCache) {
onUsedCache(data);
}
// timer.print();
// console.log("### getCache data5: ", isCache);
return [2 /*return*/, data];
}
});
});
};
CacheHandler.prototype.isProcessing = function (path) {
return this.processing[path];
};
CacheHandler.prototype.setProcessing = function (path, boo) {
this.processing[path] = boo;
};
CacheHandler.prototype.waitForProcessing = function (path) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!this.isProcessing(path)) return [3 /*break*/, 2];
console.log("waiting..");
return [4 /*yield*/, sleep(50)];
case 1:
_a.sent();
return [3 /*break*/, 0];
case 2: return [2 /*return*/];
}
});
});
};
CacheHandler.prototype.saveToDisk = function (key, data, _a) {
var _b = (_a === void 0 ? {} : _a).inMemoryCache, inMemoryCache = _b === void 0 ? true : _b;
return tslib_1.__awaiter(this, void 0, void 0, function () {
var str;
return tslib_1.__generator(this, function (_c) {
switch (_c.label) {
case 0:
if (inMemoryCache) {
this.cachedData[key] = data;
}
str = JSON.stringify(new CacheData(data));
return [4 /*yield*/, this.cacheSystem.save(key, str)];
case 1:
_c.sent();
return [2 /*return*/];
}
});
});
};
CacheHandler.prototype.loadFromDiskSequential = function (key, expireMs) {
if (expireMs === void 0) { expireMs = -1; }
return tslib_1.__awaiter(this, void 0, void 0, function () {
var processType;
var _this = this;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
processType = ProcessType.DYNAMIC(key);
if (!this.threadHandler.isProcessQueueEmpty(processType)) return [3 /*break*/, 2];
return [4 /*yield*/, this.threadHandler.runSequential(processType, function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
var result;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.getCache(key, expireMs)];
case 1:
result = _a.sent();
this.cachedData[key] = result;
return [2 /*return*/, result];
}
});
}); })];
case 1: return [2 /*return*/, _a.sent()];
case 2: return [4 /*yield*/, this.threadHandler.runSequential(processType, function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
return tslib_1.__generator(this, function (_a) {
return [2 /*return*/, this.cachedData[key]];
});
}); })];
case 3: return [2 /*return*/, _a.sent()];
}
});
});
};
CacheHandler.prototype.loadFromDisk = function (key, expireMs) {
if (expireMs === void 0) { expireMs = -1; }
return tslib_1.__awaiter(this, void 0, void 0, function () {
var str, e_1, cacheData, obj;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
return [4 /*yield*/, this.cacheSystem.get(key)];
case 1:
str = _a.sent();
return [3 /*break*/, 3];
case 2:
e_1 = _a.sent();
Logger.logError("[CACHE_HANDLER]", "Failed to load", key);
return [3 /*break*/, 3];
case 3:
if (str) {
try {
if (this.diskLoadCount[key]) {
this.diskLoadCount[key]++;
console.log("loaded", this.diskLoadCount[key], "times", key);
}
else {
this.diskLoadCount[key] = 1;
}
cacheData = new CacheData();
obj = JSON.parse(str);
Object.assign(cacheData, obj);
// console.log(cacheData.getDate().fromNow());
if (expireMs > 0 && cacheData.isExpired(expireMs)) {
console.log("Cache found but is expired. returning null.");
return [2 /*return*/, null];
}
if (cacheData.isUpToDate() === false) {
console.log("Cache found but is of old version. returning null.");
return [2 /*return*/, null];
}
return [2 /*return*/, cacheData.getData()];
}
catch (e) {
console.log("ERROR While trying to load cache from disk", e);
}
}
return [2 /*return*/, null];
}
});
});
};
CacheHandler.prototype.clear = function () {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var e_2;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
this.cachedData = {};
return [4 /*yield*/, this.cacheSystem.clear()];
case 1: return [2 /*return*/, _a.sent()];
case 2:
e_2 = _a.sent();
Logger.logError("CACHE SYSTEM", "Clear cache failed", e_2);
return [3 /*break*/, 3];
case 3: return [2 /*return*/];
}
});
});
};
return CacheHandler;
}());
export { CacheHandler };
我知道这一定与 babel 配置有关,因为我已经安装了 @babel/runtime 并检查了我的 node_modules 上确实有 interopRequireWildcard.js 文件,我尝试了互联网上可用的几个选项但没有运气,其中一些不是完全相同的问题但也与 babel 运行时相关,所以值得一试
https://github.com/airbnb/babel-preset-airbnb/issues/56
https://github.com/facebook/react-native/issues/27712
请在 rn github 问题上查看我附加的图像,我无法附加图像,因为 stackoverflow 还是新手https://github.com/facebook/react-native/issues/28317#event-3131781625