Deno's module system adopts a decentralized design, significantly different from Node.js's npm ecosystem. Understanding Deno's module import mechanism is crucial for efficient development.
Module Import Methods
1. URL Imports
Deno uses URLs to directly import modules, which is its most prominent feature:
typescript// Import from Deno standard library import { serve } from "https://deno.land/std@0.208.0/http/server.ts"; // Import from third-party libraries import { oak } from "https://deno.land/x/oak@v12.6.1/mod.ts"; // Import from GitHub import { myLib } from "https://raw.githubusercontent.com/user/repo/main/mod.ts";
2. Local File Imports
typescript// Relative path imports import { utils } from "./utils.ts"; import { helper } from "../helper/helper.ts"; // Absolute path imports import { config } from "/app/config.ts";
3. Import Maps
Use import_map.json to manage module aliases:
json{ "imports": { "std/": "https://deno.land/std@0.208.0/", "oak": "https://deno.land/x/oak@v12.6.1/mod.ts", "@utils/": "./src/utils/" } }
Usage:
typescriptimport { serve } from "std/http/server.ts"; import { Application } from "oak"; import { formatDate } from "@utils/date.ts";
Specify import map when running:
bashdeno run --import-map=import_map.json app.ts
Version Management
1. Version Locking
Deno recommends specifying specific versions in URLs:
typescript// Recommended: specify version import { serve } from "https://deno.land/std@0.208.0/http/server.ts"; // Not recommended: use latest version (may be unstable) import { serve } from "https://deno.land/std/http/server.ts";
2. Dependency Caching
Deno caches all downloaded modules:
bash# View cache location deno info # Re-download dependencies deno cache --reload app.ts # Clear cache deno cache --reload all
Module Exports
1. Named Exports
typescript// utils.ts export const add = (a: number, b: number): number => a + b; export const subtract = (a: number, b: number): number => a - b; export interface User { id: number; name: string; }
2. Default Exports
typescript// app.ts export default class Application { start() { console.log("Application started"); } }
3. Re-exports
typescript// index.ts export * from "./utils.ts"; export { default as App } from "./app.ts"; export type { User } from "./types.ts";
Permission Requirements
When importing remote modules, Deno requires network permissions:
bash# Allow network access to download modules deno run --allow-net app.ts # Allow reading cache deno run --allow-read app.ts
Comparison with Node.js
| Feature | Deno | Node.js |
|---|---|---|
| Import Method | URL imports | npm package names |
| Dependency Management | No package.json | package.json + node_modules |
| Version Control | Version number in URL | Version ranges in package.json |
| Module Resolution | Direct URL | node_modules lookup algorithm |
| Caching Mechanism | Global cache | Local node_modules |
| Type Support | Native TypeScript | Requires @types packages |
Best Practices
- Always specify versions: Use explicit version numbers in URLs
- Use Import Maps: Simplify module path management
- Dependency locking: Consider using
deno.lockfile - Minimize permissions: Only grant necessary permissions
- Cache management: Regularly clean and update cache
Practical Example
Create a simple web server:
typescript// server.ts import { serve } from "https://deno.land/std@0.208.0/http/server.ts"; const handler = async (req: Request): Promise<Response> => { const url = new URL(req.url); if (url.pathname === "/") { return new Response("Hello, Deno!", { headers: { "content-type": "text/plain" }, }); } return new Response("Not Found", { status: 404 }); }; await serve(handler, { port: 8000 });
Run:
bashdeno run --allow-net server.ts
Deno's module system provides a simpler, more direct approach to dependency management, eliminating the complexity of node_modules while maintaining excellent type support and development experience.