@tanstack/router-plugin
Version:
Modern and scalable routing for React applications
101 lines (100 loc) • 3.25 kB
JavaScript
import { parseAst, generateFromAst, logDiff } from "@tanstack/router-utils";
import babel from "@babel/core";
import * as template from "@babel/template";
import { getConfig } from "./config.js";
import { normalizePath, debug } from "./utils.js";
const unpluginRouteAutoImportFactory = (options = {}) => {
let ROOT = process.cwd();
let userConfig;
function initUserConfig() {
if (typeof options === "function") {
userConfig = options();
} else {
userConfig = getConfig(options, ROOT);
}
}
return {
name: "tanstack-router:autoimport",
enforce: "pre",
transform: {
filter: {
// this is necessary for webpack / rspack to avoid matching .html files
id: /\.(m|c)?(j|t)sx?$/,
code: /createFileRoute\(|createLazyFileRoute\(/
},
handler(code, id) {
const normalizedId = normalizePath(id);
if (!globalThis.TSR_ROUTES_BY_ID_MAP?.has(normalizedId)) {
return null;
}
let routeType;
if (code.includes("createFileRoute(")) {
routeType = "createFileRoute";
} else if (code.includes("createLazyFileRoute(")) {
routeType = "createLazyFileRoute";
} else {
return null;
}
const routerImportPath = `@tanstack/${userConfig.target}-router`;
const ast = parseAst({ code });
let isCreateRouteFunctionImported = false;
babel.traverse(ast, {
Program: {
enter(programPath) {
programPath.traverse({
ImportDeclaration(path) {
const importedSpecifiers = path.node.specifiers.map(
(specifier) => specifier.local.name
);
if (importedSpecifiers.includes(routeType) && path.node.source.value === routerImportPath) {
isCreateRouteFunctionImported = true;
}
}
});
}
}
});
if (!isCreateRouteFunctionImported) {
if (debug) console.info("Adding autoimports to route ", normalizedId);
const autoImportStatement = template.statement(
`import { ${routeType} } from '${routerImportPath}'`
)();
ast.program.body.unshift(autoImportStatement);
const result = generateFromAst(ast, {
sourceMaps: true,
filename: normalizedId,
sourceFileName: normalizedId
});
if (debug) {
logDiff(code, result.code);
console.log("Output:\n", result.code + "\n\n");
}
return result;
}
return null;
}
},
vite: {
configResolved(config) {
ROOT = config.root;
initUserConfig();
},
// this check may only happen after config is resolved, so we use applyToEnvironment (apply is too early)
applyToEnvironment() {
return userConfig.verboseFileRoutes === false;
}
},
rspack() {
ROOT = process.cwd();
initUserConfig();
},
webpack() {
ROOT = process.cwd();
initUserConfig();
}
};
};
export {
unpluginRouteAutoImportFactory
};
//# sourceMappingURL=route-autoimport-plugin.js.map