create-expo-cljs-app
Version:
Create a react native application with Expo and Shadow-CLJS!
331 lines (276 loc) • 8.95 kB
JavaScript
/**
* 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
;
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
};