creo7.0导入文件建模(使用craco对cra项目进行构建优化)
creo7.0导入文件建模(使用craco对cra项目进行构建优化)/* craco.config.js */ const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer'); module.exports = { webpack: { plugins: [ new BundleAnalyzerPlugin({ analyzerMode: 'server' analyzerHost: '127.0.0.1' analyzerPort: 8888 openAnalyzer: true // 构建完打开浏览器 reportFil
修改CRA项目的配置使用create-react-app 创建的项目默认是无法修改其内部的webpack配置的,不像vue-cli那样可以通过一个配置文件修改。 虽然有一个eject 命令可以是将配置完全暴露出来,但这是一个不可逆的操作,同时也会失去CRA带来的便利和后续升级。
如果想要无 eject 重写 CRA 配置,目前成熟的是下面这几种方式
- 通过 CRA 官方支持的 --scripts-version 参数,创建项目时使用自己重写过的 react-scripts 包
- 使用 react-app-rewired customize-cra 组合覆盖配置
- 使用 craco 覆盖配置
这里我选择的是craco
安装
- 安装依赖
yarn add @craco/craco
复制代码
- 修改pacage.json中的命令
{
"scripts":{
"start": "craco start"
"build": "craco build"
"test": "craco test"
}
}
复制代码
在根目录创建craco.config.js配置文件
/* craco.config.js */
module.exports = {
// ...
webpack: {}
babel: {}
}
复制代码
基础的配置到此完成了,接下来是处理各种配置的覆盖,完整的 craco.config.js 配置文件结构,可以在 craco 官方的文档中详细查询:Configuration File 。
注意! 目前的craco最新版本v6.4.3仅支持cra4创建的项目
构建体积分析首先引入了webpack-bundle-analyzer 这个插件来分析一下构建产物的组成
/* craco.config.js */
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
module.exports = {
webpack: {
plugins: [
new BundleAnalyzerPlugin({
analyzerMode: 'server'
analyzerHost: '127.0.0.1'
analyzerPort: 8888
openAnalyzer: true // 构建完打开浏览器
reportFilename: path.resolve(__dirname `analyzer/index.html`)
})
]
}
}
复制代码
在使用yarn build命令打包后,就可以得到一个分析图,包含了每个chunk的组成部分。
可以看到这里项目的包体积高达24M 有非常多的重复文件被打包。
代码拆分,减少重复打包由于使用了懒加载,每个页面都对应一个独立的chunk文件。有些使用比较频繁的库,会被重复打包进每个chunk中,增加了很多体积。这里使用 SplitChunksPlugin来将这些库拆成一个单独的chunk。
在craco中可以通过configure属性拿到webpack的配置对象,对其进行修改来配置,将重复的包拆分出去。
经过对图的分析,发现jsoneditor echarts antv等库对包体积的影响比较大,所以将他们拆分出去。 除了将重复打包的内容拆分之外,我们还可以将项目的基本框架也提取到一个单独的文件 base.js 中,该文件包含了所有网页的基础运行环境。(为了长期缓存 base.js 文件)
webpack: {
plugins: [/** */]
configure: (webpackConfig { env: webpackEnv paths }) => {
webpackConfig.optimization.splitChunks = {
...webpackConfig.optimization.splitChunks
cacheGroups: {
base: {
// 基本框架
chunks: 'all'
test: /(react|react-dom|react-dom-router)/
name: 'base'
priority: 100
}
jsoneditor: {
test: /jsoneditor/
name: 'jsoneditor'
priority: 100
}
echarts: {
test: /(echarts)/
name: 'echarts'
priority: 100
}
g2: {
test: /@antv/
name: 'g2'
priority: 100
}
commons: {
chunks: 'all'
// 将两个以上的chunk所共享的模块打包至commons组。
minChunks: 2
name: 'commons'
priority: 80
}
}
};
return webpackConfig;
}
}
复制代码
将它拆分出去后,包体积直接减少到了7.61M 提升显著。
按需加载大体积的库从优化后的分析图中我发现了一个体积很大的库BizCharts,而项目中这个库实际上只使用过不多的几个组件.
这种情况下,可以通过修改引入方式来进行按需引入。
import { Chart Axis Legend Tooltip } from 'bizcharts';
// 改为手动按需引入
import Chart from 'bizcharts/lib/components/Chart'
import Axis from 'bizcharts/lib/components/Axis'
import ......
复制代码
手动修改所有的引入非常的麻烦,这时可以通过babel插件来帮我们在构建时修改。
babel-plugin-import这个插件原本是用来给antd按需引入的,但在这里我们也能用于其他的库
babel: {
plugins: [
[
'import'
{ libraryName: 'bizcharts' libraryDirectory: 'lib/components' }
]
]
}
复制代码
构建速度优化
HardSourceWebpackPlugin 插件可以为模块提供中间缓存。首次构建时间没有太大变化,但是第二次开始,构建时间大约可以节约 80%。
在我的项目中,一开始的构建的速度为26s,配置完插件生成缓存后为15s 节约了60%多的时间。
附上配置// craco.config.js
const path = require('path');
const CracoLessPlugin = require('craco-less');
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
const WebpackBar = require('webpackbar');
const HardSourceWebpackPlugin = require('hard-source-webpack-plugin');
const env = process.env.REACT_APP_ENV;
module.exports = {
webpack: {
plugins: [
new BundleAnalyzerPlugin({
analyzerMode: env !== 'development' ? 'server' : 'disabled'
analyzerHost: '127.0.0.1'
analyzerPort: 8888
openAnalyzer: true
reportFilename: path.resolve(__dirname `analyzer/index.html`)
})
new WebpackBar({
profile: true
color: '#fa8c16'
})
new HardSourceWebpackPlugin()
]
alias: {
layouts: path.resolve(__dirname './src/app/layouts')
containers: path.resolve(__dirname './src/app/containers')
components: path.resolve(__dirname './src/app/components')
utils: path.resolve(__dirname './src/utils')
routers: path.resolve(__dirname './src/routers')
}
configure: (webpackConfig { env: webpackEnv paths }) => {
webpackConfig.externals = {
'ckeditor5-custom-build': 'ClassicEditor'
};
webpackConfig.optimization.splitChunks = {
...webpackConfig.optimization.splitChunks
cacheGroups: {
base: {
// 基本框架
chunks: 'all'
test: /(react|react-dom|react-dom-router)/
name: 'base'
priority: 100
}
jsoneditor: {
test: /jsoneditor/
name: 'jsoneditor'
priority: 100
}
echarts: {
test: /(echarts)/
name: 'echarts'
priority: 100
}
g2: {
test: /@antv/
name: 'g2'
priority: 100
}
commons: {
chunks: 'all'
// 将两个以上的chunk所共享的模块打包至commons组。
minChunks: 2
name: 'commons'
priority: 80
}
}
};
return webpackConfig;
}
}
babel: {
plugins: [
[ // antd 的按需加载用和自动引入样式文件
'import'
{
libraryName: 'antd'
libraryDirectory: 'es'
style: true
}
]
// bizcharts的按需加载
['import' { libraryName: 'bizcharts' libraryDirectory: 'lib/components' } 'biz']
]
}
plugins: [
{ // 修改antd主题
plugin: CracoLessPlugin
options: {
lessLoaderOptions: {
lessOptions: {
math: 'always'
modifyVars: {
'@primary-color': '#1890ff' //主题颜色
}
javascriptEnabled: true
}
}
}
}
]
};
复制代码
总结
这次的优化主要是针对减小构建产物体积的,体积从24M -> 6.8M左右,提升还是非常大的。
通过了代码分割的方式减少库被重复打包,以及按需加载一些很大的库,同时通过一些缓存的插件提升了构建速度。
最后如果你觉得此文对你有一丁点帮助,点个赞。或者可以加入我的开发交流群:1025263163相互学习,我们会有专业的技术答疑解惑
如果你觉得这篇文章对你有点用的话,麻烦请给我们的开源项目点点star:http://github.crmeb.net/u/defu不胜感激 !
PHP学习手册:https://doc.crmeb.com
技术交流论坛:https://q.crmeb.com