Create-app-rewired is a widely-used scaffolding that exposes webpack configurations only using eject by default, which is not very elegant and is not maintainable by modifying content files. React-app-rewired is the official tool to solve this problem. Today we are going to learn how to use it.

1. Install the react – app – rewired

create-react-app 2.x with Webpack 4

npm install react-app-rewired --save-devCopy the code

create-react-app 1.x or react-scripts-ts with Webpack 3

NPM install [email protected] - save - devCopy the code

2. Create config-overrides

/* config-overrides.js */module.exports = function override(config, env) { //do stuff with the webpack config... return config; }Copy the code

We can also put config-overrides. Js in another location, for example, if we want to point to a configuration file provided by a third-party library in node_modules, we can add the following configuration to package.json:

"config-overrides-path": "node_modules/other-rewire"Copy the code

3. Replace the react – scripts

Open the package. The json:

  /* 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"}Copy the code

4. Configuration

Customize the Webpack configuration

The WebPack field can be used to add your extra configuration, which does not include WebPack Dev Server.

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( ... ) }Copy the code

Customize Jest configuration – Testing

Jest configuration

Customize Webpack Dev Server

You can use devServer to configure the development environment, such as setting proxy, adjusting publicPath, and disabling the forwarding domain name check through disableHostCheck.

Starting with CRA 2.0, it is recommended to use customize-cra, which provides some common configurations that you can use directly.

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() )}Copy the code

Paths-path variables

Paths contains some path variables in create-React-app, including package directory, Dotenv configuration address, HTML template address, etc.

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'),};Copy the code

For example, if we want to modify appHtml, the default location of an HTML template, we can do this:

const path = require('path'); module.exports = { paths: Function (paths, env) {// Path.html path.apphtml = path.resolve(__dirname, "path.html "); return paths; }},Copy the code

5. Common examples

Add multi-page entry

Install react-app-rewi-multiple-entry first.

npm install react-app-rewire-multiple-entry --save-devCopy the code

Then configure 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(), )}Copy the code

Disable ManifestPlugin

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(), ),}Copy the code

Antd loads && less-loader on demand

const { override, fixBabelImports, addLessLoader } = require('customize-cra'); module.exports = { webpack: override( fixBabelImports('import', { libraryName: 'antd', libraryDirectory: 'es', style: 'css', }), addLessLoader(), ),}Copy the code

Finally, if you have any questions, please leave a comment and I will try my best to answer your questions.