create-react-app 优雅定制指南
source link: http://idayer.com/create-react-app-rewired-guide/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
create-react-app
是一款广泛使用的脚手架,默认它只能使用 eject
命令暴露出 webpack
配置,其实这样使用很不优雅,修改内容文件的话也不利于维护, react-app-rewired
正式解决这样问题的工具,今天我们就好好学习下它的用法。
1. 安装 react-app-rewired
create-react-app 2.x with Webpack 4
npm install react-app-rewired --save-dev
create-react-app 1.x or react-scripts-ts with Webpack 3
npm install [email protected] --save-dev
2. 根目录创建config-overrides.js
/* config-overrides.js */ module.exports = function override(config, env) { //do stuff with the webpack config... return config; }
当然我们也可以把 config-overrides.js
放到其他位置,比如我们要指向 node_modules
中某个第三方库提供的配置文件,就可以添加下面配置到 package.json
:
"config-overrides-path": "node_modules/other-rewire"
3. 替换 react-scripts
打开 package.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" }
4. 配置
定制 Webpack 配置
webpack
字段可以用来添加你的额外配置,当然这里面不包含 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( ... ) }
定制 Jest 配置 - Testing
jest
配置
定制 Webpack Dev Server
通过 devServer
我们可以做一些开发环境的配置,比如设置 proxy
代理,调整 publicPath
,通过 disableHostCheck
禁用转发域名检查等。
从 CRA 2.0
开始,推荐搭配 customize-cra
使用,里面提供了一些常用的配置,可以方便我们直接使用。
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 - 路径变量
paths
里面是 create-react-app
里面的一些路径变量,包含打包目录、 dotenv
配置地址、 html
模板地址等。
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
模板的默认位置,可以这样做:
const path = require('path'); module.exports = { paths: function (paths, env) { // 指向根目录的test.html paths.appHtml = path.resolve(__dirname, "test.html"); return paths; }, }
5. 常用示例
添加多页面入口
首先安装 react-app-rewire-multiple-entry
。
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(), ) }
禁用 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(), ), }
antd 按需加载 && less-loader
const { override, fixBabelImports, addLessLoader } = require('customize-cra'); module.exports = { webpack: override( fixBabelImports('import', { libraryName: 'antd', libraryDirectory: 'es', style: 'css', }), addLessLoader(), ), }
最后,如果使用上有什么问题欢迎留言,我会尽我所能解答大家的问题。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK