基础篇 - 从构建层面看 import 和 require 的区别

1,600 阅读4分钟

前言

一切的一切,都是因为群里的一个问题

image.png

虽然说最近在做 webpack 相关的事情,但是也没有对着干问题做过相关的研究,网上很多文章包括 vue 都介绍了建议使用 import ,但是没有说为什么要使用 import,对于开发者来说,调用的方式是没有区别的,那么为什么 import 的包就要比 require 的包小呢

这里暂时就不说什么调用方式了,什么动态加载(require)、静态编译(import)的,这个网上都有,这篇文章就是分析一下为什么要用 import,而不用 require

正文

首先本地先基于 webpack 搭建一个环境只是为了测试,不需要搭建太复杂的内容

基础文件内容

// webpack.config.js
module.exports = {
  mode: 'development',
  entry: './src/index.js'
}

index.js 内添加两种调用方式

function test() {
  const { b } = import('./importtest')
  console.log(b()) 
}
test()

// or

function test() {
  const { b } = require('./requiretest')
  console.log(b()) 
}
test()

importtest.js 中也是简单输出一下

// importtest.js
export default {
  b: function () {
    return {
      name: 'zhangsan'
    }
  }
}

requiretest.js 也是如此

// requiretest.js
module.exports = {
  b: function() {
    return {
      name: 'lisi'
    }
  }
}

上述的方式分别执行 webpack 后,输出的内容分别如下

import 输出

image.png

在打包时一共输出了两个文件:main.jssrc_importtest_js.jsmain.js 里面输出的内容如下

image.png

main.js 里面就是 index.js 里面的内容,importtest 里面的内容,是通过一个索引的方式引用过来的,引用的地址就是 src_importtest_js.js

require 输出

image.png

require 打包时,直接输出了一个文件,就只有一个 main.jsmain.js 里面输出的内容如下

image.png

main.js 里面的内容是 index.jsrequiretest.js 里面的所有内容

综上所述,我们从数据角度来看 import 的包是要大于 require 的,但通过打包文件来看,由业务代码导致的文件大小其实 import 是要小于 require

多引用情况下导致的打包变化

这个时候我们大概知道了 importrequire 打包的区别,接下来我们可以模拟一下一开始那位同学的问题,直接修改一下 webpack.config.js 的入口即可

module.exports = {
  mode: 'development',
  entry: {
    index: './src/index.js',
    index1: './src/index1.js'
  }
}

这里直接保证 index.jsindex1.js 的内容一样即可,还是先测试一下 import 的打包

image.png

这里的内容和单入口时打包的 import 基本一致,里面出了本身的内容外,都是引用的 src_importtest_js 的地址,那么在看看 require 的包

image.png

这里内容和单入口打包的 require 基本一致,都是把 requiretest 的内容复制到了对应的文件内

虽然我们现在看的感觉多入口打包,还是 import 的文件要比 require 的文件大,但是核心问题在于测试案例的业务代码量比较少,所以看起来感觉 import 要比 require 大,当我们的业务代码量达到实际标准的时候,区别就看出来了

总结

import: 打包的内容是给到一个路径,通过该路径来访问对应的内容

require: 把当前访问资源的内容,打包到当前的文件内

到这里就可以解释为什么 vue 官方和网上的文章说推荐 import 而不推荐 require,因为每一个使用 require 的文件会把当前 require 的内容打包到当前文件内,所以导致了文件的过大,使用 import,抛出来的是一个索引,所以不会导致重复内容的打包,就不会出现包大的情况

当然这也不是绝对的,就好像上述案例那种少量的业务代码,使用 import 的代码量其实要比 require 大,所以不建议大家直接去确定某一种方式是最好的,某一种方式就是不行的,依场景选择方法

尾声

这篇文章就是一个简单的平时技术方面基础研究的简介,不是特别高深的东西,还希望对大家有所帮助,如果有覆盖面不够,或者场景不全面的情况,还希望大家提出,我在继续补充

这种类型的文章不是我擅长的方向,还是喜欢研究一些新的东西,欢迎大家指教:

实战篇 - 如何把性能优化的颗粒度做的更细

思想篇 - 通过 hooks 的出现,反思组件化开发存在的问题

范式篇 - 如何把函数式编程合理运用到日常工作中