React技术栈之Webpack环境搭建(三)打包性能优化

前端之家收集整理的这篇文章主要介绍了React技术栈之Webpack环境搭建(三)打包性能优化前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

React技术栈之Webpack环境搭建(一)手动搭建
React技术栈之Webpack环境搭建(二)不同环境不同配置
React技术栈之Webpack环境搭建(三)打包性能优化


实际项目,动辄上千个模块,打包花1分钟以上是很常见的。我们构建的时候,往往希望自己的代码和第三方库(vendors)可以分开打包,因为不涉及到升级第三方库时,就没必要每次浪费打包时间在这上面。

Dll(动态链接库)是Webpack后面加入的功能,Dll这个概念应该是借鉴了Windows系统的dll。一个dll包,就是一个纯粹的依赖库,它本身不能运行,是用来给你的app引用的。

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

这么一来有几个好处:

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

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

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

如何使用呢?

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

const path = require('path')
const webpack = require('webpack')

const ROOT_PATH = path.resolve(__dirname);

const vendors = [
  'react','react-dom','react-redux','react-router','react-router-redux','redux','redux-actions','antd','moment',];

module.exports = {
  entry: {
    vendor: vendors
  },output: {
    path: path.resolve(__dirname,'lib'),filename: '[name].dll.js',library: '[name]_lib',},plugins: [
    new webpack.DllPlugin({
      path: path.resolve(ROOT_PATH,'lib','manifest.json'),name: '[name]_lib',context: ROOT_PATH,}),],}

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

修改package.json,增加dll命令:

"scripts": {
    "dll": "rimraf ./lib && webpack --config webpack.dll.config.js","start": "webpack-dev-server --hot --progress --config webpack.dev.config.js","build:dev": "rimraf build && webpack --progress --config webpack.dev.config.js","build:test": "rimraf build && webpack --progress --config webpack.test.config.js","build:prod": "rimraf build && webpack --progress --config webpack.prod.config.js"
  },

执行命令,生成第三方依赖dll库:

npm run dll

可以看到lib目录下生成了两个文件

修改webpack.base.config.js配置,增加DllReferencePlugin插件配置:

plugins: [
    new webpack.DllReferencePlugin({
        manifest: require(path.resolve(ROOT_PATH,'manifest.json')),})
]

这么一来,已做成dll库的那部分模块,webpack将不会重复打包。
DllReferencePlugin的选项中,context需要跟之前保持一致,这个用来指导Webpack匹配manifest中库的路径;manifest用来引入刚才输出的manifest文件

最后修改一下模板index.html,增加引用vendor.dll.js文件

<!DOCTYPE html>
<html lang="en">
<head>
  <Meta charset="UTF-8">
  <Meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
  <div id="root"></div>
  <script type="text/javascript" src="../lib/vendor.dll.js"></script>
</body>
</html>

给入口文件再加点依赖模块,方便打包观察:

import React from 'react';
import ReactDOM from 'react-dom';
import { DatePicker } from 'antd';
import moment from 'moment';
import 'moment/locale/zh-cn';

moment.locale('zh-cn');

function Index() {
    return (
      <div className="container">
        <h1>Antd DatePicker!</h1>
        <DatePicker defaultValue={moment('2015-01-01','YYYY-MM-DD')} />
      </div>
    );
}

ReactDOM.render(<Index />,document.getElementById('root'));

export default Index;

运行打包:

npm run build:dev

可以看到,入口文件里依赖的react,moment模块,直接引用了dll。

对比一下不做分离的情况下打包的结果:

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

代码https://github.com/zhutx/reac...


React技术栈之Webpack环境搭建(一)手动搭建
React技术栈之Webpack环境搭建(二)不同环境不同配置React技术栈之Webpack环境搭建(三)打包性能优化

猜你在找的React相关文章