Node.js模块化与npm

目录

一、模块化简介

[二、CommonJS 规范](#二、CommonJS 规范)

[1. 基本语法](#1. 基本语法)

[2. 导出模块](#2. 导出模块)

[3. 导入模块](#3. 导入模块)

[三、ECMAScript 标准(ESM)](#三、ECMAScript 标准(ESM))

[1. 启用 ESM](#1. 启用 ESM)

一、默认导出与导入

[1. 基本语法](#1. 基本语法)

[2. 默认导出(每个模块仅一个)](#2. 默认导出(每个模块仅一个))

[3. 默认导入](#3. 默认导入)

二、命名导出与导入

1.基本语法

[2. 命名导出(支持多个)](#2. 命名导出(支持多个))

[3. 命名导入](#3. 命名导入)

三、混合导出与导入

[四、CommonJS 与 ESM 对比](#四、CommonJS 与 ESM 对比)

五、互操作性

六、最佳实践

七、npm详解

[1. 包的概念](#1. 包的概念)

[2. npm软件包管理器](#2. npm软件包管理器)

[3. npm常用命令](#3. npm常用命令)

4.npm安装所有依赖

5.npm全局软件包


一、模块化简介

在 Node.js 中每个文件都被当做是一个独立的模块,模块内定义的变量和函数都是独立作用域的,因为 Node.js 在执行模块代码时,将使用如下所示的函数封装器对其进行封装:

而且项目是由多个模块组成的,每个模块之间相互独立,按需加载,独立作用域。

但是因为模块内的属性和函数都是私有的,如果对外使用,需要使用标准语法导出和导入才可以,而这个标准叫 CommonJS 标准。

Node.js 支持的模块化标准:

  1. CommonJS 标准语法(默认)
  2. ECMAScript 标准语法

二、CommonJS 规范

1. 基本语法

  1. 导出语法:

    javascript 复制代码
    module.exports = {
      对外属性名: 模块内私有变量
    }
  2. 导入语法:

    javascript 复制代码
    const 变量名 = require('模块名或路径')
  • 内置模块:写名字,例如:fs,path,http
  • 自定义模块:写模块文件路径,例如:./utils.js
  • 变量名的值接收的就是目标模块导出的对象

2. 导出模块

  • 方式一:module.exports

    直接赋值一个对象、函数或值,作为模块的唯一导出

    javascript 复制代码
    // math.js
    const add = (a, b) => a + b;
    module.exports = { add, subtract: (a, b) => a - b };
  • 方式二:exports 对象

    exports 对象添加属性,支持多属性导出 (本质是 module.exports 的引用)。

    javascript 复制代码
    // math.js
    exports.add = (a, b) => a + b;
    exports.subtract = (a, b) => a - b;

3. 导入模块

使用 require() 函数,返回 module.exports 的值。

  • 方式一:导入整个模块

    javascript 复制代码
    const math = require('./math.js');
    console.log(math.add(2, 3)); // 5
  • 方式二:解构导入(适用于多属性导出)

    javascript 复制代码
    const { add, subtract } = require('./math.js');
    console.log(add(2, 3)); // 5

三、ECMAScript 标准(ESM)

1. 启用 ESM

  • 方式一 :文件扩展名为 .mjs

  • 方式二 :在 package.json 中设置 "type": "module",所有 .js 文件默认按 ESM 解析。


一、默认导出与导入

1. 基本语法

  1. 导出语法:

    javascript 复制代码
    export default {
      对外属性名: 模块内私有变量
    }
  2. 导入语法:

    javascript 复制代码
    import 变量名 from '模块名或路径'
  • 变量名的值接收的就是目标模块导出的对象

2. 默认导出(每个模块仅一个)

javascript 复制代码
// utils.js
const log = (message) => console.log(message);
export default { log };  // 导出默认函数

3. 默认导入

javascript 复制代码
import utils from './utils.js';
utils.log('Hello');  // 使用默认导出的内容

二、命名导出与导入

1.基本语法

  1. 导出语法:

    javascript 复制代码
    export 修饰定义语句
  2. 导入语法:

    javascript 复制代码
    import { 同名变量 } from '模块名或路径'
  • 同名变量指的是模块内导出的变量名

2. 命名导出(支持多个)

  • 方式一:单个导出

    javascript 复制代码
    export const PI = 3.14;
    export const MAX_SIZE = 100;
  • 方式二:集中导出

    javascript 复制代码
    const PI = 3.14;
    const MAX_SIZE = 100;
    export { PI, MAX_SIZE };

3. 命名导入

  • 方式一:直接导入

    javascript 复制代码
    import { PI, MAX_SIZE } from './constants.js';
    console.log(PI); // 3.14
  • 方式二:重命名导入

    javascript 复制代码
    import { PI as圆周率 } from './constants.js';
  • 方式三:导入全部命名导出为对象

    javascript 复制代码
    import * as constants from './constants.js';
    console.log(constants.MAX_SIZE); // 100

三、混合导出与导入

  • 同时导出默认和命名

    javascript 复制代码
    // config.js
    export const API_KEY = '123';
    export default { env: 'production' };
  • 混合导入

    javascript 复制代码
    import config, { API_KEY } from './config.js';
    console.log(config.env, API_KEY); // 'production' '123'

四、CommonJS 与 ESM 对比

特性 CommonJS ECMAScript (ESM)
语法 module.exportsrequire() export/import 关键字
加载方式 动态加载(运行时解析) 静态加载(编译时解析)
文件扩展名 .js(默认) .mjs.js(需 "type": "module"
顶层 this 指向 module.exports undefined
循环依赖处理 支持,但需谨慎设计 支持,行为更可预测
浏览器兼容性 需打包工具(如 Webpack) 原生支持(现代浏览器)

五、互操作性

  • ESM 导入 CommonJS 模块

    javascript 复制代码
    // ESM 文件
    import cjsModule from './commonjs-module.js';  
    // 默认导入对应 CommonJS 的 module.exports
  • CommonJS 导入 ESM 模块
    仅支持异步 import() 函数(Node.js 14+):

    javascript 复制代码
    // CommonJS 文件
    async function loadESM() {
      const esmModule = await import('./esm-module.mjs');
      console.log(esmModule.default);
    }

六、最佳实践

  1. 统一模块规范

    • 新项目优先使用 ESM(趋势和标准)。

    • 旧项目逐步迁移,避免混用导致复杂性。

  2. 路径与扩展名

    • ESM 中导入路径需写完整(如 './file.js')。

    • CommonJS 可省略 .js

  3. 默认导出命名

    • ESM 默认导出建议使用有意义的名称(如 import axios from 'axios')。
  4. 工具链支持

    • 使用 Babel、Webpack 处理模块兼容性(旧环境或混合项目)。

七、npm详解

npm(Node Package Manager) 是 Node.js 的默认包管理工具,也是全球最大的开源软件注册中心。它用于依赖管理、脚本执行、包发布等,是 Node.js 生态系统的核心工具。


1. 包的概念

  1. :将模块,代码,其他资料整合成一个文件夹,这个文件夹就叫包

  2. 包分类

    1. 项目包:主要用于编写项目和业务逻辑

    2. 软件包:封装工具和方法进行使用

  3. 包要求:根目录中,必须有 package.json 文件(记录包的清单信息)

  4. 包使用:引入一个包文件夹到代码中时,默认引入的是包文件节下的 index.js 模块文件里导出的对象,如果没有 index.js 文件,则会引入 package.json 里 main 属性指定的文件模块导出的对象

小结:

  1. 什么是包?
  • 将模块,代码,其他资料聚合成的文件夹
  1. 包分为哪 2 类呢?
  • 项目包:编写项目代码的文件夹,软件包:封装工具和方法供开发者使用
  1. package.json 文件的作用?
  • 记录软件包的名字,作者,入口文件等信息
  1. 导入一个包文件夹的时候,导入的是哪个文件?
  • 默认 index.js 文件,或者 main 属性指定的文件

**2.**npm软件包管理器

  1. npm 使用步骤:

    1. 初始化清单文件: npm init -y (得到 package.json 文件,有则跳过此命令)

      注意 -y 就是所有选项用默认值,所在文件夹不要有中文/特殊符号,建议英文和数字组成,因为 npm 包名限制建议用英文和数字或者下划线中划线

    2. 下载软件包:npm i 软件包名称

    3. 使用软件包

  2. 下载的包会存放在哪里?

  • 当前项目下的 node_modules 中,并记录在 package.json 中

3. npm常用命令

命令 作用
npm init 初始化项目并生成 package.json
npm install <package> 安装包(默认添加到 dependencies
npm install <package> --save-dev 安装包到 devDependencies
npm install -g <package> 全局安装(如 CLI 工具)
npm uninstall <package> 卸载包
npm update <package> 更新指定包
npm audit 检查依赖安全漏洞
npm publish 发布包到 npm 仓库
npm login 登录 npm 账号
npm ci 根据 package-lock.json 安装依赖
npm outdated 检查过时的依赖

**4.**npm安装所有依赖

  • 我们拿到了一个别人编写的项目,但是没有 node_modules,项目能否正确运行?

    不能,因为缺少了项目需要的依赖软件包,比如要使用 dayjs 和 lodash,但你项目里没有这个对应的源码,项目会报错

  • 为何没有给我 node_modules?

    因为每个人在自己的本机使用 npm 下载,要比磁盘间传递要快(npm 有缓存在本机)

  • 如何得到需要的所有依赖软件包呢?

    直接在项目目录下,运行终端命令:npm i 即可安装 package.json 里记录的所有包和对应版本到本项目中的 node_modules

小结:

  1. 当前项目中只有 package.json 没有 node_modules 怎么办?
  • 当前项目目录下,打开终端,执行 npm i 安装所有依赖软件包
  1. 为什么 node_modules 不进行传递?
  • 因为用 npm 下载有缓存在本机,比磁盘之间传递要快

5.npm全局软件包

  1. 软件包区别:

    • 本地软件包:当前项目内使用,封装属性和方法,存在于 node_modules

    • 全局软件包:本机所有项目使用,封装命令和工具,存在于系统设置的位置

  2. **nodemon 作用:**替代 node 命令,检测代码更改,自动重启程序

  3. 使用:

    1. 安装:npm i nodemon -g (-g 代表安装到全局环境中)

    2. 运行:nodemon 待执行的目标 js 文件


相关推荐
寅时码4 小时前
从“一键部署”到“可观测、可定制的发布流”:我如何打造一个企业级部署工具
运维·开源·node.js
这是个栗子4 小时前
【Node.js安装注意事项】-安装路径不能有空格
前端·npm·node.js
chancygcx_5 小时前
前端核心技术Node.js(二)——path模块、HTTP与模块化
前端·http·node.js
丘色果5 小时前
NPM打包时,报reason: getaddrinfo ENOTFOUND registry.nlark.com
前端·npm·node.js
自学也学好编程8 小时前
【BUG】nvm无法安装低版本Node.js:The system cannot find the file specified解决方案
node.js·bug
牧码岛8 小时前
服务端之nestJS常用异常类及封装自定义响应模块
node.js·nestjs
奕辰杰13 小时前
关于npm前端项目编译时栈溢出 Maximum call stack size exceeded的处理方案
前端·npm·node.js
yzzzzzzzzzzzzzzzzz1 天前
node.js之Koa框架
node.js
Java陈序员1 天前
轻松设计 Logo!一款 Pornhub 风格的 Logo 在线生成器!
vue.js·node.js·vite
gongzemin1 天前
使用Node.js开发微信第三方平台后台
微信小程序·node.js·express