巨型 Vue 应用
我最近冒了很大的风险,离开了 Netlify,去追寻一个千载难逢的机会——创业。Subs 目前正在开发中。你可以在我们的 Launchrock 上阅读所有相关信息,并注册获取最新资讯。
Subs 让密码管理变得无缝衔接,无需反复输入主密码。我和一位我非常敬重的人一起加入了这家初创公司,并且已经全身心投入到这个激动人心的新项目。这并非我第一次从构思到生产一个新产品,但它已经为我带来了全新而有趣的挑战。
这个项目的架构与我过去的做法略有不同。通常情况下,我会采用我熟悉的架构:一个 Web 应用,随着时间的推移逐渐发展壮大。我的计划不是为少数几个平台提供大量优秀的功能,而是为多个平台(包括 Web、移动、桌面和浏览器扩展)提供一个单一、构建良好、性能卓越的主要功能。
架构和工具
这家初创公司的代码库规模庞大,将使用一个 Mono-repo 来存放八个独立的项目,涵盖我们所有目标平台。此外,我们还将创建一个额外的“通用”项目,用于存放所有共享组件、服务和商店。
在一个 repo 中这看起来可能很多,但以这种方式工作有很多好处。
我现在正在构建跨平台基础架构的基石,以便将来的开发尽可能轻松。我学到的一点是:原型通常会成为最终的代码,所以第一次就必须做好。从一开始就构建基石,让我能够给予主要功能应有的关注。
前端的大部分将由 Vue 和 NativeScript 驱动。我之前曾讨论过 Vue 的优势。对于这个项目,使用 Vue 生态系统来驱动 Web 应用程序、桌面应用程序和浏览器扩展,可以在单一代码库和“通用”代码库之间实现一定程度的可重用性,因此无需重复编写代码。
NativeScript 和 NativeScript-Vue 将用于 iOS 和 Android 应用程序。虽然它们不会直接从相同的共享组件中受益,但它可以让我们在所有应用程序实例之间共享一个 Vuex 存储来处理状态,以及共享调用 API 的服务。
经过实践检验的库对于加密相关任务至关重要。因此,为了提高安全性,我使用execa用 Python 编写了一个命令行界面来执行进程。这为我们未来的灵活性带来了保障。如果我们想用 Rust 或 Go 等其他语言重写 CLI 以获得更高的性能,它也可以作为替代方案。
项目结构
这个图可能有点让人困惑,我来解释一下。该项目至少包含四个由 Vue CLI 生成的应用程序:一个 Web 应用程序、一个桌面应用程序、一个浏览器扩展程序和一个通用库。
该common
库无需构建步骤,只需将其导入到项目中即可。当common
构建使用这些模块的项目时,common
库就会被嵌入其中。我确实需要yarn link
先运行并手动链接,但这是我README
未来会做的事情。这样,我对common
库所做的任何更改都会立即受益于热模块替换,并且我可以立即看到更改。
我可以像这样在 Web 应用程序中使用我的共享组件:
这件事很酷(除了我使用Sublime Text之外),因为我的组件库是空的,只有一个入口点。
我一次性导入了所有组件,这不像其他应用那样充分利用了tree shake的优势。如果担心这个问题,我会重新构建common
库中的导出组件。就我的情况而言,我的应用非常简单,所以可以解决这个问题。
每个应用都有packages
自己托管的node_modules
。我必须yarn
在八个项目中的每一个上运行它。而且我必须yarn link subscommon
在所有我想使用我的通用库的地方运行它。
这个解决方案无聊吗?设置过程稍微长一点,但对我来说没什么大不了的。我喜欢设置过程清晰明了,但不冗长。我喜欢少一些魔法,多一些理解。整个项目设置时间大约十分钟。能不能三分钟?也许吧。
共享状态和服务
我还共享了 Vuex store 和我的各项服务。由于 Vuex 是我应用中唯一使用这些服务的部分,因此它们会自行导入。
Vuex 初始化时,会将store递归注入到所有子组件中,因此你需要确保它使用的是正确的 Vue 实例。以下是我的共享 Vuex store:
import Vuex from "vuex";
import menu from "./menu";
import user from "./user";
export default function store(Vue) {
Vue.use(Vuex);
const store = new Vuex.Store({
modules: {
menu,
user,
... more stuff
}
});
return store;
}
我没有导入上面的 Vue,因为我将 Vue 传递到我的 Web 应用程序和桌面应用程序中,如下所示:
import Vue from "vue";
import App from "./App.vue";
import { store } from "subscommon";
Vue.config.productionTip = false;
new Vue({
store: store(Vue),
render: h => h(App)
}).$mount("#app");
现在 Vuex 可以正确地锁定到应用程序并用 填充任何子组件$store
。
各部分之和
该项目结构允许我在各种目标平台上快速迭代主要应用程序,从而实现其目的。
有多快?我能够在五分钟内初始化Vue CLI Electron Builder,导入我的商店,并获得桌面应用程序的精确运行副本,而无需更改任何代码。
我的 Chrome 扩展程序也几乎同样快速地运行起来,但说实话,我花了几个小时才理解 Chrome 扩展程序的工作原理,所以花了一些时间阅读文档。使用Vue CLI 插件浏览器扩展程序让我能够非常快速地启动并运行,并且保证所有扩展程序之间的代码更改最少。只有亲眼看到才会相信,但我还没有真正做到这一点。
与此同时,我的桌面应用非常小巧,功能齐全。文件结构如下:
我保留它HelloWorld
作为我所有应用程序的入口点,因为这是 Vue CLI 3 的框架方式,而且对我来说很有意义。我相信,总有一天,会有一些开发者告诉我,它不合适,需要修改。在那之前,我会保留它。
我们希望很快就能将概念验证交付给您,以便我们了解您的想法。如果您对我正在构建的项目感兴趣,并想知道我的测试版何时发布,请在 Launchrock 上注册,我会随时向您更新。
文章来源:https://dev.to/jakecodes/big-giant-vue-apps-5048