UNPKG

create-expo-cljs-app

Version:

Create a react native application with Expo and Shadow-CLJS!

331 lines (276 loc) 8.95 kB
/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * * @format */ // Note: This is a fork of the fb-specific transform.js "use strict"; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function(sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function(key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function(key) { Object.defineProperty( target, key, Object.getOwnPropertyDescriptor(source, key) ); }); } } return target; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } const crypto = require("crypto"); const fs = require("fs"); const inlineRequiresPlugin = require("babel-preset-fbjs/plugins/inline-requires"); const makeHMRConfig = require("metro-react-native-babel-preset/src/configs/hmr"); const nullthrows = require("nullthrows"); const path = require("path"); const _require = require("@babel/core"), parseSync = _require.parseSync, transformFromAstSync = _require.transformFromAstSync; const _require2 = require("metro-source-map"), generateFunctionMap = _require2.generateFunctionMap; const cacheKeyParts = [ fs.readFileSync(__filename), require("babel-preset-fbjs/package.json").version ]; /** * Return a memoized function that checks for the existence of a * project level .babelrc file, and if it doesn't exist, reads the * default RN babelrc file and uses that. */ const getBabelRC = (function() { let babelRC = null; return function _getBabelRC(_ref) { let projectRoot = _ref.projectRoot, extendsBabelConfigPath = _ref.extendsBabelConfigPath, options = _objectWithoutProperties(_ref, [ "projectRoot", "extendsBabelConfigPath" ]); if (babelRC != null) { return babelRC; } babelRC = { plugins: [], extends: extendsBabelConfigPath }; if (extendsBabelConfigPath) { return babelRC; } // Let's look for a babel config file in the project root. let projectBabelRCPath; // .babelrc if (projectRoot) { projectBabelRCPath = path.resolve(projectRoot, ".babelrc"); } if (projectBabelRCPath) { // .babelrc.js if (!fs.existsSync(projectBabelRCPath)) { projectBabelRCPath = path.resolve(projectRoot, ".babelrc.js"); } // babel.config.js if (!fs.existsSync(projectBabelRCPath)) { projectBabelRCPath = path.resolve(projectRoot, "babel.config.js"); } // If we found a babel config file, extend our config off of it // otherwise the default config will be used if (fs.existsSync(projectBabelRCPath)) { babelRC.extends = projectBabelRCPath; } } // If a babel config file doesn't exist in the project then // the default preset for react-native will be used instead. if (!babelRC.extends) { const experimentalImportSupport = options.experimentalImportSupport, presetOptions = _objectWithoutProperties(options, [ "experimentalImportSupport" ]); babelRC.presets = [ [ require("metro-react-native-babel-preset"), /* $FlowFixMe(>=0.122.0 site=react_native_fb) This comment suppresses * an error found when Flow v0.122.0 was deployed. To see the error, * delete this comment and run Flow. */ _objectSpread( _objectSpread( { projectRoot }, presetOptions ), {}, { disableImportExportTransform: experimentalImportSupport, enableBabelRuntime: options.enableBabelRuntime } ) ] ]; } return babelRC; }; })(); /** * Given a filename and options, build a Babel * config object with the appropriate plugins. */ function buildBabelConfig(filename, options) { let plugins = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : []; const babelRC = getBabelRC(options); const extraConfig = { babelrc: typeof options.enableBabelRCLookup === "boolean" ? options.enableBabelRCLookup : true, code: false, filename, highlightCode: true }; let config = _objectSpread(_objectSpread({}, babelRC), extraConfig); // Add extra plugins const extraPlugins = []; if (options.inlineRequires) { extraPlugins.push(inlineRequiresPlugin); } const withExtrPlugins = (config.plugins = extraPlugins.concat( config.plugins, plugins )); if (options.dev && options.hot) { // Note: this intentionally doesn't include the path separator because // I'm not sure which one it should use on Windows, and false positives // are unlikely anyway. If you later decide to include the separator, // don't forget that the string usually *starts* with "node_modules" so // the first one often won't be there. const mayContainEditableReactComponents = filename.indexOf("node_modules") === -1; if (mayContainEditableReactComponents) { const hmrConfig = makeHMRConfig(); hmrConfig.plugins = withExtrPlugins.concat(hmrConfig.plugins); config = Object.assign({}, config, hmrConfig); } } return _objectSpread(_objectSpread({}, babelRC), config); } function transform(_ref2) { let filename = _ref2.filename, options = _ref2.options, src = _ref2.src, plugins = _ref2.plugins; const OLD_BABEL_ENV = process.env.BABEL_ENV; process.env.BABEL_ENV = options.dev ? "development" : process.env.BABEL_ENV || "production"; try { const babelConfig = _objectSpread( _objectSpread( { // ES modules require sourceType='module' but OSS may not always want that sourceType: "unambiguous" }, buildBabelConfig(filename, options, plugins) ), {}, { caller: { name: "metro", bundler: "metro", platform: options.platform }, ast: true } ); const sourceAst = parseSync(src, babelConfig); /* $FlowFixMe(>=0.111.0 site=react_native_fb) This comment suppresses an * error found when Flow v0.111 was deployed. To see the error, delete this * comment and run Flow. */ const result = transformFromAstSync(sourceAst, src, babelConfig); const functionMap = generateFunctionMap(sourceAst, { filename }); // The result from `transformFromAstSync` can be null (if the file is ignored) if (!result) { /* $FlowFixMe BabelTransformer specifies that the `ast` can never be null but * the function returns here. Discovered when typing `BabelNode`. */ return { ast: null, functionMap }; } return { ast: nullthrows(result.ast), functionMap }; } finally { if (OLD_BABEL_ENV) { process.env.BABEL_ENV = OLD_BABEL_ENV; } } } function getCacheKey() { var key = crypto.createHash("md5"); cacheKeyParts.forEach(part => key.update(part)); return key.digest("hex"); } module.exports = { transform, getCacheKey };