1

描述:

我正在尝试将我的应用程序从 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

https://forums.expo.io/t/unable-to-resolve-module-module-babel-runtime-helpers-interoprequirewildcard-js/27806/3

请在 rn github 问题上查看我附加的图像,我无法附加图像,因为 stackoverflow 还是新手https://github.com/facebook/react-native/issues/28317#event-3131781625

4

0 回答 0