Skip to content

Instantly share code, notes, and snippets.

@Grohden
Created November 23, 2021 19:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Grohden/b351dc6f45971755eddcb3c30c20dbe8 to your computer and use it in GitHub Desktop.
Save Grohden/b351dc6f45971755eddcb3c30c20dbe8 to your computer and use it in GitHub Desktop.
Script that resolves all exports + paths from TS barrel files, meant to be used with babel-transform-imports
const fs = require('fs');
const path = require('path');
const ts = require('typescript');
/**
* Parses a barrel (index) file, extracts all it's export
* names and returns an object that maps
* a import name to the path + some meta infos.
*
*
* Note: this doesn't handle the following cases:
* ```
* import {A, B} from './foo';
*
* export {A,B}
*
* export * as Namespace from './foo';
* ```
*
* The case above is not supported.
*/
const collectExports = (file) => {
const sourceFile = ts.createSourceFile(
file,
fs.readFileSync(file).toString(),
ts.ScriptTarget.ES2015,
true,
);
const exports = {};
sourceFile.forEachChild((child) => {
if (ts.isExportDeclaration(child)) {
if (child.exportClause && child.moduleSpecifier) {
const importName = child.moduleSpecifier.text;
child.exportClause.forEachChild((node) => {
if (ts.isExportSpecifier(node)) {
exports[node.name.text] = {
importPath: importName,
isDefault: node.propertyName !== undefined,
};
}
});
}
}
});
return exports;
};
/**
* Given a result from the collectExports returns a
* import module string for the given member
*/
const memberImportSolver = (libImportPath, mappings) => (member) => {
const mapping = mappings[member];
if (!mapping) {
throw new Error(`Could not find mapping for ${member}`);
}
return path.join(libImportPath, mapping.importPath);
};
/**
* Transforms the object from collectExports into a object
* that has a key as the import name and the value as the alias original name
*/
const importAliases = (info) => {
return Object.keys(info).reduce((aliases, key) => {
const value = info[key];
if (value.isDefault) {
aliases[key] = 'default';
} else {
aliases[key] = key;
}
return aliases;
}, {});
};
module.exports = {
collectExports,
memberImportSolver,
importAliases,
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment