大家入门react一定要从这行命令入手!命令npxcreate-react-appmy-app会生成一个项目骨架,小伙伴们可以愉快的使用了。搬了半天,发现项目越来越大,一个包好几兆,严重影响加载速度。这时候就需要多入口打包,把项目分成几个小的SPA。比如登录时有1个SPA,内容管理有1个SPA,产品管理有1个SPA。每个SPA加载公共的JS,和自己的JS,不加载不相关的。我们需要配置webpack对项目进行改造,发现项目中没有webpack.config.js。React团队像你妈妈一样为你做饭,你就吃吧。封装webpack,把你当傻子。在package.json中,你会找到一个react-scripts包。打开源码,你会发现这么晚才遇到的webpack.config.js。但是我们不能直接修改这个文件,我们可以使用下面两种方法来配置webpack。第一种方式是执行命令yarneject将封装好的配置脚本释放到当前项目中,config目录下有webpack.config.js。这个过程是不可逆的,你也将失去未来升级react-scripts能给你带来的好处。第二种方式craco感谢社区提供第二种解决方案,让你的代码可以继续保持纯净的身体。首先安装@craco/craco包。yarnadd@craco/craco在项目根目录新建craco.config.js,并覆盖该文件中默认的webpack.config。craco.config.js的配置方法请参考文档:https://www.npmjs.com/package...我们采用第二种方式实现多入口改造。改造思路:保留react-create-app默认入口,入口名称为main,js为src/index.js,使用模板public/index.html为src/entries/下的各个子目录生成index.html,创建一个同名入口,入口js为src/entries/{entry-name}/index.js,使用模板public/{entry-name}.html生成{entry-name}.html根据这个思路,我们需要把webpack的配置项的入口改成多个入口,配置插件HtmlWebpackPlugin为每个入口生成对应的HTML。其他要点:output.filename需要修改生成bundle.jsoptimization.runtimeChunk需要修改为single这样不同的entry会共享同一个runtime.js而不是每个废话都生成一个,直接打分!默认情况下,webpack运行时代码会嵌入到HTML中,可以通过在.env文件中设置INLINE_RUNTIME_CHUNK=false来禁用,或者删除InlineChunkHtmlPlugindevServerConfig.historyApiFallback并将disableDotRule设置为true,否则开发服务器会重定向/的请求xxx.html在/xxx上,入口打不开html-webpack-插件');constInlineChunkHtmlPlugin=require('react-dev-utils/InlineChunkHtmlPlugin');functionconfigureWebpack(webpackConfig,{env,paths}){constisEnvDevelopment=env==='development';constisEnvProduction=env==='生产';//配置HtmlWebpackPlugin生成独立的HTML函数mkHtmlWebpackPlugin(chunks,filename,template){returnnewHtmlWebpackPlugin({inject:true,template:template||paths.appHtml,chunks,filename,...isEnvProduction?{minify:{removeComments:true,collapseWhitespace:true,removeRedundantAttributes:true,useShortDoctype:true,removeEmptyAttributes:true,removeStyleLinkTypeAttributes:true,keepClosingSlash:true,minifyJS:true,minify,CSS:true,}}:undefined});}//遍历src/entries为所有子目录创建一个webpack入口,并配置对应的HtmlWebpackPluginconstentriesDir=path.join(paths.appSrc,'entries');constfileNames=fs.readdirSync(entriesDir);常量条目={};consthtmlWebpackPlugins=[];fileNames.forEach(fileName=>{constfilePath=path.join(entriesDir,fileName);constfile=fs.statSync(filePath);if(file.isDirectory()){entries[fileName]=path.join(filePath,"index.js");lettemplate=path.join(paths.appPublic,fileName+".html");如果(!fs.existsSync(template))template=undefined;htmlWebpackPlugins.push(mkHtmlWebpackPlugin([文件名],文件名+".html",模板));}});//main是create-react-app默认创建的入口,保留这样既可以实现原来的单入口也可以实现多入口webpackConfig.entry={main:webpackConfig.entry,...entries};//覆盖默认插件配置constdefaultHtmlWebpackPluginIndex=webpackConfig.plugins.findIndex(plugin=>plugininstanceofHtmlWebpackPlugin);webpackConfig.plugins.splice(defaultHtmlWebpackPluginIndex,1,mkHtmlWebpackPlugin(["main"],"index.html"),...htmlWebpackPlugins);//create-react-app默认使用固定文件名,不适合多入口!更改为根据条目名称生成输出文件名if(isEnvDevelopment)webpackConfig.output.filename='static/js/[name].bundle.js';//共享运行时包webpackConfig.optimization.runtimeChunk="single";//react-scripts在生产环境中默认会把runtimechunk嵌入到html中//禁用这个行为,使用独立的js//也可以在根目录下新建一个.env文件,设置INLINE_RUNTIME_CHUNK=false来禁用//但是配置入口太多了,不方便管理,这里用代码禁用就可以了如果(inlineChunkHtmlPluginIndex>=0)webpackConfig。plugins.slice(inlineChunkHtmlPluginIndex,1);returnwebpackConfig;}functionconfigureDevServer(devServerConfig,{env,paths,proxy,allowedHost}){devServerConfig.historyApiFallback={disableDotRule:true,//禁用,否则访问/xxx.html时服务器会自动去掉.html并重写/xxx索引的url:paths.publicUrlOrPath,详细:true,};returndevServerConfig;}module.exports={devServer:configureDevServer,webpack:{configure:configureWebpack,}};通过上面的代码就可以完成多入口的转换。具体实践代码可以参考https://github.com/ikeyit/ike...假设你有入口/src/entries/your-loved-mp4/index.js,访问http://localhost:3000/your-lo...打开条目。执行并编译yarnbuild,可以看到build文件夹中生成了很多js,webpack会将共享和非共享代码分到不同的包中。执行命令分析BundleSizeyarnanalyze(完)欢迎关注作者github项目,学习微服务:一个支持多店铺的电商系统,基于SpringBoot的微服务架构https://ikeyit.xyz
