批改 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