早些时候CRA(create-react-app)升级到2.0.3的时候, react-app-rewired没有跟着升级, 致使项目没法启动, 因而乎直接eject 开始改造项目.javascript
查看版本css
> create-react-app --version 2.0.3
create-react-app my-project cd my-project yarn eject # 输入 y
目前为止项目目录结构, 忽略node_modules这个黑洞html
├── README.md ├── config │ ├── env.js │ ├── jest │ │ ├── cssTransform.js │ │ └── fileTransform.js │ ├── paths.js │ ├── webpack.config.js │ └── webpackDevServer.config.js ├── package.json ├── public │ ├── favicon.ico │ ├── index.html │ └── manifest.json ├── scripts │ ├── build.js │ ├── start.js │ └── test.js ├── src │ ├── App.css │ ├── App.js │ ├── App.test.js │ ├── index.css │ ├── index.js │ ├── logo.svg │ └── serviceWorker.js └── yarn.lock
yarn add antd yarn add babel-plugin-import less less-loader @babel/plugin-proposal-decorators -D
CRA eject以后package.json里面没有区分devDependencies 和 dependencies, 可是不影响使用java
由于antd是使用的less, CRA默认不支持, 因此须要改下默认的webpack配置, config/webpack.config.jsnode
我的习惯使用babelrc, 因此把babel-loader options中babelrc的值改成true, 增长.babelrc文件react
{ "presets": [ "react-app" ], "plugins": [ [ "import", { "libraryName": "antd", "libraryDirectory": "lib", "style": true }, "ant" ], [ "@babel/plugin-proposal-decorators", // 启用装饰器 { "legacy": true } ] ] }
const sassRegex = /\.(scss|sass)$/; const sassModuleRegex = /\.module\.(scss|sass)$/; const lessRegex = /\.less$/; const lessModuleRegex = /\.module\.less$/;
在module>rules中添加规则webpack
// sass rule //... { test: lessRegex, exclude: lessModuleRegex, use: getStyleLoaders( { importLoaders: 2, sourceMap: isEnvProduction && shouldUseSourceMap }, 'less-loader', { javascriptEnabled: true } ), sideEffects: true }, { test: lessModuleRegex, use: getStyleLoaders( { importLoaders: 2, sourceMap: isEnvProduction && shouldUseSourceMap, modules: true, getLocalIdent: getCSSModuleLocalIdent }, 'less-loader', { javascriptEnabled: true } ) } // file loader
至此基本项目虽然已经基本完成, 可是若是你是使用less版本比较高, 项目是没法运行的
参考issue
须要改造getStyleLoaders函数, 增长第三个参数otherConfig, 就是上面代码中的 javascriptEnabled: true
git
const getStyleLoaders = (cssOptions, preProcessor, otherConfig) => { const loaders = [ isEnvDevelopment && require.resolve('style-loader'), isEnvProduction && { loader: MiniCssExtractPlugin.loader, options: Object.assign({}, shouldUseRelativeAssetPaths ? { publicPath: '../../' } : undefined) }, { loader: require.resolve('css-loader'), options: cssOptions }, { loader: require.resolve('postcss-loader'), options: { ident: 'postcss', plugins: () => [ require('postcss-flexbugs-fixes'), require('postcss-preset-env')({ autoprefixer: { flexbox: 'no-2009' }, stage: 3 }) ], sourceMap: isEnvProduction && shouldUseSourceMap } } ].filter(Boolean); if (preProcessor) { loaders.push({ loader: require.resolve(preProcessor), options: { sourceMap: isEnvProduction && shouldUseSourceMap, ...otherConfig } }); } return loaders; };
这样修改以后, 自定义主题modifyVars也能够写在otherConfig中, 一箭双雕, 很少赘述.github
至此项目👌web
关于dll的利弊再也不赘述, 这里只是说明我用的方法, 也不详细展开, 每一个人的项目可能都不同
安装插件
yarn add clean-webpack-plugin webpack-cli add-asset-html-webpack-plugin -D
在config/paths.js exports对象中增长一行kv
appDll: resolveApp("dll"),
增长config/webpack.dll.conf.js文件
const paths = require('./paths'); const path = require('path'); const webpack = require('webpack'); const CleanWebpackPlugin = require('clean-webpack-plugin'); const vendors = [ 'react', 'react-dom' ]; module.exports = { mode: 'production', performance: { hints: false }, output: { path: paths.appDll, publicPath: paths.servedPath, filename: '[name].[hash].dll.js', library: '[name]_[hash]' }, entry: { vendor: vendors }, plugins: [ new CleanWebpackPlugin([paths.appDll], { root: paths.appPath, // 根目录 verbose: true, // 开启在控制台输出信息 dry: false // 启用删除文件 }), new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/), new webpack.DllPlugin({ path: path.join(paths.appDll, '[name]-manifest.json'), name: '[name]_[hash]' }) ] };
package.json增长dll 脚本
"dll": "webpack --progress --config config/webpack.dll.conf.js"
运行 yarn dll
打包vendor在dll文件夹中
生产模式使用dll, 修改webpack.conf.js, 增长assets插件和dllreference插件
... const AddAssetHtmlPlugin = require("add-asset-html-webpack-plugin"); .... plugins: { ... ... isEnvProduction && new webpack.DllReferencePlugin({ manifest: require('../dll/vendor-manifest.json') }), isEnvProduction && new AddAssetHtmlPlugin({ filepath: path.resolve(paths.appDll, '*.js'), includeSourcemap: false }), }
至此结束, 验证效果
yarn build
build 文件夹结构
├── asset-manifest.json ├── favicon.ico ├── index.html ├── manifest.json ├── precache-manifest.8175e98134227f2327b88338d3024239.js ├── service-worker.js ├── static │ ├── css │ │ ├── 1.83e366fa.chunk.css │ │ ├── 1.83e366fa.chunk.css.map │ │ ├── main.c7ff46e9.chunk.css │ │ └── main.c7ff46e9.chunk.css.map │ ├── js │ │ ├── 1.860809fa.chunk.js │ │ ├── 1.860809fa.chunk.js.map │ │ ├── main.0df678d7.chunk.js │ │ ├── main.0df678d7.chunk.js.map │ │ ├── runtime~main.229c360f.js │ │ └── runtime~main.229c360f.js.map │ └── media │ └── logo.5d5d9eef.svg └── vendor.52ec4f1c0bead1c1a489.dll.js
本地运行serve -s build
, 项目能正常显示, build文件夹下有vendor.hash.dll.js则说明配置成.