当前位置: 首页 > Web前端 > CSS

接到一个新项目

时间:2023-03-30 17:03:57 CSS

背景最近接到一个新项目,遇到了一些问题,所以在这里整理分享一下。前期规划要求如下:需搭建后台管理系统:主系统、子系统,开发时间6周。前期开发有两个人,再加??上一个人。说实话,时间有点紧,所以提前计划很重要。实施,先做方案,技术选型,文档分析,分页,粗略评估。技术选型首先要确定的是React,即:React、Redux、TypeScript、样式管理styled-components、国际化react-intl、组件库antd、脚手架、自配置。本来想用CRA(create-react-app)省事,后来觉得用rewired重写不太灵活,有小伙伴也想自己配置。熟悉webpack后,决定自己搭建,稍后贴出配置。与后台负责人讨论开发计划后,决定将本期开发任务分为三个小阶段:P1、P2、P3在P1完成后发布,先跑通主流程,并继续迭代P2和P3中的功能。P1主要包括:开发环境搭建测试环境资源申请Nginx配置主系统功能开发三大功能模块开发登录注册流程子系统两个模块开发时间:两周压力还在,时间紧,任务重,是第一次带人做项目,还好我心里像条老狗,一点都不慌。后来进入开发阶段,遇到了很多问题。进入开发搭建开发环境,添加各种配置和打包这一步大家都很熟悉了。因为主系统和子系统的页面样式是一样的,所以没必要分成两个系统。只需要新建一个文件夹,把各个子系统的页面放在里面,然后打包成不同的包。就有了如下配置://webpack.config.jsconstpath=require('path')constHtmlWebpackPlugin=require('html-webpack-plugin')constwebpack=require('webpack')constfs=require('fs')constlessToJS=require('less-vars-to-js')const{NODE_ENV}=process.envconstisAdminApp=process.env.APP_TYPE==='admin'constgetBaseurl=()=>{switch(process.env.ENV){case'id':return'https://xxx.test.shopee.co.id'default:return''}}constplugins=[newHtmlWebpackPlugin({template:path.resolve(__dirname,'template.html'),title:isAdminApp?'WMSLITEADMIN':'WMSLITE',}),newwebpack.DefinePlugin({__BASEURL__:JSON.stringify(getBaseurl()),}),newwebpack.IgnorePlugin(/^\.\/locale$/,/moment$/)]if(NODE_ENV!=='production'){plugins.push(newwebpack.SourceMapDevToolPlugin({}))}constthemeVariables=lessToJS(fs.readFileSync(path.resolve(__dirname,'./assets/antd-custom.less'),'utf8'))constport=isAdminApp?9527:8080module.exports={entry:['@babel/polyfill',isAdminApp?'./admin/index.js':'./pages/index.js'],输出:{文件名:isAdminApp?'admin.[hash:8].js':'main.[hash:8].js',path:path.resolve(__dirname,isAdminApp?'dist/adminstatic':'dist/static'),publicPath:isAdminApp?'/admin/':'/',},mode:NODE_ENV,devtool:false,plugins,module:{rules:[{test:/\.(js|jsx)$/,exclude:/node_modules/,使用:{loader:'babel-loader',},},{test:/\.less$/,使用:[{loader:'style-loader',},{loader:'css-loader',},{loader:'less-loader',options:{javascriptEnabled:true,sourceMap:true,modifyVars:themeVariables,},}],},{test:/\.css$/,使用:[{loader:'style-loader',},{洛阿der:'css-loader',}],},{type:'javascript/auto',测试:/\.mjs$/,使用:[],},{测试:/\.(png|jpg|gif|svg)$/i,使用:[{loader:'url-loader',options:{limit:8192,},}],}],},优化:{runtimeChunk:{name:'manifest',},splitChunks:{chunks:'all',minSize:30000,minChunks:1,maxAsyncRequests:5,maxInitialRequests:3,cacheGroups:{vendor:{test:/[\\/]node_modules/,文件名:'vendor.[chunkhash:8].js',enforce:true,priority:5,},antd:{test:/[\\/]node_modules[\\/]antd[\\/]/,文件名:'antd.[chunkhash:8.js',priority:10,},antdIcons:{test:/[\\/]node_modules[\\/]@ant-design[\\/]/,文件名:'antd-icons.[chunkhash:8].js',priority:15,},styles:{test:/\.(scss|css)$/,filename:'styles.[hash:8].css',minChunks:1,reuseExistingChunk:true,enforce:true,priority:20,},},},},devServer:{historyApiFallback:isAdminApp?{重写:[{from:/.*/g,to:'/admin/index.html',}],}:true,hot:true,port,proxy:[{context:['/admin/api','/api'],target:'https://gudangku.test.shopee.co.id',changeOrigin:true,onProxyRes(proxyRes,_,res){constcookies=proxyRes.headers['set-cookie']||[]constre=/domain=[\w.]+;/iconstnewCookie=cookies.map(cookie=>cookie.replace(re,'Domain=localhost;'))res.writeHead(200,{...proxyRes.headers,'set-cookie':newCookie,})},}],},}//package.json"scripts":{"start":"NODE_ENV=developmentAPP_TYPE=ma在webpack-dev-server","build":"NODE_ENV=productionAPP_TYPE=mainwebpack","start:admin":"NODE_ENV=developmentAPP_TYPE=adminwebpack-dev-server","build:admin":"NODE_ENV=productionAPP_TYPE=adminwebpack","lint":"eslint./--extjs","i18n":"nodei18n/index.js"},根据不同参数打包,主系统打包到dist/static,子系统打包成dist/adminstatic,解决了打包问题,还有一个问题,就是在本地开发的时候需要配置proxy,目前普遍的做法是:devServer配置proxy,修改hostNginx为反向proxy.//也可以说只有2个,我用1个,原因是比较灵活,这个系统以后要发布到7个或更多的国家,换host不优雅,不是很方便,后面遇到的问题是登录的时候需要申请一个csrftoken,因为domain不匹配,所以cookie不能进入,于是改了配置,代码见devServer部分,问题解决。打包优化初步优化,代码分包,本系统antd使用较多,代码体积,业务代码明显不适合打在一个包里,所以简单划分:压缩后总体积900K。FCP1s,勉强可以接受,后期需要优化。国际化实现了`react-intl`,使用起来很简单:主要有两种形式:直接翻译:需要特殊传递,比如placeholder,titleofModal等,如果你使用1直接显示一个[objectObject]。幸运的是,react-intl提供了injectIntl??方法来解决这个问题:是一个不能放置到需要原始String的占位符的组件。用法:从'react-intl'导入{injectIntl??};类TestComponent扩展React.Component{render(){const{intl}=this.props;return()}}exportdefaultinjectIntl??(TestComponent);传入的id是自己定义的。如果有翻译平台,可以自己添加这几个键:翻译平台翻译完成后,需要手动下载到本地,感觉很麻烦,所以写了个脚本自动下载。翻译平台更新后,执行yarni18n更新一下:按照上面两种方法替换page字段,纯手工,没什么好说的。Nginx配置功能开发完成后,需要发布到测试环境,中间需要配置Nginx。我这里有个配置平台,添加配置后自动部署提单。配置的时候还是有一些问题。首先解决index.html访问路径的问题:需要配置的路径是://index.html/admin/admin/index.html首先看/和/index.html还需要配置环境和区域:/admin和/admin/index.html也是同样的配置。不过需要注意的是/和/admin需要配置try_files:/:/admin:对应生成的conf文件:什么是try_files?从字面上理解就是尝试读取文件,结合对环境的理解,就是尝试读取文件,也就是读取Whatfiletotake?读取静态文件。$uri,这是nginx的一个变量,存放的是用户访问的地址。比如:http://www.xxx.com/index.html,那么$uri就是/index。html$uri/表示访问一个目录,比如:http://www.xxx.com/hello/test/,那么$uri/就是/hello/test/完整的解释是:try_files尝试读取该网站directory获取用户访问的文件,如果第一个变量存在则直接返回;如果不存在,继续读取第二个变量,如果存在,直接返回;如果不存在,则直接跳转到第三个参数。至于为什么需要try_files,因为我们的路由是基于browserHistory的,如果使用hashHistory,就不需要配置try_files了。你可能会问,既然不用try_files也可以配置hashHistory,为什么还要用browserHistory?可能是因为加个/#/不好看:)未完待续,持续更新..5.21目前处于P3阶段,主要功能开发完成,计划5.27测试。进度没有太大问题。有什么值得分享的,以后再说吧。