Bubbly修改项目名称教程|快速更改项目名方法

2026-06-15阅读 0热度 0
其他
在Bubbly项目中执行项目重命名,看似简单,但若未同步更新所有关联依赖,轻则构建失败,重则运行时连主类都定位不到。重命名涉及工程文件夹名、配置文件中的标识符、源码内的硬编码引用以及构建产物的显示名——任何一处遗漏都会引发连锁问题。 下面直接梳理标准操作流程,助你避开常见陷阱。 首先,务必关闭Bubbly IDE或VS Code等编辑器。随后在文件管理器中定位项目文件夹,右键重命名为新名称,例如从`hello-world`改为`my-bubbly-app`,按回车确认。这一步是所有后续操作的基础——路径不统一,后续所有路径引用都会失效。 **【关键】务必同步重命名同名的 `.bubblyproj` 文件**。项目根目录下有一个与文件夹同名、扩展名为`.bubblyproj`的工程配置文件,例如原名为`hello-world.bubblyproj`,现在必须一并改为`my-bubbly-app.bubblyproj`。否则Bubbly加载时直接报错“Project file not found”。 --- ### 修改项目配置文件中的名称字段 用文本编辑器打开 `.bubblyproj` 文件,找到 `` 标签,将旧名称(例如 `HelloWorld`)替换为新名称(例如 `MyBubblyApp`),保存。接着继续查找 `` 和 `` 两个标签,确保它们的值也完全匹配新项目名。如果存在 ``,同样更新为对应的新命名空间,例如 `MyBubblyApp`。 注意:这三个字段缺一不可,遗漏任何一个都会导致最终生成的文件名或程序集名称不匹配。 --- ### 更新源码中硬编码的项目引用 打开 `src/Program.bbl`(或项目的主入口文件),检查其中是否包含类似 `project "HelloWorld"` 或 `appname: "HelloWorld"` 的声明,全部替换为新名称。 然后在整个项目范围内搜索旧名称(按Ctrl+Shift+F,关键词带英文引号,例如 `"HelloWorld"`),排除 `node_modules` 和 `dist` 目录。重点检查 `package.json` 中的 `"name"` 字段、`build.config.js` 中的 `output.dir` 和 `appInfo.title`,每一处都替换成新项目名。 如果项目启用了模块化路由或资源加载,别忘了 `public/manifest.json` 和 `public/index.html` 中的 `name`、`short_name`、``,否则浏览器标签页仍显示旧名称,前期重命名工作等于白做。 --- ### 清理缓存并验证构建 改完所有地方后,按以下顺序验证: 1. 在终端进入项目根目录,执行 `bubbly clean`。 2. 然后执行 `bubbly build`。 3. 如果构建时报错 `Error: Cannot find module './dist/HelloWorld.js'`,说明某处路径未更新——立即检查 `build.config.js` 中 `entry` 字段和 `output.filename` 是否仍残留旧名。 4. 构建成功后,运行 `bubbly serve`,访问 `http://localhost:8080`,确认页面标题、控制台输出、打包后的JS文件名都已是新名称。 整个过程并不复杂,但每一步都环环相扣。只要按这份清单走一遍,项目改名就不会翻车。 </section> </article> <section class="mobilepromptdetail_section"> <div class="mobilepromptdetail_prevnext"> <a href="https://m.cn486.com/news/4181111/" title="上一篇 万店掌远程巡店功能使用教程:从零开始掌握操作步骤"><span>上一篇</span><strong>万店掌远程巡店功能使用教程:从零开始掌握操作步骤</strong></a> <a href="https://m.cn486.com/news/4181113/" title="下一篇 生辰应用心愿单添加完整指南,人生清单设置步骤详尽教程"><span>下一篇</span><strong>生辰应用心愿单添加完整指南,人生清单设置步骤详尽教程</strong></a> </div> </section> <section class="mobilepromptdetail_section"> <div class="mobiletutorialdetail_note"> <strong>免责声明</strong> <p>本网站新闻资讯均来自公开渠道,力求准确但不保证绝对无误,内容观点仅代表作者本人,与本站无关。若涉及侵权,请联系我们处理。本站保留对声明的修改权,最终解释权归本站所有。</p> </div> </section> <section class="mobilepromptdetail_section"> <div class="mobilepromptdetail_sectionhead"><h2>相关阅读</h2><a href="/rjjc/1.html">更多</a></div> <div class="mobilepromptdetail_related"> <a href="https://m.cn486.com/news/3990645/" title="去哪儿怎么查看机票价格趋势图 去哪儿监控方法【攻略】"><div class="mobilepromptdetail_relatedtop"><span>软件教程</span><em>04-01</em></div><strong>去哪儿怎么查看机票价格趋势图 去哪儿监控方法【攻略】</strong><p>本文聚焦:教你深度运用去哪儿平台三大核心工具锁定机...</p></a> <a href="https://m.cn486.com/news/3990481/" title="携程怎么申请酒店无忧退票 携程售后方法【步骤】"><div class="mobilepromptdetail_relatedtop"><span>软件教程</span><em>04-01</em></div><strong>携程怎么申请酒店无忧退票 携程售后方法【步骤】</strong><p>操作携程“酒店无忧退票”服务有清晰的路径:用户可直...</p></a> <a href="https://m.cn486.com/news/3920450/" title="什么是BONK币?与其他迷因币有何不同?BONK 代币经济学及未来价格介绍"><div class="mobilepromptdetail_relatedtop"><span>软件教程</span><em>12-28</em></div><strong>什么是BONK币?与其他迷因币有何不同?BONK 代币经济学及未来价格介绍</strong><p>探索BONK,Solana 的领先迷因币—— 从代币经济学与...</p></a> </div> </section> <section class="mobilepromptdetail_section"> <div class="mobilepromptdetail_linktabs"> <button class="active" type="button" data-detail-link-tab="tutorial">最新教程</button> <button type="button" data-detail-link-tab="news">最新资讯</button> </div> <div class="mobilepromptdetail_links"> <div class="mobilepromptdetail_linkcol mobilepromptdetail_linkpanel active" data-detail-link-panel="tutorial"> <h3>最新教程</h3> <a href="https://m.cn486.com/news/4163727/" title="Stable Diffusion WebUI整合包下载与模型放置全指南">Stable Diffusion WebUI整合包下载与模型放置全指南</a><a href="https://m.cn486.com/news/4163728/" title="HunyuanVideo安装失败排查指南:依赖、显存与工作流问题解决">HunyuanVideo安装失败排查指南:依赖、显存与工作流问题解决</a><a href="https://m.cn486.com/news/4163729/" title="Runway官网入口与使用指南:下载注册及常见问题全解析">Runway官网入口与使用指南:下载注册及常见问题全解析</a><a href="https://m.cn486.com/news/4163730/" title="Notion AI新手入门指南:从下载到模板设置的完整教程">Notion AI新手入门指南:从下载到模板设置的完整教程</a><a href="https://m.cn486.com/news/4163740/" title="GitHub Copilot安装指南:JetBrains插件市场一键配置与激活全流程">GitHub Copilot安装指南:JetBrains插件市场一键配置与激活全流程</a><a href="https://m.cn486.com/news/4163741/" title="2026年ComfyUI安装与配置终极指南:从零部署到高效出图全流程解析">2026年ComfyUI安装与配置终极指南:从零部署到高效出图全流程解析</a><a href="https://m.cn486.com/news/4163742/" title="CogVideoX安装包获取与部署指南:从下载到剪辑机配置的完整教程">CogVideoX安装包获取与部署指南:从下载到剪辑机配置的完整教程</a><a href="https://m.cn486.com/news/4163769/" title="2024图像识别实战精选:基于EasyDL的完整案例解析与测评">2024图像识别实战精选:基于EasyDL的完整案例解析与测评</a> </div> <div class="mobilepromptdetail_linkcol mobilepromptdetail_linkpanel" data-detail-link-panel="news"> <h3>最新资讯</h3> <a href="https://m.cn486.com/news/4187867/" title="降低AI率必看:10条指令+3款工具推荐">降低AI率必看:10条指令+3款工具推荐</a><a href="https://m.cn486.com/news/4187868/" title="跨页表格自动拼接技术实战:PDF复杂表格1:1还原引擎">跨页表格自动拼接技术实战:PDF复杂表格1:1还原引擎</a><a href="https://m.cn486.com/news/4187899/" title="Anthropic Claude Fable 5 vs Mythos 5 对比:最强通用模型评测">Anthropic Claude Fable 5 vs Mythos 5 对比:最强通用模型评测</a><a href="https://m.cn486.com/news/4187900/" title="AI生成代码合并责任:谁该负责?">AI生成代码合并责任:谁该负责?</a><a href="https://m.cn486.com/news/4187901/" title="企业AI调用的资产化工程实践全面攻略:收口、采集、提纯与复用">企业AI调用的资产化工程实践全面攻略:收口、采集、提纯与复用</a><a href="https://m.cn486.com/news/4187889/" title="AI代理安全测评:代码被删除的风险深度解析">AI代理安全测评:代码被删除的风险深度解析</a><a href="https://m.cn486.com/news/4187894/" title="Gemma 4本地零成本部署指南:顶级开源模型快速上手">Gemma 4本地零成本部署指南:顶级开源模型快速上手</a><a href="https://m.cn486.com/news/4187895/" title="自然语言转SQL排行榜:AI查询数据工具推荐">自然语言转SQL排行榜:AI查询数据工具推荐</a> </div> </div> </section> </main> <footer class="mobilehome_footer"> <div class="mobilehome_footerbrand"> <img src="/style/style2026/mobile/image/logo.png" alt="菜鸟AI" /> <div class="mobilehome_footerbrandtext"> <strong>菜鸟AI</strong> <span>www.cn486.com</span> </div> </div> <p class="mobilehome_footerslogan">菜鸟AI,聚合 AI 提示词、教程、资讯和实用工具内容。</p> <div class="mobilehome_footerlinks"> <a href="/aitsc/1.html" title="提示词模板">提示词模板</a> <a href="/aijiaocheng/1.html" title="AI教程">AI教程</a> <a href="/zixun/1.html" title="最新资讯">最新资讯</a> <a href="/aiapp/1.html" title="热门应用">热门应用</a> <a href="/tag/" title="标签聚合">标签聚合</a> <a href="/newlist/1" title="最新更新">最新更新</a> </div> <div class="mobilehome_footerdivider"></div> <div class="mobilehome_footercopyright">Copyright © 2019-2020 菜鸟AI All Reserved</div> </footer> <div class="mobilehome_authmask"></div> <div class="mobilehome_authmodal" id="mobilehomeAuthModal"> <div class="mobilehome_authinner"> <div class="mobilehome_authhead"> <div> <strong>欢迎回来</strong> <span>登录或注册后,可保存提示词和历史记录</span> </div> <button class="mobilehome_authclose" type="button" data-auth-close>×</button> </div> <div class="mobilehome_authtabs"> <button class="mobilehome_authtab active" type="button" data-auth-tab="login">登录</button> <button class="mobilehome_authtab" type="button" data-auth-tab="signup">注册</button> </div> <div class="mobilehome_authpanel active" data-auth-panel="login"> <div class="mobilehome_authfield"> <label>用户</label> <input type="text" placeholder="请输入用户" data-auth-login-account autocomplete="username" /> </div> <div class="mobilehome_authfield"> <label>密码</label> <input type="password" placeholder="请输入密码" data-auth-login-password autocomplete="current-password" /> </div> <button class="mobilehome_authsubmit" type="button" data-auth-submit="login">立即登录</button> <div class="mobilehome_authtips" data-auth-message="login">登录后可同步收藏、历史记录和常用模板</div> </div> <div class="mobilehome_authpanel" data-auth-panel="signup"> <div class="mobilehome_authfield"> <label>用户</label> <input type="text" placeholder="请输入用户" data-auth-signup-account autocomplete="username" /> </div> <div class="mobilehome_authfield"> <label>设置密码</label> <input type="password" placeholder="请设置登录密码" data-auth-signup-password autocomplete="new-password" /> </div> <div class="mobilehome_authfield"> <label>确认密码</label> <input type="password" placeholder="请再次输入密码" data-auth-signup-repassword autocomplete="new-password" /> </div> <button class="mobilehome_authsubmit" type="button" data-auth-submit="signup">创建账号</button> <div class="mobilehome_authtips" data-auth-message="signup">注册即表示同意服务条款与隐私政策</div> </div> </div> </div> <script src="/style/style2026/mobile/js/common.js"></script> <script> var _hmt = _hmt || []; (function() { var hm = document.createElement("script"); hm.src = "https://hm.baidu.com/hm.js?b1da9d0df3e9fa6302d4a5bfdb96b4fa"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); })(); </script> <script> (function () { var fallback = "/style/style2026/mobile/image/logo.png"; function markLoaded(img) { img.classList.add("is-loaded"); } function bindImage(img) { if (!img || img.dataset.safeImageBound === "1") return; img.dataset.safeImageBound = "1"; img.addEventListener("load", function () { markLoaded(img); }); img.addEventListener("error", function () { if (img.dataset.fallbackApplied === "1") { markLoaded(img); return; } img.dataset.fallbackApplied = "1"; img.src = fallback; }); if (img.complete) { if (img.naturalWidth > 0) { markLoaded(img); } else if (img.src !== fallback) { img.dataset.fallbackApplied = "1"; img.src = fallback; } } } function scanImages() { var images = document.querySelectorAll(".mobilehome_page img"); for (var i = 0; i < images.length; i++) { bindImage(images[i]); } } function observeImages() { if (!window.MutationObserver || !document.body) return; var observer = new MutationObserver(function (mutations) { for (var i = 0; i < mutations.length; i++) { var nodes = mutations[i].addedNodes; for (var j = 0; j < nodes.length; j++) { var node = nodes[j]; if (!node || node.nodeType !== 1) continue; if (node.matches && node.matches("img")) { bindImage(node); } if (node.querySelectorAll) { var nestedImages = node.querySelectorAll("img"); for (var k = 0; k < nestedImages.length; k++) { bindImage(nestedImages[k]); } } } } }); observer.observe(document.body, { childList: true, subtree: true }); } if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", function () { scanImages(); observeImages(); }); } else { scanImages(); observeImages(); } })(); </script> <script> (function () { var apiBase = "/index.php?m=member&c=mini_ai&a="; var mask = document.querySelector(".mobilehome_authmask"); var modal = document.querySelector(".mobilehome_authmodal"); var loginButton = document.querySelector('[data-auth-open="login"]'); var signupButton = document.querySelector('[data-auth-open="signup"]'); var tabs = document.querySelectorAll("[data-auth-tab]"); var panels = document.querySelectorAll("[data-auth-panel]"); function setMessage(type, text) { var node = document.querySelector('[data-auth-message="' + type + '"]'); if (node) node.textContent = text; } function switchAuthTab(target) { for (var i = 0; i < tabs.length; i++) { tabs[i].classList.toggle("active", tabs[i].getAttribute("data-auth-tab") === target); } for (var j = 0; j < panels.length; j++) { panels[j].classList.toggle("active", panels[j].getAttribute("data-auth-panel") === target); } } function openAuth(target) { if (!mask || !modal) return; switchAuthTab(target || "login"); mask.classList.add("active"); modal.classList.add("active"); document.body.style.overflow = "hidden"; } function closeAuth() { if (!mask || !modal) return; mask.classList.remove("active"); modal.classList.remove("active"); document.body.style.overflow = ""; } function renderUser(data) { var isLogin = data && parseInt(data.is_login || 0, 10) === 1; if (!loginButton || !signupButton) return; if (isLogin) { var name = data.nickname || data.username || data.email || "已登录"; loginButton.textContent = name; loginButton.removeAttribute("data-auth-open"); loginButton.classList.add("is-logined"); signupButton.textContent = "退出"; signupButton.setAttribute("data-auth-open", "logout"); signupButton.classList.add("ghost"); } else { loginButton.textContent = "登录"; loginButton.setAttribute("data-auth-open", "login"); loginButton.classList.remove("is-logined"); signupButton.textContent = "注册"; signupButton.setAttribute("data-auth-open", "signup"); signupButton.classList.remove("ghost"); } } function ajaxPost(action, data, done) { if (!window.jQuery) return; $.post(apiBase + action, data, function (res) { done(res || {}); }, "json").fail(function () { done({status: 0, msg: "请求失败,请稍后重试"}); }); } function fetchUser() { if (!window.jQuery) return; $.ajax({ url: apiBase + "public_quota&_t=" + new Date().getTime(), dataType: "json", timeout: 5000, cache: false }).done(function (res) { if (res && res.status == 1) renderUser(res.data || {}); }); } function submitLogin(button) { var account = document.querySelector("[data-auth-login-account]"); var password = document.querySelector("[data-auth-login-password]"); var username = account ? account.value.trim() : ""; var pass = password ? password.value : ""; if (!username || !pass) { setMessage("login", "请输入账号和密码"); return; } button.disabled = true; setMessage("login", "正在登录..."); ajaxPost("public_login", {username: username, password: pass}, function (res) { button.disabled = false; if (res.status == 1) { setMessage("login", "登录成功"); window.location.reload(); } else { setMessage("login", res.msg || "登录失败,请检查账号密码"); } }); } function submitSignup(button) { var account = document.querySelector("[data-auth-signup-account]"); var password = document.querySelector("[data-auth-signup-password]"); var repassword = document.querySelector("[data-auth-signup-repassword]"); var username = account ? account.value.trim() : ""; var pass = password ? password.value : ""; var pass2 = repassword ? repassword.value : ""; if (!username || !pass) { setMessage("signup", "请输入账号和密码"); return; } if (pass !== pass2) { setMessage("signup", "两次输入的密码不一致"); return; } button.disabled = true; setMessage("signup", "正在创建账号..."); ajaxPost("public_register", {username: username, password: pass}, function (res) { button.disabled = false; if (res.status == 1) { setMessage("signup", "注册成功"); window.location.reload(); } else { setMessage("signup", res.msg || "注册失败,请稍后重试"); } }); } document.addEventListener("click", function (event) { var open = event.target.closest ? event.target.closest("[data-auth-open]") : null; if (open) { var target = open.getAttribute("data-auth-open"); if (target === "logout") { ajaxPost("public_logout", {}, function () { renderUser({is_login: 0}); }); } else { openAuth(target); } } var close = event.target.closest ? event.target.closest("[data-auth-close]") : null; if (close) closeAuth(); var tab = event.target.closest ? event.target.closest("[data-auth-tab]") : null; if (tab) switchAuthTab(tab.getAttribute("data-auth-tab")); var submit = event.target.closest ? event.target.closest("[data-auth-submit]") : null; if (submit) { var type = submit.getAttribute("data-auth-submit"); if (type === "login") submitLogin(submit); if (type === "signup") submitSignup(submit); } }); if (mask) mask.addEventListener("click", closeAuth); fetchUser(); })(); </script> <script> (function(){var tabs=document.querySelectorAll("[data-detail-link-tab]"),panels=document.querySelectorAll("[data-detail-link-panel]");for(var i=0;i<tabs.length;i++){tabs[i].addEventListener("click",function(){var target=this.getAttribute("data-detail-link-tab");for(var j=0;j<tabs.length;j++)tabs[j].classList.toggle("active",tabs[j]===this);for(var k=0;k<panels.length;k++)panels[k].classList.toggle("active",panels[k].getAttribute("data-detail-link-panel")===target);});}})(); </script> </div> </body> </html>