JavaScript笔记之import和require的区别与对比

 更新时间:2026年01月16日 09:07:59   作者:爱睡觉的猫在睡觉  
在JavaScript中,require和import都用于模块导入,这篇文章主要介绍了JavaScript笔记之import和require区别与对比的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下

前言

在 JavaScript 中,importrequire 都用于引入模块,但它们来自不同的模块规范,在语法、加载时机、作用域、生态支持等方面差异很大。

1.模块系统不同

require- CommonJS 规范

// Node.js 最早的模块系统(服务器端)
const fs = require('fs');
const _ = require('lodash');

import- ES6 模块规范

// 浏览器/现代 Node.js 环境
import fs from 'fs';                    // 默认导入
import { readFile } from 'fs';          // 命名导入
import * as fsModule from 'fs';         // 全部导入
规范代表出现背景
CommonJSrequireNode.js 最早的模块系统(服务器端)
ES Module(ESM)importECMAScript 官方标准(浏览器 & Node)

👉 核心结论

require运行时模块加载机制
import编译期模块声明机制

2.加载时机与特性对比

require:运行时加载

const moduleA = require('./a') // 执行到这里才加载

特点:

  • 同步加载
  • 执行顺序 = 代码执行顺序
  • 可条件、可动态

import:编译时加载(静态分析)

import moduleA from './a'

特点:

  • 代码执行前就确定依赖关系
  • 可被 bundler / JS 引擎优化
  • 支持 Tree Shaking

📌 这是 Vite / Rollup / Webpack 能做 Tree Shaking 的根本原因

特性require (CommonJS)import (ES6)
加载时机运行时同步加载编译时静态分析
位置要求可在代码任意位置必须位于模块顶部(除动态导入)
静态分析不支持 Tree Shaking支持 Tree Shaking
异步支持同步加载静态导入同步,动态导入异步
懒加载需配合特定语法原生支持 import() 懒加载

import 只能写在顶层
⛔ 说的是:import x from 'y'

import() 可以写在任何地方
✅ 它是一个返回 Promise 的函数调用

3.懒加载实现方式对比

require的懒加载(Webpack 特定)

// 方式1:require.ensure (Webpack 特定)
const Home = resolve => {
  require.ensure(['./views/Home.vue'], () => {
    resolve(require('./views/Home.vue'));
  });
};

// 方式2:动态 require (Webpack)
const About = () => {
  return new Promise(resolve => {
    require(['./views/About.vue'], resolve);
  });
};

import的懒加载(ES6 标准)

// 标准 ES6 动态导入
const Home = () => import('./views/Home.vue');

// 更复杂的懒加载配置
const UserProfile = () => ({
  component: import('./UserProfile.vue'),
  loading: LoadingComponent,
  delay: 200,
  timeout: 3000
});

4.实际打包效果

require的打包

示例 :require

// main.js
const utils = require('./utils')
utils.a()

打包结果(简化)

function a() {}
function b() {}
const utils = { a, b }
utils.a()

📌 结论

👉 require 整包引入,无法安全删除 b

import的打包

示例 :静态 import

// utils.js
export function a() {}
export function b() {}
// main.js
import { a } from './utils'
a()

打包结果(简化)

function a() {}
// b 被删除(Tree Shaking)
a()

📌 结论

👉 import 能在打包阶段精准删除未使用代码。

5、代码拆包(code splitting)差异

import(动态)

import('./About.vue')

打包结果(Webpack / Vite):

// 主 bundle
function loadAbout() {
  return __loadChunk__('about').then(...)
}
// about.chunk.js(独立)
export default About

📌 天然支持拆包

require(动态)

require('./About.vue')

⚠️ 结果:

  • Webpack:只能整体打包进主 bundle
  • Rollup / Vite:直接报错或不支持

👉 无法可靠拆包

6、运行时代码结构差异(很重要)

require 打包后(CommonJS Runtime)

(function(modules) {
  function __webpack_require__(id) {
    // 同步加载
  }
})(modules)

特点:

  • 同步执行
  • module.exports
  • 需要模拟 CommonJS 环境

import 打包后(ESM Runtime)

Webpack(转换后)

__webpack_require__.d(exports, {
  a: () => a
})

Vite(生产)

import { a } from './chunk.js'

特点:

  • 支持 live binding
  • 更贴近浏览器原生模块
  • 运行时代码更少

Vite 项目里的一个“隐形差异”(很重要)

Vite 的策略

  • 开发环境:原生 ESM(几乎不打包)
  • 生产环境:Rollup 打包

结果:

import { debounce } from 'lodash-es'

👉 只打进 debounce

const _ = require('lodash')

👉 整个 lodash 被打包

包体积 & 性能对比(真实工程影响)

维度importrequire
主包体积更小更大
Tree Shaking
懒加载✅(import())
执行效率更优较差
构建器优化极佳受限

📌 在大型 Vue 项目里,差距可能是 几十 KB ~ 数百 KB

7.现代项目中的使用场景

Node.js 项目

// ES6 模块(Node.js 13+,package.json 中 type: "module")
import express from 'express';
import { createServer } from 'http';

// 或者 CommonJS(传统)
const express = require('express');
const http = require('http');

Vue/React 项目

// Vue Router 懒加载(推荐)
const router = new VueRouter({
  routes: [
    {
      path: '/dashboard',
      component: () => import('./views/Dashboard.vue')  // ES6 import
    }
  ]
});

// React 懒加载
const Dashboard = React.lazy(() => import('./components/Dashboard'));

混合使用(不推荐但可能遇到)

// 在 ES6 模块中导入 CommonJS 模块
import _ from 'lodash';  // lodash 是 CommonJS 模块

// 在 CommonJS 模块中导入 ES6 模块(Node.js)
const fs = require('fs');
const es6Module = await import('./es6-module.mjs');  // 需要异步

// Webpack 环境中可以混合
const oldModule = require('./old-module.js');        // CommonJS
const newModule = import('./new-module.js');         // ES6

8.性能对比

// 测试示例:加载 10 个模块
const modules = ['module1', 'module2', 'module3'];

// require - 同步,阻塞执行
console.time('require');
modules.forEach(name => {
  const module = require(`./${name}.js`);
});
console.timeEnd('require');

// import - 异步,非阻塞
console.time('import');
const promises = modules.map(name => import(`./${name}.js`));
await Promise.all(promises);
console.timeEnd('import');

9.Tree Shaking 差异

import支持静态分析

// 只导入需要的部分,打包时未使用的代码会被移除
import { Button, Input } from 'antd';    // Tree Shaking 生效
import 'antd/dist/antd.css';

// 动态导入也支持 Tree Shaking
const { Modal } = await import('antd');

为什么import能 Tree Shaking?

import { a } from './utils'

构建器在 编译阶段 就知道:

  • 引入了哪个模块
  • 使用了哪个导出
  • 依赖关系是 静态确定的

require不支持 Tree Shaking

// 整个模块都会被加载
const antd = require('antd');  // 整个 antd 包都会被包含
const Button = antd.Button;

为什么require不行?

const mod = require('./' + name)

构建器 无法确定

  • 到底 require 哪个文件
  • require 的返回结构
  • 是否有副作用

👉 只能保守处理:全留

10.总结选择建议

场景推荐使用原因
现代前端项目importES6 标准,支持 Tree Shaking,更好的懒加载
Node.js 新项目import (ES6 模块)官方推荐,更好的异步支持
Node.js 旧项目require保持兼容性
路由懒加载import()语法简洁,标准支持
条件加载import()异步,可配合条件判断
需要同步加载require 或静态 import立即需要模块时

11.最佳实践示例

// 1. 主应用使用静态导入
import Vue from 'vue';
import Router from 'vue-router';

// 2. 路由使用动态导入懒加载
const routes = [
  {
    path: '/',
    component: () => import('./views/Home.vue')
  },
  {
    path: '/about',
    component: () => import('./views/About.vue')
  }
];

// 3. 条件加载(按需加载)
if (user.needsAdminPanel) {
  const AdminPanel = await import('./admin/AdminPanel.vue');
}

// 4. 预加载(提高用户体验)
const preloadModules = [
  import('./views/Products.vue'),   // 预加载可能访问的页面
  import('./views/Contact.vue')
];

核心结论

  • 现代前端开发优先使用 import/export
  • 懒加载使用动态 import()
  • require 主要用于古早 Node.js 传统项目或兼容性需求

总结 

到此这篇关于JavaScript笔记之import和require区别与对比的文章就介绍到这了,更多相关JS import和require区别与对比内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • w3c声明下可运行 兼容性比较好的js对联广告集合

    w3c声明下可运行 兼容性比较好的js对联广告集合

    最近有美工朋友找我们要兼容性比较好的对联广告代码,我们给他一个他竟然不能运行,经过排查,这是因为现在的广告也用了一样代码,函数命名重复。
    2011-07-07
  • 微信小程序如何在页面跳转时进行页面导航

    微信小程序如何在页面跳转时进行页面导航

    小程序能够在不同的页面进行跳转切换,路由起到了至关重要的作用,下面这篇文章主要给大家介绍了关于微信小程序如何在页面跳转时进行页面导航的相关资料,需要的朋友可以参考下
    2022-09-09
  • JavaScript对象创建的七种方式详解

    JavaScript对象创建的七种方式详解

    作为一名前端开发者,JavaScript中对象创建是很重要,在JavaScript这门基于原型的语言中,对象几乎无处不在,本文我将带领大家回顾JavaScript对象创建的7种方式,需要的朋友可以参考下
    2025-09-09
  • js实现ajax的用户简单登入功能

    js实现ajax的用户简单登入功能

    这篇文章主要为大家详细介绍了js实现ajax的用户简单登入功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-06-06
  • JS+CSS实现可拖拽的漂亮圆角特效弹出层完整实例

    JS+CSS实现可拖拽的漂亮圆角特效弹出层完整实例

    这篇文章主要介绍了JS+CSS实现可拖拽的漂亮圆角特效弹出层,以完整实例形式分析了弹出层特效及圆角矩形的实现技巧,需要的朋友可以参考下
    2015-02-02
  • 学习RxJS之JavaScript框架Cycle.js

    学习RxJS之JavaScript框架Cycle.js

    这篇文章主要介绍了学习RxJS之JavaScript框架Cycle.js ,它是一个极简的JavaScript框架(核心部分加上注释125行),提供了一种函数式,响应式的人机交互接口,需要的朋友可以参考下
    2019-06-06
  • js 创建快捷方式的代码(fso)

    js 创建快捷方式的代码(fso)

    js 创建快捷方式的代码,这个是在本地运行的需要确认的,需要的朋友可以参考下。
    2010-11-11
  • 如何用原生JavaScript实现输入验证的界面

    如何用原生JavaScript实现输入验证的界面

    在开发Web应用时,表单验证是一个必不可少的功能,能够帮助我们确保用户输入的数据是有效的,这篇文章主要介绍了如何用原生JavaScript实现输入验证界面的相关资料,需要的朋友可以参考下
    2025-11-11
  • 原生JS控制多个滚动条同步跟随滚动效果

    原生JS控制多个滚动条同步跟随滚动效果

    本文要探讨的是,当这两个容器元素的内容都超出了容器高度,即都出现了滚动框的时候,如何在其中一个容器元素滚动时,让另外一个元素也随之滚动
    2017-12-12
  • 小程序实现抽奖动画

    小程序实现抽奖动画

    这篇文章主要为大家详细介绍了小程序实现抽奖动画,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-12-12

最新评论