
(
插图 )
高级网络开发人员Anton和Alexei继续讲述与Nuxt艰苦奋斗的故事。 在与此框架进行的上一轮抗争中 ,他们展示了如何在Nuxt上启动一个项目,以便每个人都很高兴。 在新文章中,我们将讨论框架的实际应用。我们开始以巨大的技术债务来重写该项目。 每月的访问者为6-7百万唯一身份访问者,但是现有平台造成了太多问题。 因此,决定将她送去退休。 当然,性能是我们最大的担忧,但我也不想浪费SEO。
经过几轮讨论,他们决定不依赖仅使用服务器端渲染的传统方法-而不是将自己陷入客户端渲染中。 结果,我们开始构建基于
Nuxt.js的解决方案。
好老的Nuxt.js
我们采用基于
Vue.js的“框架框架”
(在上一篇文章中已经为我们所知)来构建通用的客户端-服务器应用程序。 在我们的案例中,该应用程序与相当复杂的API(微服务的复杂性,但大约在其他时间)和多层缓存一起工作,它呈现可由编辑器编辑的内容,并返回已经静态的内容,以实现闪电般的快速性能。 太好了吧?
实际上,这里没有新内容。 但是使Nuxt.js变得有趣的是能够使用客户端-服务器渲染快速启动项目的能力。 有时您需要违背已建立的框架框架。 那就是我们所做的。
没有时间解释,一次构建,多次部署!
有一天,一个技术幻灯片接近我们并感到困惑:每当我们将更改推送到存储库时,我们都需要分别构建每个环境(开发环境,阶段环境和产品环境)。 太慢了 但是这些版本之间有什么区别? 是的,仅在环境变量中! 他要求做的事情听起来合情合理。 但是我们的第一个反应是:O_o
在软件开发领域,一次构建,部署多种策略是有意义的。 但是在Javascript世界中……我们拥有大量的编译器,编译器,预处理器和后处理器以及测试和查询器。 所有这些花费时间来为每个环境配置它们。 此外,还有许多潜在的机密数据泄漏问题(机密,API密钥等可以存储在配置中)。
然后我们开始
当然,我们首先从Google搜索开始。 然后,我们与Nuxt.js维护者进行了交谈,但是没有取得太大的成功。 怎么做-我不得不自己想出一个解决方案,而不是从StackOverflow复制它(这是我们活动的基础,对吗?)。
让我们弄清楚Nuxt.js是如何做到的。
Nuxt.js具有一个预期名称为nuxt.config.js的配置文件。 它用于以编程方式将配置传输到应用程序:
const config = require('nuxt.config.js') const nuxt = new Nuxt(config)
可以通过env变量设置环境。 通常,一种相当普遍的做法是动态连接配置文件。 然后,所有这些都将传输到definePlugin Webpack并可以在客户端和服务器上使用,如下所示:
process.env.propertyName
//或
context.env.propertyName。
这些变量在组装过程中烘焙,有关更多信息,请
参见 :
Nuxt.js env页面 。
您是否注意到webpack? 是的,这意味着编译,而这不是我们想要的。
让我们尝试不同
了解Nuxt.js的工作方式对我们意味着:
- 我们不能再在nuxt.config.js中使用env了;
- 任何其他动态变量(例如,在head.meta内部)都应在运行时传递给nuxt.config.js对象。
服务器/ index.js中的代码:
const config = require('../nuxt.config.js')
更改为:
其中utils / extendedNuxtConfig.js:
import config from 'config' import get from 'lodash/get'
我们甚至都没有注意到大象
好了,我们解决了从nuxt.config.js中配置对象的env属性外部获取动态变量的问题。 但是原来的问题仍然没有解决。
假设某些抽象的sharedEnv.js将用于:
- 客户端-创建一个env.js文件,该文件将在全球范围内下载(window.env.envKey),
- 服务器-必要时导入到模块中,
- 同构代码,类似
context.isClient? window.env [key]:global.sharedEnv [key]。
莫名其妙。 这种抽象将解决最严重的问题-机密数据泄漏到客户端应用程序中,因为有意识地增加价值是必要的。
Vuex将帮助我们
在调查问题时,我们注意到Vuex存储已导出到window对象。 该解决方案被迫支持Nuxt,js的同构。 Vuex是受Flux启发的数据仓库,专门为Vue.js应用程序设计。
好吧,为什么不将其用于我们的共享变量? 这是一种更有机的方法-全局存储库中的数据适合我们。
让我们从server / utils / sharedEnv.js开始:
import config from 'config' const sharedEnv = {
上面的代码将在服务器启动期间执行。 然后将其添加到Vuex存储库中:
const getSharedEnv = () => process.server ? require('~/server/utils/sharedEnv').default || {} : {}
我们将依靠这样的事实,即在服务器初始化期间启动nuxtServerInit。 有一些困难:注意getSharedEnv方法,此处添加了在服务器上重复执行检查的功能。
发生什么事了
现在我们有了可以从以下组件中提取的公共变量:
$ store.state.sharedEnv.canonicalDomain
胜利了!哦不 插件呢?
一些插件需要环境变量来配置。 当我们想使用它们时:
Vue.use(MyPlugin,{someEnvOption:'无法访问vuex存储'})
很好的竞争条件是,Vue.js会在Nuxt.js在Vuex存储库中注册sharedEnvobject之前尝试初始化自身。
尽管注册插件的功能可以访问包含存储库链接的Context对象,但是sharedEnv仍然为空。 这很简单地解决了-让我们将插件设为异步函数,然后等待nuxtServerInit执行:
import Vue from 'vue' import MyPlugin from 'my-plugin' export default async (context) => {
现在是胜利。