loadable-ts-transformer
Version:
TypeScript custom transformer for lodable-components SSR
78 lines (77 loc) • 3.1 kB
JavaScript
;
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var ts = __importStar(require("typescript"));
var chunk_name_1 = __importDefault(require("./properties/chunk-name"));
var require_async_1 = __importDefault(require("./properties/require-async"));
var require_sync_1 = __importDefault(require("./properties/require-sync"));
var is_ready_1 = __importDefault(require("./properties/is-ready"));
var resolve_1 = __importDefault(require("./properties/resolve"));
function isLoadableNode(node) {
if (!ts.isCallExpression(node))
return false;
var identifier = node.expression;
if (!ts.isIdentifier(identifier))
return false;
if (identifier.text !== 'loadable')
return false;
return true;
}
function collectImports(loadableCallExpressionNode, ctx) {
var ret = [];
function visit(node) {
if (node.kind === ts.SyntaxKind.ImportKeyword) {
ret.push(node.parent);
return node;
}
return ts.visitEachChild(node, visit, ctx);
}
ts.visitNodes(loadableCallExpressionNode.arguments, visit);
return ret;
}
function getFuncNode(loadableCallExpressionNode) {
var arg = loadableCallExpressionNode.arguments[0];
if (!arg)
return;
if (!ts.isArrowFunction(arg) && !ts.isFunctionExpression(arg))
return;
return arg;
}
function loadableTransformer(ctx) {
function visitNode(node) {
if (!isLoadableNode(node))
return ts.visitEachChild(node, visitNode, ctx);
var funcNode = getFuncNode(node);
if (!funcNode)
return node;
// Collect dynamic import call expressions such as `import('./foo')`
var imports = collectImports(node, ctx);
// Ignore loadable function that does not have any "import" call
if (imports.length === 0)
return node;
// Multiple imports call is not supported
if (imports.length > 1) {
throw new Error('loadable: multiple import calls inside `loadable()` function are not supported.');
}
var callNode = imports[0];
var obj = ts.createObjectLiteral([
chunk_name_1.default({ ctx: ctx, callNode: callNode, funcNode: funcNode }),
is_ready_1.default(ctx),
require_async_1.default(funcNode),
require_sync_1.default(ctx),
resolve_1.default(callNode),
], true);
return ts.updateCall(node, node.expression, undefined, [obj]);
}
return function (source) { return ts.updateSourceFileNode(source, ts.visitNodes(source.statements, visitNode)); };
}
exports.loadableTransformer = loadableTransformer;