在VueJS + Nuxt上进行SPA开发的经验

我们公司主要从事在线商店的开发,我们想分享我们在VueJS + Nuxt + Laravel上开发项目的经验。

本文将讨论我们如何决定将在线商店实现为SPA:我们是如何做到的,困难,轻松。

将要讨论的站点是几乎经典的在线商店,其中包含目录,过滤器,搜索,购物篮,个人帐户,即 商店里几乎所有东西。 该项目对法人和个人具有不同的逻辑,定价和映射。

为什么选择SPA


在当前项目之前,我们在开发单页应用程序方面的经验仅由几个内部项目组成。 从某种意义上说,从某种意义上说,SPA对我们来说是一匹黑马。

对于创建项目的经验和长期建立的过程,他们对解决这些问题没有提出任何疑问,因此对与项目的发展,项目的推广和稳定性相关的问题没有明确的了解。

方法的选择在我们公司引起了激烈的辩论,规模和论据都被填补,决定非常困难。 我们的开发人员决定收集该项目几页的原型,并查看每种方法会带来什么困难。 这种方法为我们提供了最终解决方案。 原型表明,管理站点状态(目录,购物篮,结帐等)更加舒适,并且在SPA版本中产生的问题更少。 由于您无需转移版面,只需向现成的组件添加逻辑,便可以显着提高排字员与程序员之间的开发和交互速度。 我们可能遇到的问题也变得更加清楚,这促使我们采取了进一步的行动。 在我们面前是技术的选择。

窗外是2017年夏季。在Twitter和媒体上,争端不会平息,它仍然会更好,会有所作为或有所反应。 我们的办公室没有顺应这一趋势。 开发人员还分为两个阵营,每个阵营都有自己的论点。 在此之前,我们每个人都已经使用了这两种技术。
有人越来越接近jsx,有人喜欢更熟悉的html或pug,有人认为不变性有助于更好地监视和管理应用程序的状态,对于某些人来说似乎过于复杂了。 另一方面,每个框架使我们有机会创建单个文件组件,并且对于这两个框架,已经存在相当稳定的库,并且具有对我们来说所有必需功能的集合(ssr,全局状态管理,路由,元数据管理)。 对于react,它是nextjs,对于vue,它是nuxtjs。 选择时的Nuxt仍处于beta版本,但相当稳定。 因为 我们的开发过程的构建方式是,首先要组成,然后构建后端部分,然后将页面布局转移到前端,因此框架的选择非常简单。 我们选择了vue和nuxtjs,因为 决定组成该站点并并行启动api。 使用这种方法,可以方便地立即组成组件并向其中添加逻辑。 我们的布局设计师采用了更接近的方法来创建其常用的html。

关于后端的一点


在服务器解决方案和总体上,用于构建后端的技术选择方面,我们采用了更为熟悉的方式。 选择的语言是php,为此我们使用laravel框架。 所有这些都在nginx上旋转。 作为数据库解决方案,我们有mysql。

开始开发,使用过的软件包和问题


Nuxt为我们提供了非常令人满意的软件包,用于管理应用程序状态(vuex)和路由(vue-router)。 因此,可以立即开始组装项目并将逻辑固定在组件上,然后根据需要查找我们需要的软件包。 首先,当然,我需要一个与后端部分进行通信的解决方案。 为此,选择了axios,每个人都已经选择了标准的axios,然后选择了nuxt-axios-module包装器。 我们还立即帮助项目避免在环境中迷失,并以所需的配置在每个环境中运行-选择dotenv和nuxt-dotenv-module包装器。 要开始开发,这就足够了,布局过程已经开始。

第一次暂停发生在需要向布局添加图像滑块的时候。 从房间的布局一侧听到“我的滑梯在哪里,我想要jquery”。 快速浏览现成的解决方案后,发现了一些适合我们的滑块。 但是几乎每个人都以jquery的形式拖延了一个依赖关系,我不想将其添加到完成的包中,从而增加了它的大小。 有些软件包不支持服务器渲染,这对我们也很重要。 结果,选择就落在了令人毛骨悚然的地方,完全满足了我们的要求,甚至更多。 拧紧滑块后,我们的布局设计师长期处于亏损状态。 “就是全部,我还需要做其他事情吗? 只需指定一张图片列表即可使用?”

接下来是用于选择日期的组件的选择。 还有更多的运气 很快找到了我们心爱的Flatpickr的包装纸。 剩下的就是对其进行一些样式化。

该站点上的几个地方都有一张地图。 但是,因为 我们不需要完美的细节和详细的地图,在服务之间别无选择。 然而,在开发之时,甚至到现在,还没有理想的解决方案能够满足我们的所有需求。 基于所有优点和缺点,选择了Google地图和vue2-google-maps包装器。 该软件包足够大,给我们带来了很多不必要的麻烦,但它可以很好地解决其问题。

在某些形式中,我们具有用于输入电话的字段。 用户需要帮助输入电话,因为格式的选择太多了,以后处理以单一格式输入的数据会更加容易。 因此,您需要口罩。 我想使用已经熟悉的文本掩码,在这里我们很幸运,他们已经有了vue的解决方案-vue-text-mask。

这些软件包几乎涵盖了我们的所有要求。 剩下的就是跟踪组件外部的点击,这有助于vue-click-outside。 我们使用vue-backtotop实现了页面的快速滚动。 要处理日期,请使用瞬间。

最终捆绑包大小以及1兆字节来自何处


应该记住的是,选择包装的重要标准是包装的重量。

在项目的中间,我们决定分析最终项目并查看装配尺寸。 温和地说,结果令人惊讶。 app.js的帮派大小刚刚超过950kb gzip。 npm运行分析团队为我们带来了一个漂亮的图表,其中包含了所有模块的大小,从中我们意识到一些模块正在以jquery,lodash等形式提取不必要的依赖关系。 他们不得不拒绝这些包裹,并找到替代办法。 当前,整个捆绑包的大小为480kb gzip。



注意依赖关系,并定期检查应用程序的大小。

初始加载页面和api获取的数据


Nuxt提供了一个方便的机会,可以在加载客户端之前在服务器端用数据填充商店。 为此,使用动作nuxtServerInit。 对于我们来说看起来像这样:



由于我们同时在多个组件中使用类别和某些其他实体,因此对我们来说,立即将它们放入商店更方便。

但是这里得到的json大小有问题。 由于服务器将所有接收到的数据发送给客户端以进行初始呈现,因此html大小可能太大。 当我们在类别中开始传输属于每个类别的所有页面上不需要的图像,描述和其他字段时,我们遇到了这一问题。 json大小超过2mb。 幸运的是,可以通过从服务器提供的数据中删除不必要的字段来轻松解决此问题。

内存泄漏


一段时间后,在测试服务器上的应用程序上,我们开始观察到内存消耗的异常增加。 pm2占据了所有服务器内存的90%,应用程序定期崩溃。 在github页面上,nuxt已经挂了几个有相同问题的问题。

当我们在页面的asyncData方法中发出多个请求时,出现了问题。



幸运的是,nuxt开发人员迅速解决了这个问题,目前该进程消耗了大约40mb的内存。

有趣的问题及其解决方案


组成文章
在站点控制面板中,可以添加文章并将各种块插入到文章内容中,例如带有商品的块。



来自服务器的HTML看起来像这样:



$ product-4表示应使用标识符为4的Product.vue组件代替此指针,Vue为我们提供了使用render方法渲染该组件的广泛可能性。 首先,我们在到达的html中查找对指向组件的指针的所有引用,并通过api获取显示该组件所需的数据。 接下来,我们将整个html分成一棵树。 喜马拉雅图书馆为我们提供了帮助。 然后,我们通过将指针替换为现成的组件来收集html。

...而且没有足够的力量来撰写文章)他们在项目开发期间于2017年夏天开始撰写文章,而在院子里已经是2018年夏天,该项目已经启动,而文章尚未发布。
因此,我们发布了我们收集的内容,但仍然有许多有趣的主题和观察。
如果这会很有趣-写下来就可以了))好吧,您错过了还有什么有趣的消息。

我想说这个项目已经进行了大约4个月。 它没有特别的问题,并且网站的速度令人印象深刻,并使其与其他商店区分开。

Source: https://habr.com/ru/post/zh-CN414137/


All Articles