当前位置: 首页 > 后端技术 > Node.js

Wuzzle,你可以自定义create-react-app创建的React应用,无需eject

时间:2023-04-03 15:02:55 Node.js

作为React官方维护的命令行工具,create-react-app(简称CRA)可以非常轻松的创建一个全配置的React应用,帮助使用快速进入React开发。它最大的缺点是创建的应用程序不能按需自定义配置。如果要自定义,只能弹出。而eject意味着将应用的所有配置都交给用户维护,繁琐得让人望而却步。现在有了wuzzle,我们可以任意定制CRA创建的React应用,不用弹出。不使用eject查看CRAwebpack配置首先,使用CRA创建一个支持TypeScript的demo应用(如果不习惯使用TS去掉参数--templatetypescript):$npxcreate-react-app--templatetypescriptdemo#...$cddemo安装wuzzle:$npmi-Dwuzzle打开package.json编辑脚本Mountwuzzle:"scripts":{-"start":"react-scriptsstart",+"start":"wuzzlereact-scriptsstart",-"build":"react-scriptsbuild",+"build":"wuzzlereact-scriptsbuild",},现在,你可以通过运行带有参数的启动或构建脚本来直接查看CRA--dry-run内部webpack配置配置:$npmrunbuild----dry-run#...@wuzzle/cli:applyConfigWebpackconfig不同之处:{#...devtool:#...entry:#...output:#...cache:#...resolve:#...module:#...plugins:#...#...}引入less而不弹出,在样式文件上使用antd,CRA应用程序支持css、scss/sass,但不少。如果想充分利用antd,做主题修改,需要在webpack配置中少引入。返回--dry-run并仔细查看模块字段:$npmrunbuild----dry-run#...@wuzzle/cli:applyConfigWebpackconfigwithdifference:{#...module:{#...规则:[#...{oneOf:[#...{测试:/\.(scss|sass)$/,排除:/\.module\.(scss|sass)$/,使用:[{loader:'.../mini-css-extract-plugin/dist/loader.js',options:{}},{loader:'.../css-loader/...',选项:#...},{loader:'.../postcss-loader/...',选项:#...},{loader:'.../resolve-url-loader/...',options:#...},{loader:'.../sass-loader/...',options:#...}],},{test:/\.module\.(scss|无礼)$/,使用:[{loader:'.../mini-css-extract-plugin/dist/loader.js',options:#...},{loader:'.../css-loader/...',options:#...},{loader:'.../postcss-loader/...',options:#...},{loader:'.../resolve-url-loader/...',选项:#...},{loader:'.../sass-loader/...',选项:#...}]},#...]}]},#...}不难发现sass的配置方式和less非常相似。稍微修改一下,把sass-loader换成less-loader,去掉resolve-url-loader就可以达到目的安装less配置所需的依赖项:npmi-Dlessless-loader然后,在package.json旁边创建文件wuzzle.config.js来修改CRA内部使用的webpack配置。这里可以使用wuzzle提供的修改帮助方法来减少工作Const:constappPaths=require('react-scripts/config/paths');const{deleteUseItem,firstRule,firstUseItem,replaceUseItem}=require('wuzzle');module.exports=(webpackConfig,webpack,wuzzleContext)=>{const{commandArgs}=wuzzleContext;if(commandArgs[0]==='start'||commandArgs[0]==='build'){//将sass-loader替换为less-loader以支持.less文件constlessOptions={javascriptEnabled:true};constscssRuleQuery={file:{dir:appPaths.appSrc,base:'index.scss'}};constlessRule=firstRule(webpackConfig,scssRuleQuery);Object.assign(lessRule,{test:/\.(less)$/,exclude:/\.module\.less$/});deleteUseItem(lessRule,{loader:'resolve-url-loader'});replaceUseItem(lessRule,{loader:'sass-loader'},{loader:'less-loader',options:{来源eMap:true,lessOptions}});firstUseItem(lessRule,{loader:'css-loader'}).options.importLoaders=2;constscssModuleRuleQuery={file:{dir:appPaths.appSrc,base:'index.module.scs'}};constlessModuleRule=firstRule(webpackConfig,scssModuleRuleQuery);Object.assign(lessModuleRule,{test:/\.module\.less$/});deleteUseItem(lessModuleRule,{loader:'resolve-url-loader'});replaceUseItem(lessModuleRule,{loader:'sass-loader'},{loader:'less-loader',options:{sourceMap:true,lessOptions}});firstUseItem(lessModuleRule,{loader:'css-loader'}).options.importLoaders=2;}};之后,将所有.css文件的后缀改为.less:将index.css重命名为index.less,并在index.tsx中导入'./index.css';更改为import'./index.less';将App.css重命名为App.less,并更改import'./App.css';导入“./App.less”;在App.tsx中。安装antd:$npmi-Santdimportantdstylefileinindex.less:-body{-...-}-code{-...-}+@import'~antd/dist/antd.less';如果要修改antd主题,可以回到wuzzle.config.js,在lessOptions中添加modifyVars字段,例如:-constlessOptions={javascriptEnabled:true};+constlessOptions={+javascriptEnabled:true,+modifyVars:{'@primary-color':'#1da57a'},+};现在,运行start或build脚本,看看在CRA应用中引入less和使用antd的效果:$npmstartStartingthedevelopmentserver...编译成功!现在可以在浏览器中查看demo了。本地:http://localhost:3000在您的网络上:http://192.168.100.24:3000请注意,开发构建未优化。要创建生产构建,请使用npmrunbuild.webpack编译成功未发现问题。在不弹出的情况下调整CRA测试配置。CRA测试是基于jest内部打包的,不是webpack。对于jest,wuzzle提供了两种自定义配置的方式:将jest自身编译替换为兼容的wepback编译,用户修改webpack编译配置。继续使用jest自己编译,用户修改jest编译配置。下面看看如何通过这两种方式引入less来保持测试脚本的兼容性。方法1回到package.json,编辑scripts,为测试脚本挂载wuzzle:"scripts":{-"test":"react-scriptstest",+"test":"wuzzlereact-scriptstest",},然后,运行带参数--dry-run的测试脚本,查看webpack编译出来的配置,而不是jest本身:$npmtest----dry-run#...@wuzzle/cli:applyConfigWebpackconfigwith区别:{#...模块:{规则:[{测试:/\.(js|jsx|mjs|cjs|ts|tsx)$/,排除:/node_modules/,使用:#...},{测试:/\.css$/,排除:/node_modules/,使用:[{loader:'.../null-loader/...'}]},{测试:/\.svg$/,排除:/node_modules/,使用:#...},{排除:[/\.(js|jsx|mjs|cjs|ts|tsx|json|css|svg)$/,/node_modules/],使用:#。..}]},#...}可以发现只需要在css配置中添加.less文件的匹配,在bottom配置中去掉.less文件的匹配即可。回到wuzzle.config.js,修改替换jest自身的webpack编译配置:module.exports=(webpackConfig,webpack,wuzzleContext)=>{const{commandArgs}=wuzzleContext;//...+if(commandArgs[0]==='test'){+constcssRule=firstRule(webpackConfig,{file:'index.css'});+cssRule.test=[cssRule.test,/\.less$/];++constfallbackRule=firstRule(webpackConfig,{file:'index.fallback'});+fallbackRule.exclude.push(/\.less$/);+}};现在,运行测试脚本,看看在CRA测试中引入了less效果是:$npmtest#...File'src/setupTests.ts'compiled.File'src/App.test.tsx'compiled.File'src/App.tsx'compiled.File'src/App.less'compiled.File'src/logo.svg'已编译。通过src/App.test.tsx(10.183秒)?呈现学习反应链接(40毫秒)测试套件:1个通过,1个总测试:1个通过,1个总快照:0总时间:11.005秒运行与更改文件相关的所有测试套件。方法2回到package.json,再次编辑scripts的测试脚本,加入参数--no-webpack关闭webpack编译:"scripts";:{-"test":"wuzzlereact-scriptstest",+"test":"wuzzlereact-scriptstest--no-webpack",},然后,使用参数--dry-run运行测试脚本查看jest自编译配置:$npmtest----dry-run#...@wuzzle/cli:applyConfigJestconfig区别:{#...transform:[['^.+\\.(js|jsx|mjs|cjs|ts|tsx)$','.../node_modules/react-scripts/config/jest/babelTransform.js',{}],['^.+\\.css$','.../node_modules/react-scripts/config/jest/cssTransform.js',{}],['^(?!.*\\.(js|jsx|mjs|cjs|ts|tsx|css|json)$)','.../node_modules/react-scripts/config/jest/fileTransform.js',{}]],#...}这个配置和jest的用户配置略有不同,jest内部使用配置、结构参考ProjectConfig与方法一类似,只是在css配置中添加对.less文件的匹配,在bottom配置中去掉对.less文件的匹配。回到wuzzle.config.js,先新建一个对象,把原来直接导出的方法放到modify字段导出:module.exports={modify(webpackConfig,webpack,wuzzleContext){//把直接导出的顶层在这里发挥作用。},};之后继续在wuzzle.config.js中添加jest字段修改jest编译配置:module.exports={modify(webpackConfig,webpack,wuzzleContext){//...},+jest(jestConfig,jestInfo,wuzzleContext){+for(consttransformItemofjestConfig.transform){+constfileRegExp=newRegExp(transformItem[0]);+if(fileRegExp.test('index.css')){+transformItem[0]='^.+\\.(css|less)$';+}+if(fileRegExp.test('index.fallback')){+transformItem[0]='^(?!.*\\.(js|jsx|mjs|cjs|ts|tsx|css|less|json)$)';+}+}+},};现在运行测试脚本,在CRA测试中也可以看到引入less的效果。不同的是,因为关闭了webpack编译,所以性能可能会更好。进一步定制至此,CRA应用程序的所有脚本都已定制,不再需要弹出脚本。可以在真实项目中编辑package.json:"scripts":{-"eject":"react-scriptseject",}过程中,SSR(服务端渲染),E2E(端到端测试),也可以使用eslint的深入配置。关于如何结合CRA和wuzzle进一步构建真正的应用,可以参考官方示例e2e/.../react-scripts。写在最后目前,文章中的示例工程已经收录在wuzzle-blog/.../demo中,读者朋友可以根据需要打开参考。如果您有任何问题或想法,请留言。另外,如果大家对wuzzle有什么问题或者想法,欢迎在wuzzle/issues新建一期,中英文双语。如果您有兴趣并且有时间贡献代码,欢迎您提交PR。详情请参考开发指南。最后,如果觉得小工具有帮助的话,可以在GitHubrepowuzzle上点个小??来比个心。阅读更多Wuzzle,基于webpack的JS转译