Tweak the create-react-app webpack config(s) without using 'eject' and without creating a fork of the react-scripts
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Core system for customizing webpack, Jest, dev server, and paths configurations through override functions in config-overrides.js.
Simple webpack-only configuration override using a single function export.
/**
* Single function export for webpack-only overrides
* @param config - Webpack configuration object
* @param env - Environment string ('development' or 'production')
* @returns Modified webpack configuration
*/
module.exports = function override(config, env) {
// Modify webpack config
return config;
};Usage Example:
module.exports = function override(config, env) {
// Add a new webpack plugin
config.plugins.push(new SomeWebpackPlugin());
// Modify existing rules
const babelLoader = config.module.rules.find(rule =>
rule.use && rule.use.find(use => use.loader && use.loader.includes('babel-loader'))
);
return config;
};Advanced configuration override using object export with separate functions for different aspects.
/**
* Object export with multiple override functions
*/
module.exports = {
webpack: function(config, env) { return config; },
jest: function(config) { return config; },
devServer: function(configFunction) { return configFunction; },
paths: function(paths, env) { return paths; }
};Customize webpack configuration for development and production builds.
/**
* Webpack configuration override function
* @param config - Webpack configuration object from react-scripts
* @param env - Environment string ('development' or 'production')
* @returns Modified webpack configuration object
*/
webpack: function(config, env) {
// Modify webpack configuration
return config;
}Usage Examples:
webpack: function(config, env) {
// Add custom alias
config.resolve.alias = {
...config.resolve.alias,
'@': path.resolve(__dirname, 'src')
};
// Add custom loader
config.module.rules.push({
test: /\.custom$/,
use: 'custom-loader'
});
// Modify existing rules
const oneOfRule = config.module.rules.find(rule => rule.oneOf);
oneOfRule.oneOf.unshift({
test: /\.module\.scss$/,
use: ['style-loader', 'css-loader', 'sass-loader']
});
return config;
}Customize Jest testing configuration beyond what's possible in package.json.
/**
* Jest configuration override function
* @param config - Jest configuration object from react-scripts
* @returns Modified Jest configuration object
*/
jest: function(config) {
// Modify Jest configuration
return config;
}Usage Examples:
jest: function(config) {
// Add custom test path ignore patterns
if (!config.testPathIgnorePatterns) {
config.testPathIgnorePatterns = [];
}
if (!process.env.RUN_COMPONENT_TESTS) {
config.testPathIgnorePatterns.push('<rootDir>/src/components/**/*.test.js');
}
// Add custom setup files
config.setupFilesAfterEnv = config.setupFilesAfterEnv || [];
config.setupFilesAfterEnv.push('<rootDir>/src/setupTests.js');
// Modify module name mapping
config.moduleNameMapper = {
...config.moduleNameMapper,
'^@/(.*)$': '<rootDir>/src/$1'
};
return config;
}Customize webpack development server configuration.
/**
* Dev server configuration override function
* @param configFunction - Original function that creates dev server config
* @param env - Environment string (passed by react-app-rewired)
* @returns New function that creates modified dev server config
*/
devServer: function(configFunction, env) {
return function(proxy, allowedHost) {
const config = configFunction(proxy, allowedHost);
// Modify dev server config
return config;
};
}Usage Examples:
devServer: function(configFunction) {
return function(proxy, allowedHost) {
const config = configFunction(proxy, allowedHost);
// Enable HTTPS with custom certificates
const fs = require('fs');
config.https = {
key: fs.readFileSync(process.env.REACT_HTTPS_KEY, 'utf8'),
cert: fs.readFileSync(process.env.REACT_HTTPS_CERT, 'utf8'),
ca: fs.readFileSync(process.env.REACT_HTTPS_CA, 'utf8'),
passphrase: process.env.REACT_HTTPS_PASS
};
// Add custom middleware
config.before = function(app) {
app.get('/api/health', (req, res) => {
res.json({ status: 'ok' });
});
};
return config;
};
}Customize file paths used by react-scripts.
/**
* Paths configuration override function
* @param paths - Paths object from react-scripts
* @param env - Environment string ('development', 'production', or 'test')
* @returns Modified paths object
*/
paths: function(paths, env) {
// Modify paths configuration
return paths;
}Usage Examples:
paths: function(paths, env) {
// Change build directory
paths.appBuild = path.resolve(__dirname, 'dist');
// Add custom paths
paths.appCustom = path.resolve(__dirname, 'custom');
// Modify source directory (advanced use case)
if (env === 'development') {
paths.appSrc = path.resolve(__dirname, 'dev-src');
}
return paths;
}Different ways to organize your config-overrides.js file:
// 1. Single file in project root
// config-overrides.js
// 2. Directory with index.js
// config-overrides/index.js
// 3. Custom path via package.json
{
"config-overrides-path": "node_modules/some-preconfigured-rewire"
}
// 4. Custom path via command line
// --config-overrides ./custom/path/overrides.jsReact-app-rewired will automatically detect and warn about deprecated configuration patterns:
// Deprecated dev server field (shows warning from config-overrides.js)
module.exports = {
devserver: function(configFunction) { /* deprecated */ }
};
// Warning message displayed:
console.log(
'Warning: `devserver` has been deprecated. Please use `devServer` instead as ' +
'`devserver` will not be used in the next major release.'
);
// Modern dev server field
module.exports = {
devServer: function(configFunction, env) { /* use this */ }
};Compatibility Note: The system supports both devServer and devserver for backwards compatibility, but devserver shows a deprecation warning and will be removed in a future major release.
Install with Tessl CLI
npx tessl i tessl/npm-react-app-rewired