import y export: comparte código entre módulos
En JavaScript moderno cada archivo es un módulo independiente. Con export expones lo que quieres compartir; con import lo consumes desde otro archivo. Esta separación es la base de cualquier proyecto escalable.
¿Qué es un módulo?
Antes de ESM (ES Modules), todos los archivos JavaScript compartían el mismo ámbito global. Hoy, cada archivo es un módulo: su propio ámbito aislado. Nada sale al exterior a menos que lo exportes explícitamente.
// matematicas.js
// Todo lo que no se exporta es PRIVADO al módulo
const PI = 3.14159;
function cuadrado(n) {
return n * n;
}
export function suma(a, b) {
return a + b;
}
export function areaCirculo(radio) {
return PI * cuadrado(radio); // PI y cuadrado son privados
}
// PI y cuadrado NO son accesibles desde fuera// matematicas.ts
// Todo lo que no se exporta es PRIVADO al módulo
const PI = 3.14159;
function cuadrado(n: number): number {
return n * n;
}
export function suma(a: number, b: number): number {
return a + b;
}
export function areaCirculo(radio: number): number {
return PI * cuadrado(radio); // PI y cuadrado son privados
}
// PI y cuadrado NO son accesibles desde fueraEn el navegador usa <script type="module">. En Node.js agrega "type": "module" en tu package.json o usa extensión .mjs.
export — exponer funciones, clases y variables
Puedes exportar cualquier declaración: variables, funciones, clases, e incluso tipos en TypeScript.
// usuarios.js — varias formas de exportar
// 1. Export inline — junto a la declaración
export const VERSION = "1.0.0";
export function crearUsuario(nombre, email) {
return { id: crypto.randomUUID(), nombre, email };
}
export class RepositorioUsuarios {
#usuarios = [];
agregar(usuario) {
this.#usuarios.push(usuario);
}
listar() {
return [...this.#usuarios];
}
}
// 2. Export al final del archivo (equivalente)
const LIMITE_USUARIOS = 100;
function validarEmail(email) {
return email.includes("@");
}
export { LIMITE_USUARIOS, validarEmail };// usuarios.ts — también puedes exportar tipos e interfaces
export const VERSION = "1.0.0";
export interface Usuario {
id: string;
nombre: string;
email: string;
}
export function crearUsuario(nombre: string, email: string): Usuario {
return { id: crypto.randomUUID(), nombre, email };
}
export class RepositorioUsuarios {
private usuarios: Usuario[] = [];
agregar(usuario: Usuario): void {
this.usuarios.push(usuario);
}
listar(): Usuario[] {
return [...this.usuarios];
}
}
export const LIMITE_USUARIOS = 100;
export function validarEmail(email: string): boolean {
return email.includes("@");
}import — consumir desde otros módulos
import siempre va al principio del archivo. Los nombres deben coincidir exactamente con los exportados (puedes renombrarlos con as).
// main.js
import { crearUsuario, validarEmail, LIMITE_USUARIOS } from "./usuarios.js";
// Usar lo importado normalmente
const email = "ana@ejemplo.com";
if (validarEmail(email)) {
const usuario = crearUsuario("Ana", email);
console.log(usuario);
// { id: "...", nombre: "Ana", email: "ana@ejemplo.com" }
}
// Importar con alias para evitar colisiones
import { suma as sumar } from "./matematicas.js";
console.log(sumar(3, 4)); // 7
// Importar todo el módulo como namespace
import * as Mat from "./matematicas.js";
console.log(Mat.areaCirculo(5)); // 78.53...// main.ts
import { crearUsuario, validarEmail, LIMITE_USUARIOS, type Usuario } from "./usuarios.js";
// En TS puedes importar solo tipos con 'import type'
import type { Usuario as UsuarioTipo } from "./usuarios.js";
const email = "ana@ejemplo.com";
if (validarEmail(email)) {
const usuario: Usuario = crearUsuario("Ana", email);
console.log(usuario);
// { id: "...", nombre: "Ana", email: "ana@ejemplo.com" }
}
// Importar con alias
import { suma as sumar } from "./matematicas.js";
console.log(sumar(3, 4)); // 7
// Namespace import
import * as Mat from "./matematicas.js";
console.log(Mat.areaCirculo(5)); // 78.53...{ id: "...", nombre: "Ana", email: "ana@ejemplo.com" }
7
78.53975En ESM nativo (Node.js y navegador) debes incluir la extensión en las rutas: "./matematicas.js". TypeScript permite omitir la extensión al escribir, pero al compilar genera los .js correctamente.
Múltiples exports en un archivo
Un módulo puede exportar cuantas cosas necesite. Organiza por responsabilidad, no por cantidad.
// formato.js — módulo con múltiples utilidades relacionadas
export function capitalizar(texto) {
return texto.charAt(0).toUpperCase() + texto.slice(1).toLowerCase();
}
export function truncar(texto, max = 50) {
return texto.length > max ? texto.slice(0, max) + "..." : texto;
}
export function slugify(texto) {
return texto
.toLowerCase()
.normalize("NFD")
.replace(/[̀-ͯ]/g, "")
.replace(/s+/g, "-")
.replace(/[^w-]/g, "");
}
export const FORMATOS = {
fecha: "DD/MM/YYYY",
moneda: "es-MX",
};
// Uso en otro archivo:
// import { capitalizar, slugify, FORMATOS } from "./formato.js";
// console.log(slugify("Hola Mundo")); // "hola-mundo"// formato.ts
export function capitalizar(texto: string): string {
return texto.charAt(0).toUpperCase() + texto.slice(1).toLowerCase();
}
export function truncar(texto: string, max = 50): string {
return texto.length > max ? texto.slice(0, max) + "..." : texto;
}
export function slugify(texto: string): string {
return texto
.toLowerCase()
.normalize("NFD")
.replace(/[̀-ͯ]/g, "")
.replace(/s+/g, "-")
.replace(/[^w-]/g, "");
}
export interface ConfigFormatos {
fecha: string;
moneda: string;
}
export const FORMATOS: ConfigFormatos = {
fecha: "DD/MM/YYYY",
moneda: "es-MX",
};hola-mundo