create-expo-cljs-app
Version:
Create a react native application with Expo and Shadow-CLJS!
189 lines (159 loc) • 4.74 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
*
*/
;
var _template = _interopRequireDefault(require("@babel/template"));
var _traverse = _interopRequireDefault(require("@babel/traverse"));
var t = _interopRequireWildcard(require("@babel/types"));
var _invariant = _interopRequireDefault(require("invariant"));
function _getRequireWildcardCache() {
if (typeof WeakMap !== "function") return null;
var cache = new WeakMap();
_getRequireWildcardCache = function() {
return cache;
};
return cache;
}
function _interopRequireWildcard(obj) {
if (obj && obj.__esModule) {
return obj;
}
if (obj === null || (typeof obj !== "object" && typeof obj !== "function")) {
return {
default: obj
};
}
var cache = _getRequireWildcardCache();
if (cache && cache.has(obj)) {
return cache.get(obj);
}
var newObj = {};
var hasPropertyDescriptor =
Object.defineProperty && Object.getOwnPropertyDescriptor;
for (var key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
var desc = hasPropertyDescriptor
? Object.getOwnPropertyDescriptor(obj, key)
: null;
if (desc && (desc.get || desc.set)) {
Object.defineProperty(newObj, key, desc);
} else {
newObj[key] = obj[key];
}
}
}
newObj.default = obj;
if (cache) {
cache.set(obj, newObj);
}
return newObj;
}
function _interopRequireDefault(obj) {
return obj && obj.__esModule
? obj
: {
default: obj
};
}
const WRAP_NAME = "$$_REQUIRE"; // note: babel will prefix this with _
// Check first the `global` variable as the global object. This way serializers
// can create a local variable called global to fake it as a global object
// without having to pollute the window object on web.
const IIFE_PARAM = _template.default.expression(
"typeof globalThis !== 'undefined' ? globalThis : typeof global !== 'undefined' ? global : typeof window !== 'undefined' ? window : this"
);
function wrapModule(
fileAst,
importDefaultName,
importAllName,
dependencyMapName,
globalPrefix
) {
const params = buildParameters(
importDefaultName,
importAllName,
dependencyMapName
);
const factory = functionFromProgram(fileAst.program, params);
const def = t.callExpression(t.identifier(`${globalPrefix}__d`), [factory]);
const ast = t.file(t.program([t.expressionStatement(def)]));
const requireName = renameRequires(ast);
return {
ast,
requireName
};
}
function wrapPolyfill(fileAst) {
const factory = functionFromProgram(fileAst.program, ["global"]);
const iife = t.callExpression(factory, [IIFE_PARAM()]);
return t.file(t.program([t.expressionStatement(iife)]));
}
function jsonToCommonJS(source) {
return `module.exports = ${source};`;
}
function wrapJson(source, globalPrefix) {
// Unused parameters; remember that's wrapping JSON.
const moduleFactoryParameters = buildParameters(
"_importDefaultUnused",
"_importAllUnused",
"_dependencyMapUnused"
);
return [
`${globalPrefix}__d(function(${moduleFactoryParameters.join(", ")}) {`,
` ${jsonToCommonJS(source)}`,
"});"
].join("\n");
}
function functionFromProgram(program, parameters) {
return t.functionExpression(
undefined,
parameters.map(makeIdentifier),
t.blockStatement(program.body, program.directives)
);
}
function makeIdentifier(name) {
return t.identifier(name);
}
function buildParameters(importDefaultName, importAllName, dependencyMapName) {
return [
"global",
"require",
importDefaultName,
importAllName,
"module",
"exports",
dependencyMapName
];
} // Renaming requires should ideally only be done when generating for the target
// that expects the custom require name in the optimize step.
// This visitor currently renames all `require` references even if the module
// contains a custom `require` declaration. This should be fixed by only renaming
// if the `require` symbol hasn't been redeclared.
function renameRequires(ast) {
let newRequireName = WRAP_NAME;
(0, _traverse.default)(ast, {
Program(path) {
const body = path.get("body.0.expression.arguments.0.body");
(0, _invariant.default)(
!Array.isArray(body),
"metro: Expected `body` to be a single path."
);
newRequireName = body.scope.generateUid(WRAP_NAME);
body.scope.rename("require", newRequireName);
}
});
return newRequireName;
}
module.exports = {
WRAP_NAME,
wrapJson,
jsonToCommonJS,
wrapModule,
wrapPolyfill
};