早些時候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則說明配置成.