编程导航开发经验话题讨论

开发经验

15 参与
分享

快来分享你的内容吧~

点击登录,快来和大家讨论吧~
表情
图片
话题
打卡
综合
交流
文章
问答

智能 bi 项目前端部分怎么报错了[撇嘴][撇嘴][撇嘴]

微信公众号网页本地开发环境搭建

<html> <head></head> <body> <div class="content ql-editor"> <h2>前言</h2> <p>大家好,我是松柏。</p> <p>前两天公司要我配合前端同学开发微信公众号网页,需要我在本地提供开发环境,这个过程中也是踩了几个大坑,今天把这个过程整理出来分享给大家,希望对大家有所帮助。</p> <h2>公众号网页的好处</h2> <p>那我们首先要了解下为什么要做微信公众号网页,它有什么好处呢?</p> <ol> <li data-list="ordered"><span class="ql-ui"></span>首先就是微信拥有广泛的用户基础,公众号网页可以直接在微信内为用户提供服务。</li> <li data-list="ordered"><span class="ql-ui"></span>其次是公众号网页可以为用户提供非常方便的交互体验,在微信内就能完成阅读、购物、支付等操作。</li> <li data-list="ordered"><span class="ql-ui"></span>第三通过右上角分享或者点击链接,用户能直接进入到网站中,对产品的传播十分有利。</li> </ol> <h2>搭建步骤</h2> <p>了解了它的好处之后,我们开始搭建开发环境。</p> <p>1)申请测试号<br>一般情况下我们会使用测试号在本地开发调试,所以首先要申请测试号:<a href="https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login" target="_blank">https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login</a><br>扫码登录之后,我们会看到这个界面:<img src="https://pic.code-nav.cn/planet_post_image/1626574509983178753/d4xvc24k.jpeg" alt="image.png"></p> <p>2)接口信息配置 <br>为了本地开发调试方便, URL 我们可以填内网穿透的地址,Token 自己可以随意填。<br>需要注意的是填写的 URL 一定是公网可访问的,而且需要按照文档校验微信传过来的数据,才能够配置成功。<br>比如我这里是 http://域名/mp ,这个 url 可以访问到我本地 Java 项目,该方法如下:</p> <div class="ql-code-block-container"> <div class="ql-code-block"> public String check(String timestamp, String nonce, String signature, String echostr) throws WxErrorException { if (wxMpService.checkSignature(timestamp, nonce, signature)) { return echostr; } else { return ""; } } </div> </div> <blockquote> <p>wxMpService 对象来自 <a href="https://github.com/Wechat-Group/WxJava" target="_blank">wxJava</a></p> </blockquote> <p>3)配置 JS 接口安全域名<br>这里可以直接写本地的 ip <br><img src="https://pic.code-nav.cn/planet_post_image/1626574509983178753/kd7wgzqn.jpeg" alt="image.png"></p> <p>4)关注测试号<br>这一步是必须的,关注之后我们才能使用后续的一些接口<br><img src="https://pic.code-nav.cn/planet_post_image/1626574509983178753/cghg87g8.jpeg" alt="image.png"></p> <p>5)设置授权回调页面域名<br>这一步的目的是保证我们在公众号网页获取用户相关数据时,能够正确地回调到指定接口或页面<br>首先找到下图中的选项,点击修改:<br><img src="https://pic.code-nav.cn/planet_post_image/1626574509983178753/66uweet3.jpeg" alt="image.png"><br><img src="https://pic.code-nav.cn/planet_post_image/1626574509983178753/5eqkqbgb.jpeg" alt="image.png"><br>这里我们直接填前端的调试地址就可以<br>可能有小伙伴好奇,既然是回调地址,为什么不直接写后端地址,处理完登录逻辑之后再重定向到前端呢?<br>这里的原因我们在最后一步解释</p> <p>6)前端跳转到授权页面<br>根据公众号的<a href="https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html#0" target="_blank">文档</a>,在前端的合适位置判断当前是否是微信环境,是的话则就跳转,参考代码如下:</p> <div class="ql-code-block-container"> <div class="ql-code-block"> if (isWechat()) { window.location.href = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=xxx&amp;redirect_uri=http%3A%2F%2F127.0.0.1:8000%2Fapi%2Flogin%2Fwx&amp;response_type=code&amp;scope=snsapi_userinfo#wechat_redirect`; } </div> </div> <p>isWechat 方法可以根据 UA 判断实现。<br>可以看到,我在 redirect_uri 参数中传递的是一个前端地址,然后通过代理请求后端,而不是直接写后端接口,这里跟上一步是有联系的,原因我们同样在最后一步解释</p> <p>7)通过后端回调函数重定向到指定页面<br>在上一步中我们指定了 redirect_uri ,也就是微信处理完之后的回调地址,我们这一步的目的就是编写这个回调函数,处理微信返回的数据并记录登录态完成登录:</p> <div class="ql-code-block-container"> <div class="ql-code-block"> @GetMapping("/login/wx") public void userLoginByWxMpWeb(HttpServletRequest request, HttpServletResponse response, @RequestParam("code") String code) throws IOException { // todo 根据 code 获取用户信息并记录登录态 response.sendRedirect("http://localhost:8000"); } </div> </div> <p>为什么我们不在 redirect_uri 中直接写后端地址呢?<br>我们梳理一下这个过程:</p> <blockquote> <p>tip: 我这里的场景是前端通过代理访问后端,如果是直接访问后端应该就不会有上述问题</p> </blockquote> <ol> <li data-list="ordered"><span class="ql-ui"></span>微信网页环境下,浏览器访问微信服务器</li> <li data-list="ordered"><span class="ql-ui"></span>微信服务器处理后将请求重定向到 redirect_uri</li> <li data-list="ordered"><span class="ql-ui"></span>redirect_uri 处理后重定向到前端地址</li> </ol> <p>其中,我们会在 redirect_uri 这个回调中处理并记录用户的登录态,也就是 cookie 的 domain 是 redirect_uri 的域名,如果 redirect_uri 与前端地址的域名不一致,那么从前端访问发起请求的时候就不会携带上述的 cookie ,导致无法登录。示意图如下: <img src="https://pic.code-nav.cn/planet_post_image/1626574509983178753/f8h1a41y.jpeg" alt="时序图.png"> 8)通过微信开发者工具调试<br>使用官方的开发工具可以方便的模拟出微信环境,首先点击公众号网页项目: <br><img src="https://pic.code-nav.cn/planet_post_image/1626574509983178753/31cgwh1s.jpeg" alt="image.png"><br> 然后输入项目地址:<br><img src="https://pic.code-nav.cn/planet_post_image/1626574509983178753/imukqdk9.jpeg" alt="image.png"><br>到这里开发环境的准备就完成了</p> <h2>结语</h2> <p>经过以上步骤,我们就能在本地愉快的开发微信公众号网页啦!<br>本篇文章就到这里了,欢迎一起交流学习,再见!</p> #开发环境搭建# </div> </body> </html>

鱼皮的 Bug 修复手册上线

<html> <head></head> <body> <div class="content ql-editor"> <p>鱼友们好,我的 Bug 修复手册上线啦!</p> <p></p> <p><strong>当然是免费的</strong> ,放在了我们编程导航网站上:<a href="https://www.codefather.cn/course/bug" target="_blank">https://www.codefather.cn/course/bug</a></p> <p></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1601072287388278786/cvra6lfx.jpeg" alt=""></p> <p></p> <p>下面简单介绍一下这个手册。</p> <p></p> <h2>为什么要做 Bug 修复手册?</h2> <p></p> <p>鱼皮带大家做项目多年,发现大家遇到的很多编程方面的问题其实都是 <strong>通用</strong> 的。</p> <p></p> <p>比如为什么前端网页打不开啦!为什么没办法登录了!为什么后端项目启动不了啦!为什么数据查询不出来啦!等等等等这一系列的问题。对于刚开始学做项目的同学来说,这些 Bug 属实让人头疼。</p> <p></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1601072287388278786/xtq2f0p4.jpeg" alt=""></p> <p></p> <p>但如果每次遇到 Bug,都去找人求助,其实你自身的能力并不会得到有效的提升,时间久了,反而会养成 “伸手党” 的习惯。所以,最好在遇到 Bug 前,先尝试自己解决。</p> <p></p> <p>授人以鱼不如授人以渔,为提高 Bug 的解决效率、带大家掌握解决 Bug 的套路、提升自主解决问题的能力,鱼皮决定打造了这份《程序员 Bug 修复手册》。</p> <p></p> <h2>手册大纲</h2> <p></p> <p>手册主要分为如下 3 部分:</p> <p></p> <h4>1、解决 Bug 的流程套路</h4> <p></p> <p>这部分不涉及具体的 Bug,是一些方法论和经验,做项目前必读。</p> <p></p> <p>比如解决 Bug 的流程和套路:</p> <p></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1601072287388278786/49ereyq0.jpeg" alt=""></p> <p></p> <p>常见的请求错误码解释及解决方案:</p> <p></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1601072287388278786/nod13j9h.jpeg" alt=""></p> <p></p> <h4>2、经典 Bug 解决方案</h4> <p></p> <p>根据大家过去向我发起的项目相关的提问,我整理了一些常见的、经典的 Bug,大家可以根据需要查找和阅读。</p> <p></p> <p>比如前端框架初始化错误、数据查询为空等等:</p> <p></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1601072287388278786/107p2cfc.jpeg" alt=""></p> <p></p> <h4>3、Bug 案例分享</h4> <p></p> <p>收录了鱼皮本人和一些博主分享的真实 Bug 踩坑和排查过程,感兴趣的同学可以阅读长见识。看别人解决 Bug 还是很爽的哈哈!</p> <p></p> <p>目前这部分文章不多,还在持续更新中,大家有遇到有趣的 Bug 或者好的文章也欢迎推荐。</p> <p></p> <hr> <p></p> <p>Bug 修复手册:<a href="https://www.codefather.cn/course/bug" target="_blank">https://www.codefather.cn/course/bug</a></p> <p></p> <p>祝大家都能成长为 Bug 解决小能手~(当然没 Bug 更好哈哈)</p> <p>#开发经验#</p> </div> </body> </html>

分享下鱼厂的研发规范

<html> <head></head> <body> <div class="content ql-editor"> <p>前几天我分享了自己 <a href="https://mp.weixin.qq.com/s/PLlTO3xq6eheDJKUu9j4IA" target="_blank">创业一周年的复盘总结</a> ,其中提到了一点:随着团队的扩大,我们会更注重研发规范和技术沉淀。</p> <p></p> <p>有程序员朋友就问了:啥是研发规范?</p> <p></p> <p>还有朋友表示:鱼皮别拿咱当外人,把你们公司的研发规范发来看看?</p> <p></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1601072287388278786/tql7scss.jpeg" alt="" style="" width="316"></p> <p></p> <p>可以,必须安排!</p> <p></p> <p>这篇文章就给大家简单分享下我们公司的研发规范,不过在开始前必须要明确 2 点:</p> <p></p> <ol> <li data-list="ordered"><span class="ql-ui"></span>每个团队都应该根据情况定制自己的研发规范,别人的规范仅供参考,未必最适合你们团队。</li> <li data-list="ordered"><span class="ql-ui"></span>篇幅有限,本文仅分享一些我认为很重要的规范,并且移除了我们自己的敏感信息。</li> </ol> <p></p> <h2>一、项目整体研发流程</h2> <p></p> <p>1)团队共同确认目标和规划</p> <p></p> <p>开会讨论,产出目标和规划文档</p> <p></p> <p>2)产品调研和需求分析</p> <p></p> <p>产出调研报告和需求分析文档</p> <p></p> <p>3)需求评审</p> <p></p> <p>开需求评审会,明确要做的需求和工作,评估工作量并明确工作时间节点。</p> <p></p> <p>4)方案设计</p> <p></p> <p>产出方案设计文档,比如数据库表设计、页面设计、接口设计等。</p> <p></p> <p>5)研发</p> <p></p> <p>包括各自开发、单元测试、前后端联调等</p> <p></p> <p>6)测试和验收</p> <p></p> <p>包括研发自测、产品验收、组内验收等</p> <p></p> <p>7)代码提交</p> <p></p> <p>提交可上线的代码,需要由负责人审查,通过后可合并</p> <p></p> <p>8)部署上线</p> <p></p> <p>将代码发布到服务器上,组内进行上线通知并更新上线文档,上线后需要自行验证</p> <p></p> <p>9)产品迭代</p> <p></p> <p>持续收集用户对新功能的反馈、并进行数据分析,从而验证改动效果,便于下一轮的更新迭代。</p> <p></p> <h2>二、开发规范</h2> <p></p> <h3>开发前注意事项</h3> <p></p> <p>1)确保自己充分理解了业务和需求,需要先进行整体的方案设计;尤其是对于重要需求和核心业务,必须先跟组内同学核对方案并通过后,才能下手开发,避免重复工作。</p> <p></p> <p>2)先熟悉项目再开发,建议阅读项目文档、项目代码、接口文档、前端组件文档等。</p> <p></p> <p>3)慎重引入新的依赖或类库、或者升级版本,重大依赖变更需要和组内其他成员确认。</p> <p></p> <p>4)熟悉团队已实现的功能和代码,尽量复用,避免重复开发。</p> <p></p> <p>5)熟悉团队内部的研发规范,并在 IDE 中进行相应的配置,比如前端配置 ESLint、Prettier 等代码规范插件。</p> <p></p> <h3>开发中注意事项</h3> <p></p> <p>1)开发新功能时,确保从项目仓库拉取 <strong>最新主分支</strong> 的代码。</p> <p></p> <p>2)每个功能都要新建自己的分支进行开发,<strong>千万不要直接修改主分支的代码</strong>!注意分支名称要使用英文、足够语义化,不要和其他人的混淆。</p> <p></p> <p>3)开发时,尽量复用现有的功能、模块、类、方法、对象代码。有现成的代码,就不要再重复编写。如无法复用,可以适当通过注释说明。</p> <p></p> <p>4)开发时,遵循团队内部的研发规范,尽量参考现有项目代码的写法,尤其是不要使用和原项目不一致的格式、命名、写法,避免特立独行。</p> <p></p> <p>5)开发过程中,有任何不明确的地方,不要凭空猜测,及时去联系项目的其他成员或负责人确认。</p> <p></p> <p>6)开发过程中,每隔一段时间(比如 1 - 3 天)可以使用 <code>git pull</code> 同步一下最新的主分支代码,防止合并代码冲突。</p> <p></p> <p>7)开发过程中,注意整体时间进度的把控,先完成再完美,有风险时及时反馈。</p> <p></p> <p>8)开发时,需要格外注意对异常情况的捕获和处理。</p> <p></p> <p>9)每个分支尽量保证纯净,尽量减少每次开发和提交时改动的代码量。建议每次开分支只改一个功能、Bug 或模块,不要把多个不相关的功能写在一起,并且非必要不修改。</p> <p></p> <p>10)完成部分功能开发后,一定要自测!自测时,可以 Mock 假数据。<strong>注意一定不要在线上测试、一定不要影响线上数据!</strong></p> <p></p> <h2>三、代码提交规范</h2> <p></p> <p>1)只有通过测试和产品验收的代码,才能够发起合并到主分支的 PR 请求。在这之前可以提交到自己的分支。</p> <p></p> <p>2)发起合并到主分支的 PR 前,<strong>一定要完整阅读 3 遍自己的代码</strong>,避免不规范的写法和无意义的改动。</p> <p></p> <p>3)每次合并尽量只专注于一个功能或改动,避免多个功能耦合在一起合并,提高审查效率并降低改动风险。</p> <p></p> <p>4)每次提交时,需要在 commit 信息中提供代码改动说明,还可以通过关联需求文档、测试用例、方案文档、效果截图等方式进行补充说明。</p> <p></p> <p>commit 信息可参考<a href="https://www.conventionalcommits.org/zh-hans/v1.0.0/" target="_blank">《约定式提交》文档</a>,但不做强制要求。</p> <p></p> <p>5)除非特殊情况,否则所有的代码必须经过至少一位项目负责人 Code Review 审核通过后,才能合并;并且只有合并到主分支的代码才允许发布上线。</p> <p></p> <h2>上线规范</h2> <p></p> <h3>上线前注意事项</h3> <p></p> <p>1)上线前,除了严格验证功能特性能否正常运行、并符合需求外,还要格外关注程序的:</p> <p></p> <ol> <li data-list="bullet"><span class="ql-ui"></span>健壮性。比如给用户友好的错误提示、输入校验。</li> <li data-list="bullet"><span class="ql-ui"></span>安全性。防止越权操作、输入校验。</li> <li data-list="bullet"><span class="ql-ui"></span>稳定性。尽量保证调用 100% 成功,如果有几率失败,要考虑重试或容错策略。</li> </ol> <p></p> <p>2)除非特殊情况,只有经过产品验证的功能、通过代码审核的主分支代码才允许发布上线。</p> <p></p> <p>3)除非特殊情况,尽量在工作日上线(建议周二 ~ 周四),保证上线后出了问题时能够及时修复。</p> <p></p> <h3>上线后注意事项</h3> <p></p> <p>1)上线后,一定要再次进行完整流程的测试,尤其要重点关注权限相关的功能测试。</p> <p></p> <p>2)上线后,一定要在群内及时同步上线信息,周知相关的成员,如果遇到问题第一时间反馈。</p> <p></p> <p>3)首次上线后,需要即时配置监控告警。</p> <p></p> <p>4)上线验证通过、并经过内部群成员确认后,可以在外部用户群发布版本更新公告。</p> <p></p> <p>5)上线后,即时更新项目的更新记录文档。</p> <p></p> <p>6)注意,上线不是终点。上线后的一段时间(至少一周内),一定要持续观察自己负责的功能是否正常运行、持续接受用户反馈、通过数据分析来观察新功能的效果,期间有任何问题都需要即时修复处理,并且准备好下一期的改进迭代。</p> <p>#技术# #开发经验#</p> </div> </body> </html>

复用 - 快速开发新产品的秘诀

<html> <head></head> <body> <div class="content ql-editor"> <p>在我最近发布的 <a href="https://www.bilibili.com/video/BV1iD421p7gP/" target="_blank">鱼厂一周年复盘总结</a> 中,提到了我们团队注重技术沉淀的理念。其中重要的一点就是:在开发产品时,我们尽可能地保证重复的功能只开发一次,以提高效率、降低开发成本。</p> <p></p> <p>有好学的小伙伴问:具体是怎么实现的呢?如何践行这种设计呢?</p> <p></p> <p>这个问题的确非常好,给大家简单分享一下我们快速开发新产品的秘诀。</p> <p></p> <p>其实有很多种提高开发效率、避免重复开发的方法,本质上都是 “复用”,我按照复用的粒度,从小到大依次给大家举例讲解。</p> <p></p> <p>1)代码级复用:对重复的代码进行复用,也许只是简单的几行代码。</p> <p></p> <p>举个例子,下面这段通过本地加锁让用户串行操作的逻辑,可以复用到很多逻辑中:</p> <p></p> <div class="ql-code-block-container"> <div class="ql-code-block"><span class="ql-token hljs-comment">// 锁必须要包裹住事务方法</span> <span class="ql-token hljs-type">QuestionFavourService</span> <span class="ql-token hljs-variable">questionFavourService</span> <span class="ql-token hljs-operator">=</span> (QuestionFavourService) AopContext.currentProxy(); <span class="ql-token hljs-keyword">synchronized</span> (String.valueOf(userId).intern()) { <span class="ql-token hljs-keyword">return</span> questionFavourService.doQuestionFavourInner(userId, questionId); } </div> </div> <p></p> <p>针对这种逻辑单独封装方法又有些 “小题大做” 了,所以一般我们会给可复用的关键代码打上注释,或者用 IDEA 的 region 注释进行标识,要用到的时候复制粘贴即可。</p> <p></p> <p>可以使用我们开发的 <a href="http://jianqiezhushou.com/" target="_blank">剪切助手工具</a> 保留所有复制过的代码,并进行分组,下次要粘贴时就能轻松找回。</p> <p></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1601072287388278786/m8bpqki6.jpeg" alt=""></p> <p></p> <p>2)函数级复用:将常用的功能逻辑封装成函数(方法)。比较典型的是 Service 类中的方法,比如 UserService 中编写一个获取登录用户信息的方法,很多类都可以调用;也可以将该方法复制粘贴到其他项目中。</p> <p></p> <p>3)类级别复用:将常用的一组功能封装为类或服务。比较典型的是工具类、数据访问层的 Mapper 和通用业务逻辑 Manager 类。比如获取网络请求的工具类 NetUtils、操作文件存储的服务等。</p> <p></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1601072287388278786/ciyhbwjy.jpeg" alt=""></p> <p></p> <p>4)模块级复用:遵循领域驱动设计(DDD)的思想,很多项目都是可以拆分成多个模块的,每个模块都是可复用的功能单元。说人话,其实模块就是多个相关的类的集合。比如 AI 模块,可能包含了 AI 相关的 model 数据实体、调用 AI 的 API 请求工具类、组合上下文的历史管理类等等。</p> <p></p> <p>我们在做某个新功能时,首先会思考这个功能以后有没有可能会被复用,对于评估下来可复用的功能,我们会考虑首次在项目中开发时,就把和这个功能相关的代码都放到一个目录(包)下,而不是按层级分到 Controller、Service、Model 等包中。</p> <p></p> <p>刚开始这个模块可能只有当前项目使用,并不会做的很完善,其他项目也要用时可能是先通过复制粘贴的模式;等模块逐渐完善后,再考虑是否需要将该模块独立出来,供其他项目复用。</p> <p></p> <p>5)插件和 SDK 级复用:其实就是把模块单独抽离出来,封装为可直接引入项目的插件或者 SDK 依赖包。比如我们公司内封装了自己的 AI SDK、短信 SDK、企微消息 SDK、动态公告系统插件等。(动态公告系统是我们实习生开发的,在星球内分享了教程哦:<a href="https://t.zsxq.com/19491FHYf" target="_blank">https://t.zsxq.com/19491FHYf</a> )</p> <p></p> <p>对于大一点的公司,一般会有自己的私有 Maven 和 Npm 仓库,公司内的开发同学可以将制作好的 SDK 或插件上传到私有库,其他同事通过依赖管理工具,就能直接下载。</p> <p></p> <p>6)API 级复用:区别于必须要手动引入到项目中的 SDK 或插件,将功能封装为 API 接口供其他项目调用,会是一种更灵活、更解耦合的方式。比如我们将在线执行代码的能力单独部署到了一些服务器上,供所有项目一行代码调用。</p> <p></p> <p>有同学可能会问了:什么情况下要提供 API?什么情况下提供 SDK 呢?</p> <p></p> <p>一般在企业中,API 常用于跨团队开发的场景,典型的就是获取其他业务的数据、或者复用其他业务的能力。比如我们想在编程导航项目中获取到代码小抄项目中的代码数据,完全没必要把获取代码小抄数据的功能抽出来封装为 SDK,这个代价太大了,不如让代码小抄项目提供一个返回代码数据的接口即可。而 SDK 更适用于封装工具库,或者和数据无关的、业务解耦的能力。</p> <p></p> <p>当然,很多时候,我们会同时提供 API 和 SDK。比如腾讯云,不仅提供给开发者在线调用的 API,还提供了 SDK 来简化 API 的调用。</p> <p></p> <p>7)系统级复用:这是成本最高的、也是收益最大的复用,比如前端项目万用模板、后端项目万用模板等,每个新项目都可以基于模板快速得到很多基础能力,大幅提高开发效率。相信大家使用编程导航内的万用模板做项目时,也能感受到这点。</p> <p></p> <p>也建议大家在做项目的过程中,注重积累,沉淀属于自己的弹药库,成为代码复用大师!</p> <p>#开发#</p> </div> </body> </html>

Bug 解决 | 项目启动失败

<html> <head></head> <body> <div class="content ql-editor"> <p>想必所有学编程的同学都遇到过这样一个问题:把别人的代码或项目拉取到自己的电脑上,然后按照别人提供的步骤去启动项目。</p> <p>结果当你自信满满地点击运行键时,就看到了:</p> <p><img src="https://pic.code-nav.cn/planet_post_image/1601072287388278786/87jzilsi.jpeg" alt=""></p> <p>这个时候,很多初学编程的同学就会慌了。为什么我和你的代码一样、操作一模一样,结果项目还启动失败了呢?!</p> <p><img src="https://pic.code-nav.cn/planet_post_image/1601072287388278786/0lokxnal.jpeg" alt=""></p> <p>不要慌,这其实是一个非常普遍的问题,也很好解决。今天这篇文章就来分享一下如何解决它。</p> <h2>项目启动失败原因</h2> <p>首先,运行一个项目,需要考虑以下几个要素:</p> <ol> <li data-list="ordered"><span class="ql-ui"></span>代码</li> <li data-list="ordered"><span class="ql-ui"></span>环境(系统、平台)</li> <li data-list="ordered"><span class="ql-ui"></span>依赖</li> <li data-list="ordered"><span class="ql-ui"></span>资源</li> </ol> <p>只要保证这 4 个要素和其他成功运行的项目一致,那么 99.9% 的概率你也能成功运行项目!</p> <h3>代码一致</h3> <p>首先是代码,这个没什么好说的,只要别人提供给你的代码是正确可运行的,直接用 git 版本控制工具 clone(拷贝)到本地即可。</p> <h3>环境一致</h3> <p>然后是最最最最重要的环境!绝大多数情况下,都是因为你本地电脑的环境和其他同学的环境不一致,才导致了报错。</p> <p>环境又包括系统、平台等。系统就是指 Windows、Linux、MacOS 等,如果是 Java 项目,因为 JVM 的存在,所以基本上不会出现系统不兼容的问题;但如果是其他不具备跨平台特性的语言,在 Win 上能跑的项目可能到 Linux 上就不能正确运行了,会出现各种各样隐藏的坑。</p> <p>平台是指运行代码需要的基本环境,比如 Node.js、Java、.NET 等。对于平台来说,最重要的莫过于 <strong>版本</strong> 了,如果版本不兼容,那么项目就很容易运行不起来,或者有很多奇奇怪怪的错误。</p> <p>就拿我给大家开源的项目代码来说,有的同学能运行,有的同学就不能运行,多半是环境版本的问题。</p> <p>比如在安装了 Java 17 的电脑上去跑 Java 8 的后端代码,在 Node 10 的电脑上去跑 Node 16 的前端代码等等。</p> <p><img src="https://pic.code-nav.cn/planet_post_image/1601072287388278786/6zv5ho79.jpeg" alt=""></p> <p>一般情况下,目前还是建议后端同学用 Java 8 和 Spring Boot 2,前端同学用 Node.js &gt;= 16 的版本,别去追求太高的版本,否则出了问题后果自负。</p> <h3>依赖一致</h3> <p>除了环境外,我们在安装项目依赖时,也同样需要注意版本。举个例子,对于前端项目来说,有些项目依赖的版本定义可能并不明确,如下图:</p> <p><img src="https://pic.code-nav.cn/planet_post_image/1601072287388278786/el0ikrcj.jpeg" alt=""></p> <p>版本号前的 <code>^</code> 的意思是版本号的末尾可以变化,所以你实际安装的版本可能和其他更早安装的依赖版本不一致,有可能就会出现代码冲突、不兼容。</p> <p>所以前端项目一般会使用 package-lock.json 文件来锁住依赖的版本号,保证不同开发人员在不同时间拉取依赖时版本都是一致的。</p> <p>而 Java 后端项目相对就简单了一些,我们写 Maven(Gradle)依赖时一般都指定一个明确的版本号,不存在版本号不一致导致的冲突。</p> <p>如果 jar 包之间冲突的话,那又是另一个故事了,可以用 Maven Helper 解决一下。</p> <p><img src="https://pic.code-nav.cn/planet_post_image/1601072287388278786/vfd6a0ha.jpeg" alt=""></p> <p>所以,如果你是跟着别人的视频教程或直接下载源码启动项目,请确保你的本地环境、依赖版本和作者的一致。一般在文档上都有明确的说明,可不要做个小马虎,跳着去看别人的文档哦。</p> <h3>资源一致</h3> <p>除了环境之外,还有一个很不起眼的因素,就是资源,像 CPU、内存、硬盘容量等等。</p> <p>比如项目需要至少 8 G 内存、10 G 硬盘,结果你的电脑只有 4 G 内存、硬盘也不够了,那么项目要么运行不起来,要么就是后期出现各种奇奇怪怪的问题。</p> <h3>其他因素</h3> <p>除了上述几个因素外,还有一些可能影响项目启动的其他因素,比如:</p> <p>1)运行所需的依赖没有启动。比如后端项目运行前一般都要启动数据库、Redis 等,可以通过认真阅读报错信息并百度来定位到问题。</p> <p>2)网络环境不一致。比如在公司的内网环境无法拉取到外网的依赖,自家网络无法拉取到国外的依赖镜像等。典型的就是 NPM 依赖或 Maven 依赖安装失败,此类报错会有明显的 “网络连接错误” 的提示,直接百度就能解决此类问题。</p> <p>3)系统权限问题。一般此类问题会有明显的 “permission” 相关的报错信息,直接百度就能解决此类问题。</p> <p>建议不要把项目放到系统目录中,或者可以使用管理员权限、<code>sudo</code> 命令(Linux / Mac 用户)来执行安装依赖、启动项目等可能需要更高权限的命令。</p> <p>4)其他细节问题。比如在存放项目代码的任何路径中,尽量不要出现中文,也可能会影响项目的运行。</p> <h2>推荐的解决方案</h2> <p>综上,我们如果拉下来别人的开源项目学习、跟着视频教程学习、或者是拉取公司的项目开发前,<strong>最先要做的事情是阅读官方文档</strong> 来确定项目运行的环境、依赖版本、需要的资源、运行条件等关键信息,跟安装游戏和软件一样的,一定要认真了解。</p> <p>以开源知识库 wiki.js 项目为例,很明确地指出了这些要求:</p> <p><img src="https://pic.code-nav.cn/planet_post_image/1601072287388278786/b1zls0bb.jpeg" alt=""></p> <p>阅读官方文档真的是非常重要的!像鱼皮在 <a href="https://yuyuanweb.feishu.cn/wiki/VC1qwmX9diCBK3kidyec74vFnde" target="_blank">编程导航知识星球</a> 里带大家做了一个用户中心项目。刚做完框架版本就大更新了,结果一些同学就一脸懵逼了。其实只要仔细阅读一遍官方文档,很多问题就迎刃而解了,不用担心和视频的操作不一致,大胆探索。</p> <p>如果认真按照官网文档的要求进行了操作,却还是无法启动项目,就要收集尽可能多地报错信息,从中找到一些关键词去百度或询问 AI。对于开源项目,可以去框架的 Github Issues 区去搜一下,比如 <a href="https://github.com/ant-design/ant-design-pro/issues" target="_blank">Ant Design Pro 框架</a>。</p> #开发经验# </div> </body> </html>

鱼皮,你好!有什么方便调试快速

鱼皮,你好!有什么方便调试快速定位的工具?比如说打印了很多种类的数据,筛选某一类以abc开头的数据,能够全部定位显示出来,不包含其他的数据

鱼皮,你好!有什么方便调试快速

鱼皮,你好!有什么方便调试快速定位的工具?比如说打印了很多种类的数据,筛选某一类以abc开头的数据,能够全部定位显示出来,不包含其他的数据

#开发经验# 省钱小技巧,服务器在刚刚购买后的几天内,是可以退款的哦~ 昨天给大家演示项目上线临时买了一台,今天退掉了,美滋滋 [呲牙]

为什么我不建议编程初学者做桌面端项目?

<html> <head></head> <body> <div class="content ql-editor"> <p><strong>直说了吧,我讨厌做桌面端项目。</strong></p> <p>鱼皮从大学期间刚学编程没多久,就跟着工作室开始做项目。至今为止做过大大小小几十个项目,网页、小程序、各种工具轮子、控制台程序、脚本都做过一些,但就是几乎没做过桌面端项目。</p> <p>哦,除了我的毕业设计之外。因为我的毕设题目是被强行敲定的,我命由天不由我,当时做了一个桌面端的图像处理软件,用的是 C++ 的 Qt 开发框架。</p> <p><img src="https://pic.code-nav.cn/planet_post_image/1601072287388278786/oml33oxh.jpeg" alt=""></p> <p>为什么我不喜欢做桌面端项目呢?</p> <p>我个人的几个原因:</p> <ol> <li data-list="ordered"><span class="ql-ui"></span>桌面端项目不利于分享。相比于网站、小程序这种应用形态,开发桌面端项目还得让用户下载安装包、还得做个官方去宣传,太麻烦了。</li> <li data-list="ordered"><span class="ql-ui"></span>桌面端项目不利于移植。以前大家可能都用 Windows,但现在选择多了,macOS、Linux 的用户也越来越多,如果你想开发一个同时兼容多个操作系统的应用,成本会比较高,要考虑到各个平台的差异和限制。</li> <li data-list="ordered"><span class="ql-ui"></span>桌面端项目的技术栈老旧。这里的老旧是相比前端 web 开发来说的,前端新技术层出不穷、越来越卷,甚至有大前端跨平台、一统客户端的野心。而桌面端技术呢?就拿 Java 桌面端开发来说吧,无论是组件还是开发框架,都少的可怜。</li> </ol> <p>所以一般情况下,如果又更好的选择,我是不会去做桌面端项目的,也不建议编程初学者去做桌面端项目。</p> <p>但是,最近我们公司在研发一个工具类的项目,由于要使用操作系统的功能,必须要让用户在自己的电脑上安装使用,所以只能选择桌面端。</p> <p>实话说,第一次带团队做桌面端项目,我是非常紧张的。因为我对桌面端开发的了解并不深,担心出现一些无法解决的问题,导致整个项目都无法完成。</p> <p>所以在做这个项目前,我给了团队的技术同学很长一段时间,专门去调研桌面端开发框架、以及通过写 Demo 的方式,调研能否实现我们项目必须的功能,而且多次开会确认。</p> <p>最终,我们选择的框架是 Electron。这是一个跨平台的桌面端开发框架,最大的优势是可以用我们技术同学最熟悉的前端语言开发,不用学习新的语言。</p> <p><img src="https://pic.code-nav.cn/planet_post_image/1601072287388278786/zp8tqlzf.jpeg" alt=""></p> <p>虽然 Electron 不是最新的跨端开发技术,但是生态还是不错的,也比较成熟,太新的框架我们反而不敢用。</p> <p>Electron 框架的实现原理是内置了浏览器的内核,相当于在桌面端里运行了我们开发的网页,所以它的一个大缺点就是打包出来的应用体积会比较大。</p> <p>但是都 5G 时代了,体积大一点我觉得并没有什么影响。</p> <p><img src="https://pic.code-nav.cn/planet_post_image/1601072287388278786/ad2m9io5.jpeg" alt=""></p> <p>开发过程中,我们遇到了不少难题,尤其是有些功能 Windows 能用、Mac 不能用,典型的兼容性问题。为了解决这些问题,我们的技术同学要来回在两个不同系统的电脑上打包测试,花费了很多时间。</p> <p><img src="https://pic.code-nav.cn/planet_post_image/1601072287388278786/nsn6s46t.jpeg" alt=""></p> <p>虽然 Electron 开发出来的桌面端程序的性能是比不过原生应用的,但是经过我们的测试验证,体验也还是 ok 的,而且绝大多数的系统能力都可以使用 Electron 来调用。</p> <p>我们也已经顺利使用 Electron 开发完了工具的核心功能,现在项目已经属于测试阶段,后面会给大家分享,期待的话请多多为我投票(点赞)吧~</p> #开发# </div> </body> </html>

下载 APP