diff --git a/packages/react-native-babel-preset/src/index.js b/packages/react-native-babel-preset/src/index.js index 1d46f1ceef0..d2b5fc98721 100644 --- a/packages/react-native-babel-preset/src/index.js +++ b/packages/react-native-babel-preset/src/index.js @@ -10,11 +10,41 @@ 'use strict'; +const {version: packageVersion} = require('../package.json'); const main = require('./configs/main'); module.exports = function (babel, options) { return main(options); }; +let cacheKey; +module.exports.getCacheKey = () => { + if (cacheKey != null) { + // Memoize + return cacheKey; + } + if (!packageVersion.endsWith('-main')) { + // Assume the integrity of package contents for published npm releases. + cacheKey = packageVersion; + return cacheKey; + } + // For anyone working with a `-main` version, contents may vary over time + // even though the version does not. Hash the relevant contents of this + // package. Lazy-load dependencies we only need on this slow path. + const {createHash} = require('crypto'); + const {readFileSync} = require('fs'); + const key = createHash('md5'); + [ + readFileSync(__filename), + readFileSync(require.resolve('./configs/main.js')), + readFileSync(require.resolve('./configs/hmr.js')), + readFileSync(require.resolve('./configs/lazy-imports.js')), + readFileSync(require.resolve('./passthrough-syntax-plugins.js')), + readFileSync(require.resolve('./plugin-warn-on-deep-imports.js')), + ].forEach(part => key.update(part)); + cacheKey = key.digest('hex'); + return cacheKey; +}; + module.exports.getPreset = main.getPreset; module.exports.passthroughSyntaxPlugins = require('./passthrough-syntax-plugins'); diff --git a/packages/react-native-babel-transformer/src/index.js b/packages/react-native-babel-transformer/src/index.js index 8ba7c3afe3d..d5e541c370a 100644 --- a/packages/react-native-babel-transformer/src/index.js +++ b/packages/react-native-babel-transformer/src/index.js @@ -23,13 +23,14 @@ import type { */ const {parseSync, transformFromAstSync} = require('@babel/core'); +const {getCacheKey: getPresetCacheKey} = require('@react-native/babel-preset'); const makeHMRConfig = require('@react-native/babel-preset/src/configs/hmr'); const crypto = require('crypto'); const fs = require('fs'); const nullthrows = require('nullthrows'); const path = require('path'); -const cacheKeyParts = [fs.readFileSync(__filename)]; +const cacheKeyParts = [getPresetCacheKey(), fs.readFileSync(__filename)]; // TS detection conditions copied from @react-native/babel-preset function isTypeScriptSource(fileName /*: string */) {