前言

webpack打包大多数前端工程师们都已经用过,然后今天我想和大家分享的是webpack如何打包才能输出最优生产环境文件,主要针对两种人群:未自己手把手配置过webpack的人、配置过webpack但是不熟悉或者不知所以然的的人。如果fe大神看到请勿略此文,谢谢!

准备工作

在做讲解之前,我希望大家先去我的github上clone下我的demo项目,然后按照我的讲解亲自code一边!

最基本的打包构建

这是项目目录结构:

ps:先来看下最简单的打包,这边为了模拟打包文件大点,index.js引入了一些用不到的模块,然后webpack只做了最简单的js压缩处理。

//index.js

import React from 'react';

import { render } from 'react-dom';

import { Router, Route, IndexRoute, hashHistory } from 'react-router';

import Redux from 'redux';

import reactRedux from 'react-redux';

import App from './app/App';

import antd from 'antd';

import 'antd/dist/antd.min.css';

import './assets/common.scss';

import './index.scss';

render(, document.getElementById("app"));

//webpack

....

plugins: [

new webpack.optimize.UglifyJsPlugin({

output: {

comments: false

},

compress: {

warnings: false

}

})]

在webpack刚出来的时候,大多数人使用webpack其实和用grunt、gulp一样,把项目中的引用到的模块、样式文件等都打包成一个js文件。这样做的缺点:项目越庞大,打包出来的js文件越大,打包时间越长,最关键的是在单页面应用当中,会很大程度加大首屏加载时间,用户体验不好

上图可以看出打包时间7s左右,一个app.js文件达到352kb。然后这边还不包括antd.min.css(大概400kb antd-ui框架样式),你要想这仅仅是我这边只加了react开发需要用的一些基本模块,业务逻辑和业务css样式基本没有的情况下的数据。实际项目这个数据肯定还要来的大得多。

开始优化

首先我们考虑的是单个文件过大,拆分成多个打包。

css与js分离

把一个超大文件,先按js和css拆分成两个文件,然后页面并行加载这两文件肯定比加载一个文件来的快的,然后文件体积大小肯定也是有所缩小的。

extract-text-webpack-plugin

//webpack

...

plugins: [

new webpack.optimize.UglifyJsPlugin({

output: {

comments: false

},

compress: {

warnings: false

}

}),

new ExtractTextPlugin({

filename:'css/[name].css',

allChunks: true

})

]

打包时间有所缩短,app.js的文件体积也有所缩小。由于我这边业务css和业务逻辑代码基本没有,所以这次优化效果不显著。但是及时这样,app.js还是要比我们心里预计的来的大的多。

公共模块与业务模块分开打包

在实际项目当中,我们引入的模块其实可以分为公共模块与业务模块。

webpack把入口分为两个,一个业务主入口,另一个公共模块打包入口

CommonsChunkPlugin

//webpack

entry:{

vendors:['react',

'redux',

'react-dom',

'react-redux',

'react-router',

'antd/dist/antd.min.css',//ui框架样式也打包进来

PATHS.ASSETS.join('common.scss')],

app:'./index.js'

},

...

plugins: [

new webpack.optimize.UglifyJsPlugin({

output: {

comments: false

},

compress: {

warnings: false

}

}),

new ExtractTextPlugin({

filename:'css/[name].css',

allChunks: true

}),

new webpack.optimize.CommonsChunkPlugin({

name: 'vendors',

filename: 'js/[name].js',

warn:false

}),

]

时间为什么长了呢?其实这个不难理解,因为ui框架(antd)样式也打包进来了。打包成的四个文件:app.js/app.css、vendors.js/vendors.css。app是你业务逻辑代码和业务样式,vendors是你公共引用模块逻辑代码和公共样式。在实际大项目中,这四个文件js部分和css部分一般大小都差不多,所以分成四个文件后并行加载能大大缩减首页文件加载时间!ps:这边由于业务代码基本没有 所以app和vendors文件大小差异过大。

利用插件进一步优化打包文件

通过上面js和css分离,模块划分分离两大步骤,在单页面开发当中基本上你的文件划分定了。在这样的情况下,如果还想减少加载时间,提高体验。在自动化工程这块我们只能在文件体积上做文章了,继续减少文件体积。

optimize-css-assets-webpack-plugin与ModuleConcatenationPlugin

//css压缩

new OptimizeCssAssetsPlugin({

// assetNameRegExp: /.css$/g,

// cssProcessor: require('cssnano'),

cssProcessorOptions: {

discardComments: {

removeAll: true

}

},

canPrint: true

}),

//webpack3.0以上

new webpack.optimize.ModuleConcatenationPlugin(),

由于进一步压缩css和js导致时间打包会有所延长,但是效果还是有的上图可以看出js和css都一定程度缩小了。

衍生问题-打包时间过长怎么办

每次修改业务代码打包都会重新打包公共模块,但是实际情况公共模块打包基本是不会去修改的,那么我么你如果把公共模块打包单独提出来,每次只打包业务模块,这样打包时间是不是会大大缩减?事实上,webpack确实提供了这样的功能-DllPlugin与DllReferencePlugin

DllPlugin与DllReferencePlugin

Dll这个概念应该是借鉴了Windows系统的dll。一个dll包,就是一个纯纯的依赖库,它本身不能运行,是用来给你的app引用的。

打包dll的时候,Webpack会将所有包含的库做一个索引,写在一个manifest文件中,而引用dll的代码(dll user)在打包的时候,只需要读取这个manifest文件,就可以了。

这么一来有几个好处:

Dll打包以后是独立存在的,只要其包含的库没有增减、升级,hash也不会变化,因此线上的dll代码不需要随着版本发布频繁更新。

App部分代码修改后,只需要编译app部分的代码,dll部分,只要包含的库没有增减、升级,就不需要重新打包。这样也大大提高了每次编译的速度。

假设你有多个项目,使用了相同的一些依赖库,它们就可以共用一个dll。

如何使用呢?

首先要先建立一个dll的配置文件,entry只包含第三方库:

//webpack-dll

/*webpack-dll页面配置*/

const path = require('path');

const webpack = require('webpack');

//把css样式从打包文件里面分离出来

const ExtractTextPlugin = require('extract-text-webpack-plugin');

//css压缩

const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');

const PATHS = require('./PATHS');

let dllConfig = {

entry:{

vendors:['react',

'redux',

'react-dom',

'react-redux',

'react-router',

'antd/dist/antd.min.css',

PATHS.ASSETS.join('common.scss')]

},

module:{

rules: [{

test: /\.css$/,

use: ExtractTextPlugin.extract({

fallback: "style-loader",

use: 'css-loader?sourceMap'

})

}, {

test: /\.scss$/,

use: ExtractTextPlugin.extract({

fallback: 'style-loader',

use: ['css-loader?sourceMap', 'sass-loader?sourceMap']

})

}]

},

output:{

path:PATHS.DIST,//打包编译完的文件根目录

filename: "js/[name].js",//打包编译完文件路径和名称

library: '[name]',

},

plugins: [

new ExtractTextPlugin({

filename:'css/[name]-[contenthash:8]-dll.css',

allChunks: true

}),

new OptimizeCssAssetsPlugin({

// assetNameRegExp: /.css$/g,

// cssProcessor: require('cssnano'),

cssProcessorOptions: {

discardComments: {

removeAll: true

}

},

canPrint: true

}),

new webpack.optimize.UglifyJsPlugin({

output: {

comments: false

},

compress: {

warnings: false

}

}),

//webpack3.0以上

new webpack.optimize.ModuleConcatenationPlugin(),

new webpack.DllPlugin({

path: 'manifest.json',

name: '[name]',

context: __dirname,

}),

]

};

module.exports = dllConfig;

webpack.DllPlugin的选项中,path是manifest文件的输出路径;name是dll暴露的对象名,要跟output.library保持一致;context是解析包路径的上下文,这个要跟接下来配置的dll user一致。

运行Webpack,会输出两个文件一个是打包好的vendor.js,一个就是manifest.json,长这样:

{

"name": "vendors",

"content": {

"./node_modules/process/browser.js": {

"id": 0,

"meta": {}

},

"./node_modules/react/index.js": {

"id": 1,

"meta": {}

},

"./node_modules/warning/browser.js": {

"id": 2,

"meta": {}

},

"./node_modules/prop-types/index.js": {

"id": 3,

"meta": {}

},

"./node_modules/invariant/browser.js": {

"id": 4,

"meta": {}

},

"./node_modules/fbjs/lib/emptyFunction.js": {

"id": 5,

"meta": {}

},

"./node_modules/object-assign/index.js": {

"id": 6,

"meta": {}

},

.......

Webpack将每个库都进行了编号索引,之后的dll user可以读取这个文件,直接用id来引用。

Dll user的配置:

const webpack = require('webpack');

module.exports = {

output: {

path: 'build',

filename: '[name].[chunkhash].js',

},

entry: {

app: './src/index.js',

},

plugins: [

new webpack.DllReferencePlugin({

context: __dirname,

manifest: require('./manifest.json'),

}),

],

};

运行Webpack之后,结果如下:

明显速度快了,文件也小了。

平时开发的时候,修改代码后重新编译的速度会大大减少,节省时间。

结尾

其实还有一些优化,高版本的webpack比低版本的webpack打包要快而且文件要小,这属于webpack本身的性能优化带给我们的,例如:

Scope Hoisting-作用域提升 加快减少闭包函数数量从而加快js执行速度

本身打包速度提升 可以自己升级webpack去体验下。

html如何打包文件发送,手把手教你webpack如何打包才能输出最优生产文件相关推荐

  1. 手把手教你用LayaAir打包安卓APK

    LayaAir版本:1.7 jdk版本:jdk-12.0.1_windows-x64_bin 地址链接 PS:我本人是用的最新的jdk版本 sdk版本:24.1.1  地址链接 Android Stu ...

  2. 手把手教你申请计算机软件著作权(2)—— 生成代码文件身份证明

    #今天也是咸鱼的一天~ 上一篇关于软著申请的博客手把手教你申请计算机软件著作权(1)里有说,要求提交一份代码的前三十页和后三十页.在这篇博客里,就详细叙述一下如何提交代码文件. 手把手教你申请软件著作 ...

  3. 手把手教你AndroidStudio多渠道打包

    最近不断有朋友向我咨询AndroidStudio多渠道的打包方法,今天整理一下之前积累的打包套路,写一篇文章,手把手的教给大家.         说到多渠道,这里不得不提一下友盟统计,友盟统计是大家日 ...

  4. ❤️手把手教你做一个爱情保温软件❤️——python封装.exe文件+爬虫(每日情话系列)

    陪伴是最长情的告白 ❤️导读 ❤️可执行文件的准备阶段--爬虫 ❤️源码 ❤️封装成可执行文件 ❤️生成图标 ❤️可能会产生的报错 ❤️我的文件分享 ❤️特别推荐 ❤️导读 何为爱?很多人说在中国爱是 ...

  5. 手把手教你将pyqt程序打包成exe(2)

    手把手教你pyqt程序打包成exe 如果是打包萌新,建议您先看: 上一篇提到打包的环境和打包示例一(没有外部资源依赖的打包): 手把手教你pyqt打包成exe(1) 文章目录 手把手教你pyqt程序打 ...

  6. 手写webpack得打包流程

    目录 搭建一个最基础的环境(用于测试) 本地新建一个文件夹(打包库)webpack-meself 分析webpack环境打包后的js my-pack.js文件书写 手写Compiler.js 解析包, ...

  7. 【新】手把手教你申请计算机软件著作权——新系统填写申请表

    悬崖上的花,越芬芳越无常~ 之前其实是写过了完整的手把手教你申请软著系列的,但是天有不测风云,5月份完成的博客,到了8月底,软著登记的网站系统,居然改版了!!! 所以8.31号之后申请的软著,都需要在 ...

  8. 手把手教你在vue中使用icon图标,附demo代码

    icon图标的使用 START icon图标的使用,对于番茄我来说,算是一个痛点吧.写这篇文章之前,也看了不少别人有关图标使用的博客.想了很久,还是想自己写一篇属于番茄我自己的一篇图标相关的博客.一来 ...

  9. Webpack:打包分析,Preloading, Prefetching

    打包分析概念 当用webpack代码打包之后,可以借助打包分析的工具对打包生成的文件进行一定的分析,分析打包是否合理 分析工具:https://github.com/webpack/analyse 分 ...

最新文章

  1. linux驱动篇之 driver_register 过程分析(一)
  2. NASM、MASM浅谈
  3. 优秀!22岁读博士,26岁当教授,因为太优秀反而没人敢追?
  4. 2019年大数据发展趋势预测
  5. Spring Cloud构建微服务架构:服务容错保护(Hystrix服务降级)【Dalston版】 1
  6. Java:源文件名、公共类名、main()方法之间关系
  7. 北大青鸟java+web_java web ui开发
  8. 函数递归/二分法/列表,字典生成式/三元表达式/匿名函数/内置函数
  9. Javascript 判断浏览器是否为IE的最短方法
  10. 记录一次由于流的read(byte[3 * 1024], 0, len); 读取不足定义的长度,引发的线上bug
  11. 大数据引领医药行业 为时过早
  12. OTDR常见测试曲线​
  13. 【广义S变换】一维广义S变换对非平稳信号处理的matlab仿真
  14. 一线大厂软件测试流程(思维导图)详解
  15. Cesium 影像纠偏
  16. 物理防火墙是什么?有什么作用?
  17. 微型计算机显卡,“智能”显卡 华硕ROG Matrix显卡赏析
  18. html图片加水印元素,使用HTML5 Canvas给图片加水印效果
  19. php投影,投影+直播双模式方案搭建
  20. ENQUEUE_MIGRATED

热门文章

  1. 如何正确汉化/选择模拟人生2 (SIMS2)以及其资料片的语言
  2. 【转】Windows+虚拟机、有线网卡+无线网卡+叠加带宽(图)
  3. 使用Photoshop给黑白照片着色变彩色相片实例教程
  4. 淘淘商城 taotao-image-server
  5. 如何认真的毁掉一个项目?
  6. 小飞兔整站下载如何设置特殊标签?
  7. 获取高质量苹果应用【限免】10月17日 限免应用推荐
  8. ord java_Ord
  9. sketch制作LOGO(一)---环形光晕
  10. LOL英雄联盟.html