Skip to content
youhoc
  • Pages
    • Home
    • Modern App Guidelines
    • Node.js
      • Installing & Exploring
      • Loading Modules
      • npm - Get Command Input
      • Express.js
        • Express Web Server
        • Template Engine & MVC
        • Authentication
        • Authentication Trong REST API Với JWT
        • File Upload with Multer, Express.js
        • Server-Side Validation Với Express-Validator
      • Sequelize
        • Sequelize Transactions: Đảm Bảo Tính Toàn Vẹn Dữ Liệu
        • 7 loại Data Types phổ biến Trong Sequelize
        • Phân Trang (Pagination) Trong Express.js Với Sequelize/MySQL
      • Hướng dẫn Cơ bản về Rest API
      • Node-cron Simple to Complex Setup with PM2
      • Hono
        • Hono Response
        • Error Handling
    • Cloudflare
      • Minimal Cloudflare Worker + Hono + Drizzle ORM (part 1)
      • Minimal Cloudflare Worker + Hono + Drizzle ORM (part 2)
    • htmx
      • HTMx Form: Request, Response, Swap
    • Linux
      • Day 1: Linux Distributions & Navigation
      • Day 2: User Management
      • Day 3: File Permission & Ownership
      • Day 4: Package Management
      • Day 5: Services Management
    • Javascript
      • JS The Weird Part
        • Execution Context
        • Types & Operators
        • Objects & Functions
        • Error Handling & Strict Mode
        • Typescript, ES6, Tra
      • Modern JS
        • JS in the Browser
        • Data Storage JSON
        • Modern JS
        • Advanced Objects & Methods
        • Webpack & Babel
        • Async
      • jQuery
        • In-depth Analysis of jQuery
      • React-ready JS
        • Arrow Function
        • Template Literals
        • Logical AND, OR, Ternary, Nullish Operators
        • Destructuring & Rest Operator
        • Array Method
        • Immutability and Spread Operator
        • Promises, Async/Await, Callback
    • Typescript
      • TypeScript cơ bản (phần 1)
      • TypeScript cơ bản (phần 2)
      • icon picker
        require vs import
    • ReactJS
      • React from Andrew
        • Summary from Next
        • 1. Basics
        • 2. React Components
        • 3. Webpack
        • 4. Styling with SCSS
        • 5. React Router
        • 6. React Hook
      • Modern React From The Beginning
        • Intro to JSX
        • Vite Build Tools
        • Basic Component Creation
        • Component State
        • Props & Component Composition
        • useState with Inputs & Form Submission
        • useEffect, useRef & Local Storage
        • Async / Await and Http Request in React
        • React Router: Declarative Mode
        • ContextAPI
        • React Router: Framework Mode
          • File-routing & HTML Layouts
          • Server-side Data Query
          • Links & Navigation
          • Loaders
    • PHP
      • gruntJS
      • composer
      • MySQL
      • Thiết lập Cloudflare Turnstile chống spam trong PHP
    • Docker
      • Container Basics
      • Container Networking
      • Container Image
      • Container Volume & Persistent Data
      • Dockerfile
      • Docker Compose
      • Docker Registry
    • Payload CMS

require vs import

Từ Express thuần đến TypeScript
Bạn đang quen tay với Express và Node.js, mỗi ngày viết require như một thói quen. Rồi một ngày bạn mở một project TypeScript, hoặc đọc một tutorial hiện đại, và bắt gặp import express from 'express' — trông gọn hơn, “xịn” hơn, nhưng lại không rõ nó khác gì require không, hay chỉ là cú pháp khác cho cùng một thứ?
Bài viết này sẽ giúp bạn hiểu rõ hai hệ thống module này, cách chuyển đổi tư duy từ CJS sang ESM, và đặc biệt là exports vs export default — thứ hay gây nhầm lẫn nhất khi mới chuyển sang TypeScript.

Hai hệ thống module trong JavaScript

JavaScript có hai hệ thống module hoàn toàn khác nhau:
CommonJS (CJS) — ra đời cùng Node.js, dùng require / module.exports
ES Modules (ESM) — chuẩn hiện đại của JavaScript, dùng import / export
Chúng không phải là “cú pháp khác nhau cho cùng một thứ” — chúng là hai cơ chế khác nhau về cách load và xử lý module.

CommonJS — Người bạn cũ của Express

Nếu bạn đang viết Express, bạn đang dùng CJS:
CJS hoạt động theo kiểu đồng bộrequire() đọc file, thực thi ngay, trả về kết quả. Đơn giản và dễ đoán.

ES Modules — Chuẩn hiện đại

ESM là cú pháp import/export bạn thấy trong TypeScript và các framework hiện đại:
ESM hoạt động theo kiểu bất đồng bộ và được phân tích tĩnh (static analysis) — nghĩa là JavaScript biết bạn import gì trước khi chạy code. Đây là lý do TypeScript yêu thích ESM.

exports vs export: Coi chừng dư chữ “s”

Đây là điểm hay bị nhầm nhất: coi chừng dư chữ “s”. Hãy đối chiếu trực tiếp:

Xuất nhiều thứ (Named Export)

Lưu ý: Với default export, bạn đặt tên gì khi import cũng được. Với named export, tên phải khớp (hoặc dùng as để đổi tên).

Bảng đối chiếu đầy đủ

Hành động
CommonJS
ESM / TypeScript
Import cả module
const x = require('x')
import x from 'x'
Import có chọn lọc
const { a, b } = require('x')
import { a, b } from 'x'
Export một thứ
module.exports = x
export default x
Export nhiều thứ
module.exports = { a, b }
export { a, b }
Export từng cái
exports.a = ...
export const a = ...
Import động
require('./x')
await import('./x')
There are no rows in this table

import trong TypeScript hoạt động thế nào?

Khi bạn viết TypeScript với cấu hình mặc định ("module": "commonjs" trong tsconfig.json):
TypeScript biên dịch xuống thành:
Vậy nên, về runtime, TypeScript vẫn đang dùng CJS — chỉ là bạn được viết cú pháp ESM gọn hơn, và được hưởng lợi từ type checking.
Nếu muốn dùng ESM thật sự với TypeScript, đổi tsconfig.json:
Nhưng với Express API thông thường, "module": "commonjs" là đủ và ít rắc rối hơn.

Một số lưu ý thực tế

✅ Nên làm:
Trong TypeScript, dùng import/export nhất quán — đừng trộn với require
Dùng export default cho thứ chính của file (router, class, function chính)
Dùng named export khi file xuất nhiều thứ ngang hàng nhau (models, utils…)
❌ Tránh:
Quy tắc nhỏ để nhớ:
Mỗi file nên có một phong cách export nhất quán — hoặc default, hoặc named, không nên trộn
File models/index.ts thường dùng named export để re-export nhiều model
File routes/user.ts thường dùng export default vì chỉ xuất một router

Tóm tắt

CommonJS (require/module.exports) là hệ thống module mặc định của Node.js, dùng phổ biến trong Express
ESM (import/export) là chuẩn hiện đại, TypeScript sử dụng cú pháp này
TypeScript mặc định biên dịch import xuống require — nên runtime vẫn là CJS
module.exports = { a, b } tương đương export { a, b } — đều là named export
module.exports = x tương đương export default x — đều là default export
Khi chuyển sang TypeScript, bạn không cần lo lắng quá nhiều về sự khác biệt — cứ dùng cú pháp import/export và TypeScript sẽ lo phần còn lại.
Bước tiếp theo: Khi đã quen với TypeScript, bạn có thể tìm hiểu thêm về path alias (@/models/User thay vì ../../models/User), barrel file (pattern dùng index.ts để re-export), và cách tổ chức module trong một project Express + TypeScript lớn hơn.
Want to print your doc?
This is not the way.
Try clicking the ··· in the right corner or using a keyboard shortcut (
CtrlP
) instead.