create-react-app 2.0中使用antd(eject)
早些時候CRA(create-react-app)升級到2.0.3的時候, react-app-rewired沒有跟著升級, 導致專案無法啟動, 於是乎直接eject 開始改造專案.
檢視版本
> create-react-app --version 2.0.3
建立專案
create-react-app my-project cd my-project yarn eject # 輸入 y
目前為止專案目錄結構, 忽略node_modules這個黑洞
├── 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, 但是不影響使用
因為antd是使用的less, CRA預設不支援, 所以需要改下預設的webpack配置, config/webpack.config.js
首先修改babel配置
個人習慣使用babelrc, 所以把babel-loader options中babelrc的值改為true, 增加.babelrc檔案
{ "presets": [ "react-app" ], "plugins": [ [ "import", { "libraryName": "antd", "libraryDirectory": "lib", "style": true }, "ant" ], [ "@babel/plugin-proposal-decorators", // 啟用裝飾器 { "legacy": true } ] ] }
參照預設的sass配置, 增加less配置
const sassRegex = /\.(scss|sass)$/; const sassModuleRegex = /\.module\.(scss|sass)$/; const lessRegex = /\.less$/; const lessModuleRegex = /\.module\.less$/;
在module>rules中新增規則
// 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
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中, 一舉兩得, 不多贅述.
至此專案:ok_hand: