create-react-app
是一款普遍使用的腳手架,默認它只能使用eject
命令暴露出webpack
配置,其實這樣使用很不優雅,修改內容文件的話也不利於維護,react-app-rewired
正式解決這樣問題的工具,今天咱們就好好學習下它的用法。css
npm install react-app-rewired --save-dev
npm install react-app-rewired@1.6.2 --save-dev
/* config-overrides.js */ module.exports = function override(config, env) { //do stuff with the webpack config... return config; }
固然咱們也能夠把config-overrides.js
放到其餘位置,好比咱們要指向node_modules
中某個第三方庫提供的配置文件,就能夠添加下面配置到package.json
:html
"config-overrides-path": "node_modules/other-rewire"
打開package.json
:node
/* package.json */ "scripts": { - "start": "react-scripts start", + "start": "react-app-rewired start", - "build": "react-scripts build", + "build": "react-app-rewired build", - "test": "react-scripts test --env=jsdom", + "test": "react-app-rewired test --env=jsdom", "eject": "react-scripts eject" }
webpack
字段能夠用來添加你的額外配置,固然這裏面不包含Webpack Dev Server
。react
const { override, overrideDevServer, fixBabelImports, addLessLoader, addWebpackAlias, addWebpackModuleRule } = require('customize-cra'); const removeManifest = () => config => { config.plugins = config.plugins.filter( p => p.constructor.name !== "ManifestPlugin" ); return config; }; module.exports = { webpack: override( removeManifest(), fixBabelImports('import', { libraryName: 'antd', libraryDirectory: 'es', style: 'css', }), addLessLoader(), addWebpackModuleRule({ test: require.resolve('snapsvg/dist/snap.svg.js'), use: 'imports-loader?this=>window,fix=>module.exports=0', },), addWebpackAlias({ Snap: 'snapsvg/dist/snap.svg.js' }), ), devServer: overrideDevServer( ... ) }
jest
配置webpack
經過devServer
咱們能夠作一些開發環境的配置,好比設置proxy
代理,調整publicPath
,經過disableHostCheck
禁用轉發域名檢查等。web
從CRA 2.0
開始,推薦搭配customize-cra
使用,裏面提供了一些經常使用的配置,能夠方便咱們直接使用。shell
const { override, overrideDevServer, } = require('customize-cra'); const addProxy = () => (configFunction) => { configFunction.proxy = { '/v2ex/': { target: 'https://www.v2ex.com', changeOrigin: true, pathRewrite: { '^/v2ex': '/' }, }, }; return configFunction; } module.exports = { webpack: override( ... ), devServer: overrideDevServer( addProxy() ) }
paths
裏面是create-react-app
裏面的一些路徑變量,包含打包目錄、dotenv
配置地址、html
模板地址等。npm
module.exports = { dotenv: resolveApp('.env'), appPath: resolveApp('.'), appBuild: resolveApp('build'), appPublic: resolveApp('public'), appHtml: resolveApp('public/index.html'), appIndexJs: resolveModule(resolveApp, 'src/index'), appPackageJson: resolveApp('package.json'), appSrc: resolveApp('src'), appTsConfig: resolveApp('tsconfig.json'), appJsConfig: resolveApp('jsconfig.json'), yarnLockFile: resolveApp('yarn.lock'), testsSetup: resolveModule(resolveApp, 'src/setupTests'), proxySetup: resolveApp('src/setupProxy.js'), appNodeModules: resolveApp('node_modules'), publicUrl: getPublicUrl(resolveApp('package.json')), servedPath: getServedPath(resolveApp('package.json')), // These properties only exist before ejecting: ownPath: resolveOwn('.'), ownNodeModules: resolveOwn('node_modules'), // This is empty on npm 3 appTypeDeclarations: resolveApp('src/react-app-env.d.ts'), ownTypeDeclarations: resolveOwn('lib/react-app.d.ts'), };
好比咱們要修改appHtml
即html
模板的默認位置,能夠這樣作:json
const path = require('path'); module.exports = { paths: function (paths, env) { // 指向根目錄的test.html paths.appHtml = path.resolve(__dirname, "test.html"); return paths; }, }
首先安裝react-app-rewire-multiple-entry
。antd
npm install react-app-rewire-multiple-entry --save-dev
而後在config-overrides.js
配置:
const { override, overrideDevServer } = require('customize-cra'); const multipleEntry = require('react-app-rewire-multiple-entry')([{ entry: 'src/pages/options.tsx', template: 'public/options.html', outPath: '/options.html', }]); const addEntry = () => config => { multipleEntry.addMultiEntry(config); return config; }; const addEntryProxy = () => (configFunction) => { multipleEntry.addEntryProxy(configFunction); return configFunction; } module.exports = { webpack: override( addEntry(), ), devServer: overrideDevServer( addEntryProxy(), ) }
const { override, } = require('customize-cra'); const removeManifest = () => config => { config.plugins = config.plugins.filter( p => p.constructor.name !== "ManifestPlugin" ); return config; }; module.exports = { webpack: override( removeManifest(), ), }
const { override, fixBabelImports, addLessLoader } = require('customize-cra'); module.exports = { webpack: override( fixBabelImports('import', { libraryName: 'antd', libraryDirectory: 'es', style: 'css', }), addLessLoader(), ), }
最後,若是使用上有什麼問題歡迎留言,我會盡我所能解答你們的問題。
本文首發: create-react-app 優雅定製指南
另外推薦關注公衆號:湖中劍,實時獲取文章更新。