webpack build后生成的app、vendor、manifest三者有何职能不同?

第一次build后生成正式环境文件,然后发现js文件竟然生成了app.jsvendor.jsmanifest.js

问:想请问下这三者在功能上有何侧着、不同吗?另外还有没有再精简、优化的空间图片描述

阅读 13.5k
评论 2017-05-03 提问
    2 个回答
    Dont
    • 6.8k

    题主,你可以通过build设置先不做压缩,看看里面的代码长啥样。

    你标签写着vue,从我接触过的vue demo来说吧。 首先一个vue项目,肯定要用到vue的,其次是这个项目页面的js,也就是怎么实例化vue并写出业务来。

    如果是传统的jquery开发模式,一个页面至少也是要包含两个js,一个是jquery的,一个是页面业务的。

    回到app,vendor,manifest这三者,贴一下之前vue脚手架的webpack配置

    new webpack.optimize.CommonsChunkPlugin({
          name: 'vendor',
          minChunks: function (module, count) {
            // any required modules inside node_modules are extracted to vendor
            return (
              module.resource &&
              /\.js$/.test(module.resource) &&
              module.resource.indexOf(
                path.join(__dirname, '../node_modules')
              ) === 0
            )
          }
        }),
        // extract webpack runtime and module manifest to its own file in order to
        // prevent vendor hash from being updated whenever app bundle is updated
        new webpack.optimize.CommonsChunkPlugin({
          name: 'manifest',
          chunks: ['vendor']
        })

    app.js是入口js,vendor则是通过提取公共模块插件来提取的代码块(webpack本身带的模块化代码部分),而manifest则是在vendor的基础上,再抽取出要经常变动的部分,比如关于异步加载js模块部分的内容。

    从截图上看也看出,vendor的文件大小最大,因为其包含了vue整一个框架的代码,以及webpack的模块化代码。

    至于manifest的话,主要是一些异步加载的实现方法(通过建立script方式动态引入js),内容上包含异步js的文件名和路径。

    之前查过一些资料,主要是js的改动会改变异步加载里面的js文件名,频繁的变动,而相对来说vue库之类的代码,实际上只要编译打包一次就够了,如果只是打包成一个vendor的话,经常变动js会导致vendor重复编译,有点浪费,所以把会重复跟随变动的部分抽离出来作为manifest文件。

    这是我的个人理解,有问题请指正哈

    评论 赞赏
      uihoh0
      • 588

      @Dont 说的大部分都对,有几个点觉得要改改:1,CommonsChunkPlugin 抽取的是公共部分而不是"经常变动的部分";2,观察了一下,webpack应该是会在最后一个CommonsChunkPlugin产出的chunk注入webpackJsonp的定义,以及异步加载相关的定义,而就是这个会涉及到所有entry及chunk的md5,所以会"经常变动",同时vue-cli默认的vendor是打包node_module下的所有依赖,会很大,在生产环境,过大的文件要尽量利用缓存来加快载入速度,但“经常变动”不利于缓存,所以为了将entry(这里可认为是app.js)的变动隔离在vendor之外,vue-cli在vendor之后多做了一个manifest的chunk,这样entry只要不引入新的node_modules里的包就不会影响到vendor了.ps:所以其实跟编译次数没什么关系,所有文件每次打包都会再编译一次的,重点是大文件,缓存,变动代码的拆分.

      以下说明仅依照vue-cli全家桶默认配置解读,如有错误,请指出:
      app.js:基本就是你实际编写的那个app.vue(.vue或.js?),没这个页面跑不起来.
      vendor.js:vue-cli全家桶默认配置里面这个chunk就是将所有从node_modules/里require(import)的依赖都打包到这里,所以这个就是所有node_modules/下的被require(import)的js文件
      manifest.js: 最后一个chunk,被注入了webpackJsonp的定义及异步加载相关的定义(webpack调用CommonsChunkPlugin处理后模块管理的核心,因为是核心,所以要第一个进行加载,不然会报错).

      精简:由于默认的vendor的打包策略导致这个chunk很大,按照默认配置这基本没什么好精简了,要精简的话基本要针对项目实际来修改各个chunk的打包策略(尽量减少包的大小来提速首屏加载)

      优化:单页面基本就跟精简同个道理吧,多页面的话感觉还是自定义一下vendor的打包策略,毕竟不一定所有页面都会用到全量的第三方依赖,适当减少vendor的体积能提高不少加载速度.

      评论 赞赏
        撰写回答

        登录后参与交流、获取后续更新提醒