Use when fixing CJS/ESM module issues in Nango integrations after zero-yaml migration - covers import path fixes, creating ESM wrappers for CJS vendor modules, and restoring commented-out code
This skill documents common issues and fixes when migrating Nango integrations to ESM (zero-yaml migration).
Could not resolve "../../vendor/dinero.js/index.js"Cannot find module '../../../vendor/dinero.js'Check git history to see what was changed during migration:
git log --oneline -10 -- <file>
git show <commit>:<file> | head -20
Look for commented-out code with "temporary" comments - these are often proper implementations replaced with broken workarounds
Verify the vendor module exists and check its structure:
ls -la vendor/<module>/
cat vendor/<module>/package.json
When a vendor module only has CJS exports but your project uses ESM:
Create vendor/<module>/index.js:
import Module from './build/cjs/<module>.js';
export default Module;
Update imports to use .js extensions (required for ESM):
// Before (commented out or broken)
// import foo from "../../../vendor/foo";
// After (working ESM)
import foo from "../../vendor/foo/index.js";
Replace any "temporary" hardcoded workarounds with the original implementation.
Example - Currency Conversion:
// BAD: Hardcoded workaround (loses currency-specific precision)
function fromMajorToDinero(amount: number | null | undefined, _currencyCode: string | undefined): number | null {
if (amount == null) return null;
return Math.round(amount * 100); // Wrong for JPY, KWD, etc.
}
// GOOD: Proper implementation using currency exponents
import dinero from "../../vendor/dinero.js/index.js";
import { currencies } from "../../vendor/dinero.js/dinero-currencies.js";
function fromMajorToDinero(amount: number | null | undefined, currencyCode: string | undefined): number | null {
if (amount == null || !currencyCode) return null;
const currency = currencies[currencyCode.toUpperCase()];
if (!currency) return null;
const exponent = currency.exponent;
const amountInMinor = Math.round(amount * 10 ** exponent);
return dinero({
amount: amountInMinor,
currency: currency as any,
}).getAmount();
}
From nango-integrations/<integration>/mappers/<file>.ts:
nango-integrations/vendor/: use ../../vendor/From nango-integrations/<integration>/actions/<file>.ts:
nango-integrations/vendor/: use ../../vendor/# Type check
npx tsc --noEmit
# Full compile
npx nango compile
_paramName (underscore prefix) - indicates intentionally unused parameter, likely a workaround* 100) replacing dynamic lookups (like * 10 ** exponent)