在多个文件中import同一个文件,webpack会多次打包吗

13

最近自己在练习写React,Vue的时候,会在不同的子组件中多次import同一个文件,例如:import React from 'react'import Vue from 'vue',引入的次数多了慢慢让我产生了疑惑,引入这么多次,webpack会多次打包吗?直觉告诉我webpack并不傻,不会愚蠢的打包多次使打包后的文件异常臃肿,如果不会的话为什么不会呢?怀着好奇心在谷歌搜索很久也没有找到让我信服的的答案,于是我自己做了个实验(源码),来证明自己的猜想:

1.模拟react/vue环境

第一步是安装相关webpack、babel等相关依赖以及建好目录
webpack设置:

//webpack.config.js
module.exports = {
  entry: './app.js',
  output: {
    filename: 'bundle.js'
  },
  module: {
    loaders:[
      {
        test: /\.js[x]?$/,
        exclude: /node_modules/,
        loader: 'babel-loader?presets[]=es2015&presets[]=react'
      },
    ]
  }
}

package.json所需依赖:

//package.json
{
  "name": "test",
  "version": "0.0.1",
  "devDependencies": {
    "webpack": "^1.14.0"
  },
  "dependencies": {
    "babel-core": "^6.21.0",
    "babel-loader": "^6.2.10",
    "babel-preset-es2015": "^6.18.0",
    "babel-preset-react": "^6.16.0"
  }
}

其他用于测试的文件:

//demo.js--相当于vue
export default {
  test(argu) {
    console.log(argu)
  }
}

//test1.js --相当于某个组件

import demo from './demo'

export default {
  test1() {
    demo.test(1)
  }
}

//test2.js --相当于另一个组件
import demo from './demo'

export default {
  test1() {
    demo.test(2)
  }
}

//add.js --入口文件

import Test1 from './test1'
import Test2 from './test2'

Test1.test1()
Test2.test2()

我在 test1.js, test2.js中都引入demo.js,并且exoprt 出依赖demo.js的方法,然后再在app.js中引入 test1.js, test2.js webpack打包后打开bundle.js,找到demo部分。demo部分
我们发现在bundle.js中引入的文件都被分成了带有序号(num)的“代码片”,通过__webpack_require__(num)来引入对应的模块,而我们import两次用来测试的demo.js也只是被打包成了序号为2的代码块,由此我们可以推论出:

不同文件中多次import同一个文件,webpack并不会多次打包,只会在打包后的文件中会多次引用打包后的该文件对应的函数。

问题终于搞清楚了,很舒服!!👻

你可能感兴趣的

13 条评论
JeremyChen · 2017-04-01

不错不错

回复

mavis_0211 · 2017-06-06

很棒,本来想推荐的,但声望值不够,不让推荐

回复

流畅的心情 · 2017-07-17

谢谢分享。

回复

水剑承王 · 2017-07-25

这里还有另一个问题

我们在不同的文件中都引用了同一个模块(比如 import React from 'react')
而且我们知道, import 语句会执行一遍它引用的模块
这样的话,react 这个模块岂不是在不同的 component 文件中被执行了很多次?
react 代码那么多,这样多次执行对性能是否会有影响?
或者根本是只执行一次,后面都去缓存中取值?

求解答,谢谢!

回复

0

你的问题有点意思 这里面的原理我暂时没有研究过 但是根据你的问题我直接在demo.js(类似 react) 中 console.log() 试了一下 最终的结果也是只log 了一次 不知道解决你的问题了没有 况且像react 这类框架它本身并不执行代码 export的只是它封装好的对象而已~~

zegendary 作者 · 2017-07-25
0

感谢回答。
我刚才也在 React.js 的源码中加了 console.log() 测试。
确实只会打印一次,所以也只执行了一次。

水剑承王 · 2017-07-26
老咸鱼 · 2017-08-02

?不错

回复

LOXun · 2018-01-31

项目中使用了一个公共接口文件,我import进来几个需要的就扣但是打包把他们全部打包进来了,每个文件都有,我在entry 里边把这个文件专门设置输出为一个common.js,打包后调用接口确实用的是common.js,但是每个文件还是把这个公共文件你加载进来了,不知道为什么

回复

0

你好 遇到同样的问题 怎么解决的。

崔大迪 · 2018-08-16
0

@崔大迪 我也碰到过,自定义的组件被重复打包,使项目体积成倍增大。后来把这些组件定义在全局上解决了。

tombear · 3月5日
江伟 · 2018-05-02

大话西游:我们早就想这么做了!。。点赞👍666

回复

xuangu · 2018-05-15

工程打包后的报告显示,在生成的不同的js内,webpack重复多次打包了同一个文件,所以是配置问题导致的重复么,不太明白

回复

Refrain · 2018-08-01

比如我在多个组件里都import同一个js 引入的那个js又import了另外的第三方库 vue里面路由又用了路由懒加载 后来webpacket打包出来了每个chunk 里面都包含了import的那个js里面的第三方库 有遇到这样的情况吗

回复

载入中...