React 和Webpack构建打包优化实例详解

本文主要介绍了浅谈react + webpack 构建打包优化,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧,希望能帮助到大家。

使用 babel-react-optimize 对 React 代码进行优化

检查没有使用的库,去除 import 引用

按需打包所用的类库,比如 lodash 、 echart 等

lodash 可以采用babel-plugin-lodash 进行优化。

需要注意的是

在 babel-react-optimize 中使用了 babel-plugin-transform-react-remove-prop-types 这个插件。正常情况下,如果你在代码中没有引用到组件的 PropTypes ,则完全没问题。如果你的组件用到了,那么使用该插件可能会导致问题。

具体见:

https://github.com/oliviertassinari/babel-plugin-transform-react-remove-prop-types#is-it-safe

Webpack 构建打包优化

Webpack 构建打包存在的问题主要集中于下面两个方面:

Webpack 构建速度慢

Webpack 打包后的文件体积过大

Webpack 构建速度慢

可以使用 Webpack.DDLPlugin , HappyPack 来提高构建速度。具体参见小铭在 DMP DDLPlugin 的文档。原文如下:

Webpack.DLLPlugin

添加一个 webpack.dll.config.js
主要是用到一个 DllPlugin 插件,把一些第三方的资源独立打包,同时放到一个 manifest.json 配置文件中,

这样在组件中更新后,就不会重新 build 这些第三方的资源,

同时独立配置 dll/vendors.js 文件,提供给 webpack.dll.config.js

修改 package.json

在 scripts 中添加: “dll”: “webpack –config webpack.dll.config.js –progress –colors “, 。

执行 npm run dll 以后,会在 dll 目录下生产 两个文件 vendor-manifest.json ,vendor.dll.js

配置 webpack.dev.config.js 文件,加入一个 DllReferencePlugin 插件,并指定 vendor-manifest.json 文件

new webpack.DllReferencePlugin({ context: join(__dirname, 'src'), manifest: require('./dll/vendor-manifest.json')})

登录后复制

修改 html

 

登录后复制

注意,需要在 htmlWebpackPlugin 插件中配置 NODE_ENV 参数

Happypack

通过多线程,缓存等方式提升 rebuild 效率 https://github.com/amireh/happypack

在 webpack.dev.config.js 中针对不同的资源创建多个 HappyPack, 比如 js 1 个,less 1 个,并设置好 id

new HappyPack({ id: 'js', threadPool: happyThreadPool, cache: true, verbose: true, loaders: ['babel-loader?babelrc&cacheDirectory=true'],}),new HappyPack({ id: 'less', threadPool: happyThreadPool, cache: true, verbose: true, loaders: ['css-loader', 'less-loader'],})

登录后复制

在 module.rules 中配置 use 为 happypack/loader, 设置 id

{ test: /.js$/, use: [ 'happypack/loader?id=js' ], exclude: /node_modules/}, { test: /.less$/, loader: extractLess.extract({ use: ['happypack/loader?id=less'], fallback: 'style-loader' })}

登录后复制

减少 Webpack 打包后的文件体积大小

首先需要对我们整个 bundle 进行分析,由哪些东西组成及各组成部分所占大小。

这里推荐 webpack-bundle-analyzer 。安装后在 webpack.dev.config.js 中添加插件即可,就能在每次启动后自动在网站打开分析结果,如下图

plugins.push( new BundleAnalyzerPlugin());

登录后复制

React 和Webpack构建打包优化实例详解

除此之外,还可以将打包过程输出成json文件

webpack --profile --json -> stats.json

登录后复制

然后到下面这两个网站进行分析

webpack/analyse

Webpack Chart

通过上面的图表分析可以清楚得看到,整个 bundle.js 的组成部分及对应的大小。

解决 bundle.js 体积过大的解决思路如下:

生产环境启用压缩等插件,去除不必要插件

拆分业务代码与第三方库及公共模块

webpack 开启 gzip 压缩

按需加载

生产环境启用压缩等插件,去除不必要插件

确保在生产环境启动 webpack.DefinePlugin 和 webpack.optimize.UglifyJsPlugin 。

const plugins = [ new webpack.DefinePlugin({  'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'production') }),  new webpack.optimize.UglifyJsPlugin({  compress: {   warnings: false,   drop_console: false //eslint-disable-line  }  })   ]

登录后复制

拆分业务代码与第三方库及公共模块

由于项目的业务代码变更频率很高,而第三方库的代码变化则相对没有那么频率。如果将业务代码和第三库打包到同一个 chunk 的话,在每次构建的时候,哪怕业务代码只改了一行,即使第三方库的代码没有发生变化,会导致整个 chunk 的 hash 跟上一次不同。这不是我们想要的结果。我们想要的是,如果第三方库的代码没有变化,那在构建的时候也要保证对应的 hash 没有发生变化,从而能利用浏览器缓存,更好的提高页面加载性能和缩短页面加载时间。

因此可以将第三库的代码单独拆分成 vendor chunk,与业务代码分离。这样就算业务代码再怎么发生变化,只要第三方库代码没有发生变化,对应的 hash 就不变。

首先 entry 配置两个 app 和 vendor 两个chunk

entry: { vendor: [path.join(__dirname, 'dll', 'vendors.js')], app: [path.join(__dirname, 'src/index')]},output: { path: path.resolve(__dirname, 'build'), filename: '[name].[chunkhash:8].js'},

登录后复制

其中 vendros.js 是自己定义的哪些第三方库需要纳入 vendor 中,如下:

require('babel-polyfill');require('classnames');require('intl');require('isomorphic-fetch');require('react');require('react-dom');require('immutable');require('redux');

登录后复制

然后通过 CommonsChunkPlugin 拆分第三库

plugins.push( // 拆分第三方库 new webpack.optimize.CommonsChunkPlugin({ name: 'vendor' }), // 拆分 webpack 自身代码 new webpack.optimize.CommonsChunkPlugin({  name: 'runtime',  minChunks: Infinity }));

登录后复制

上面的配置有两个细节需要注意

使用 chunkhash 而不用 hash

单独拆分 webpack 自身代码

使用 chunkhash 而不用 hash

先来看看这二者有何区别:

hash 是 build-specific ,任何一个文件的改动都会导致编译的结果不同,适用于开发阶段

chunkhash 是 chunk-specific ,是根据每个 chunk 的内容计算出的 hash,适用于生产

因此为了保证第三方库不变的情况下,对应的 vendor.js 的 hash 也要保持不变,我们再 output.filename 中采用了 chunkhash

单独拆分 webpack 自身代码

Webpack 有个已知问题:

webpack 自身的 boilerplate 和 manifest 代码可能在每次编译时都会变化。

这导致我们只是在 入口文件 改了一行代码,但编译出的 vendor 和 entry chunk 都变了,因为它们自身都包含这部分代码。

这是不合理的,因为实际上我们的第三方库的代码没变,vendor 不应该在我们业务代码变化时发生变化。

因此我们需要将 webpack 这部分代码分离抽离

new webpack.optimize.CommonsChunkPlugin({   name: "runtime",   minChunks: Infinity}),

登录后复制

其中的 name 只要不在 entry 即可,通常使用 “runtime” 或 “manifest” 。

另外一个参数 minChunks 表示:在传入公共chunk(commons chunk) 之前所需要包含的最少数量的 chunks。数量必须大于等于2,或者少于等于 chunks的数量,传入 Infinity 会马上生成 公共chunk,但里面没有模块。

拆分公共资源

同 上面的拆分第三方库一样,拆分公共资源可以将公用的模块单独打出一个 chunk,你可以设置 minChunk 来选择是共用多少次模块才将它们抽离。配置如下:

new webpack.optimize.CommonsChunkPlugin({ name: 'common', minChunks: 2,}),

登录后复制

是否需要进行这一步优化可以自行根据项目的业务复用度来判断。

开启 gzip

使用 CompressionPlugin 插件开启 gzip 即可:

// 添加 gzipnew CompressionPlugin({ asset: '[path].gz[query]', algorithm: 'gzip', test: /.(js|html)$/, threshold: 10240, minRatio: 0.8})

登录后复制

大家学会了吗?赶紧动手尝试一下吧。

相关推荐:

parcel.js打包出错到选择nvm的全部过程解析

Parcel打包示例详解

webpack多入口文件页面打包详解

以上就是React 和Webpack构建打包优化实例详解的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2789256.html

(0)
上一篇 2025年3月8日 18:40:31
下一篇 2025年3月8日 18:40:40

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • node.js中的npm和webpack配置方法详解

    node.js用c++语言编写而成的,是一个基于chrome v8引擎的javascript运行环境,让javascript的运行脱离浏览器服务端,可以使用javascript语言书写服务器端代码,主要介绍了详解node.js中的npm和w…

    2025年3月8日
    200
  • React根据宽度自适应高度实例分享

    有时对于响应式布局,我们需要根据组件的宽度自适应高度。css无法实现这种动态变化,传统是用jquery实现。本文主要介绍了react根据宽度自适应高度的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧,希…

    2025年3月8日
    200
  • JS实现websocket实时消息提示

    本文主要介绍了js实现websocket长轮询实时消息提示的效果的相关资料,需要的朋友可以参考下,希望能帮助到大家。 效果图如下: 参考代码如下: jsp代码:             “>”  style=”max-width:90…

    2025年3月8日
    200
  • JS hash制作单页Web应用实例分享

    本文我们会先从hash是什么,hash有什么作用以及何为单页web应用开始讲解,后面将会介绍到js hash制作单页web应用实例,希望能帮助到大家。 一、何为hash 这里要讲的hash(也叫哈希),指的是JS中location对象的ha…

    编程技术 2025年3月8日
    200
  • React利用相对于根目录进行引用组件实例详解

    本文主要给大家介绍了关于react如何使用相对于根目录进行引用组件的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧,希望能帮助到大家。 在对自己开发的组件中经常…

    编程技术 2025年3月8日
    200
  • React Native中RefreshContorl下拉刷新教程

    我们知道app中都有下拉加载,在react native中也有类似的控件,本文主要介绍了react native中的refreshcontorl下拉刷新使用,希望能帮助到大家。 一、属性方法 (1) onRefresh function 在…

    编程技术 2025年3月8日
    200
  • React实践Tree组件如何使用

    本文主要介绍了react实践之tree组件的使用方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧,希望能帮助到大家。 实现功能 渲染数据 展开合并 使用 数据结构: const node = { title:…

    2025年3月8日
    200
  • React中组件间抽象实例讲解

    在组件构建中,通常有一类功能需要被不同的组件公用,此时就涉及抽象的概念,在react中我们主要了解mixin和高阶组件。本文主要介绍了浅谈react中组件间抽象,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧,希…

    编程技术 2025年3月8日
    200
  • React Native中NavigatorIOS组件简单使用教程

    本文主要介绍了react native中navigatorios组件的简单使用详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧,希望能帮助到大家。 一、NavigatorIOS组件介绍 1,组件说明 使用 N…

    编程技术 2025年3月8日
    200
  • React组件生命周期实例分析

    本文主要和大家分享react组件生命周期,react组件的生命周期有一堆的相关函数,其实就是一推的钩子函数。在react组件创建的各个阶段触发特定的钩子函数。希望能帮助到大家。 可以先大概看一下下面这张图: constructor 构造函数…

    2025年3月8日 编程技术
    200

发表回复

登录后才能评论