通过DllPlugin DllReferencePlugin 实现依赖包分开打包并注入到代码中

前言:

最近在优化项目的时候,发现随着前端项目变得越来越大,导致vendor.js也随之变得很大,虽然用了代码分离和依赖文件按需加载,解决了vendor.js单个文件比较大的问题。 但是每次运行打包都需要很久,这个让人也很痛苦。于是开始研究怎么优化这些结构。首先,项目中有很多依赖文件,webpack每次在打包这些文件是很耗时的,但是这些文件在项目开发过程中是基本上不会变的。 这样每次都打包就显得很浪费。
基础技术框架: vue2.0生成的项目文件结构。webpack@^1.13.2

探索过程:

webpack打包优化。于是就找到了webpack 优化 体积篇, 这篇文章,优质好文。 里面提供了两种方案, 一种是webpack的external配置依赖; 一种就是本文介绍的 DllPlugin&DllReferencePlugin。 前者比较简单,使用起来也很方便。但是不够灵活。 于是作者采用了第二种方案。
第二种方案的好处就是可以按需将多个依赖打包成一个js文件。 在js中还是可以正常引用,同时逼格也稍微高一点, 我承认是因为这一点选择的这个方案。 但是看了文章中的第二个方案后发现。我只能把文件打包成js,并不能很完美的在index.html中引入这个js文件。 这个真的很苦恼, 这么明显掉逼格的方式博主肯定是不会用的。于是开始研究解决方案,首先想到的是html-webpack-plugin, 这个插件是webpack中用作将webpack打包后输出的文件chunks,插入到HTML中的。 但是有两个限制条件:

  1. 我们这里的dll.js 是提前打包好了的,而不是在每次build的时候去打包输出的;这样才能做到依赖包一次构建,无限次使用
  2. vue中webpack输出的文件名都带有hash值; 而用dll构建后输出的文件名是固定的。

博主就想到了一个歪招, 就是在html-webpack-plugin中添加自定义参数,然后再HTML中使用 ejs语法 htmlWebpackPlugin.options.xx来获取参数值,来向HTML中注入script标签。 后来发现在本地开发环境每次启动都会编译失败, 导致script标签插入不进去。本来就已经绝望了,要放弃了。 但是这个时候其实距离最后的成功已经很近了。html-webpack-plugin中HTML 是支持ejs语法的,只是没有从html-webpack-plugin中正确的获取到参数。 只要能够将参数通过webpack的配置传到HTML页面,就大功告成了。
html-webpack-plugin中有句话:webpackConfig: the webpack configuration that was used for this compilation. This can be used, for example, to get the publicPath (webpackConfig.output.publicPath) 就是HTML中可以通过webpackConfig获取到webpack的配置。 哈哈, 这就可以了。[注: 此功能在webpack2.0以上不能使用]

=====================================
一个月后
当博主想要自己做一个插件的时候,发现了这个好用的小工具 add-asset-html-webpack-plugin, 正是博主要实现的功能, 果断使用。 有个小坑, 在附录代码中会说明。
=====================================

下面是主要文件的配置。 有问题欢迎反馈。

操作:

  1. config/index.js 中配置依赖包
modules.exports = {
…. 原始配置
library: {
    'lib_v1_0': ["babel-polyfill", "mqtt"],
    'vueBucket_v1_2': [
      "vue/dist/vue.esm.js",
      "vue-lazyload",
      "vue-resource",
      "vue-router",
      "vuex",
      "vuex-router-sync",
    ]
  }
}
  1. 新建 build/webpack.dll.conf.js
    • 这个文件读取config/index.js 的library 中配置了那些module需要打包
    • dll build 导出manifest.json 文件, 留给 DllReferencePlugin在打包时候识别dll都打包了那些node_module
// webpack.dll.conf.js
const webpack = require('webpack');
const path = require('path')
const CleanWebpackPlugin = require('clean-webpack-plugin');
const {build, dev, library} = require('../config')
const assetsSubDirectory = process.env.NODE_ENV === 'production'
? build.assetsSubDirectory : dev.assetsSubDirectory

module.exports = {
  // 读取library.entry 里配置的node_module
  entry: library,
  // 输出到static文件夹下面, 补充知识[vue项目目录之static]
  output: {
    path: path.resolve(__dirname, '..', assetsSubDirectory),
    filename: `[name].dll.js`,
    library: '[name]_library'
  },
  plugins: [
    new CleanWebpackPlugin(['static'], { root: path.resolve(__dirname, '..')}),
    // 文件输出到 ./build/manifest.json 中
    new webpack.DllPlugin({
        path: path.resolve(__dirname, '..', assetsSubDirectory, '[name].manifest.json'),
        name: '[name]_library',
    }),
    // 压缩打包的文件
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false
      }
    })
  ]
};
  1. 解析dll打包的node_module
// webpack.base.conf.js
var path = require('path')
var config = require('../config')
var webpack = require('webpack')
var AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin');
...

module.exports = {
  ...
  plugins: [
    ...,
    ...Object.keys(config.library).map(name => {
      return new webpack.DllReferencePlugin({
        context: '.',
        manifest: require(`../static/${name}.manifest.json`),
      })
    }),
    new AddAssetHtmlPlugin(Object.keys(config.library).map(name => {
      return {
        filepath: require.resolve(path.resolve(`./static/${name}.dll.js`)),
        includeSourcemap: false
      }
    })),
  ]
}
  1. package.json中配置打包命令
  • 运行命令 npm run build:dll
{
  "scripts": {
    "dev": "node build/dev-server.js",
    "build:dll": "webpack --config build/webpack.dll.conf.js"
  }
}
  1. 项目目录如下


    目录.png

参考知识:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,302评论 5 470
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,232评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,337评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,977评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,920评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,194评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,638评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,319评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,455评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,379评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,426评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,106评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,696评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,786评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,996评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,467评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,043评论 2 341

推荐阅读更多精彩内容

  • GitChat技术杂谈 前言 本文较长,为了节省你的阅读时间,在文前列写作思路如下: 什么是 webpack,它要...
    萧玄辞阅读 12,662评论 7 110
  • 无意中看到zhangwnag大佬分享的webpack教程感觉受益匪浅,特此分享以备自己日后查看,也希望更多的人看到...
    小小字符阅读 8,125评论 7 35
  • 写在开头 先说说为什么要写这篇文章, 最初的原因是组里的小朋友们看了webpack文档后, 表情都是这样的: (摘...
    Lefter阅读 5,266评论 4 31
  • 前言 WebPack 是什么? WebPack 是什么,WebPack 可以看做是模块打包机:它做的事情是,分析你...
    Promise__阅读 1,118评论 3 12
  • 概念 当某个对象触发了某种事件时,所发生的一切详细信息保存在一个临时的地方,这个地方叫做事件对象(黑匣子) 获取事...
    哪树繁花阅读 309评论 0 0