谢谢你,Nuxt
爱莉安娜·格兰德曾说过:“一个教会了我耐心,一个教会了我痛苦。”她指的是她的前任们。今天,我要和大家聊聊Nuxt的前任们。
Nuxt's?Nuxt'is?Nuxt'ises?
Nuxt到底是什么?
Nuxt是“VueJS框架”。他们的网站上是这么说的,他们为什么要撒谎呢?
Nuxt 的功能非常强大,很难准确描述它的具体作用。它可以根据你的文件夹结构自动设置路由,自动为静态网站进行代码分割,甚至还会导致有人在博客文章中频繁使用“automatically:”这个词。
但它最广为人知的用途可能是使用 Vue 进行服务器端渲染。
服务器端 Vue
Vue 是一个 JavaScript 框架。这意味着你编写的代码会在运行时在浏览器中执行。但几年前,有人敏锐地意识到,我们可以用 Node 在服务器端执行 JavaScript,所以我们也应该能够在服务器端运行和编译 JavaScript 框架。他们把这种技术称为“同构 JavaScript”。
我至今仍然不明白那是什么意思。幸运的是,它后来更名为“通用 JavaScript”。Vue 的主要价值在于它能够帮助开发者构建这些“通用应用”。它的功能远不止于此,但这却是它最广为人知的。这有点像约翰·卡拉辛斯基饰演杰克·瑞恩,但更确切地说,他就是吉姆·哈尔珀特,而且永远都是。
如果不看看实际应用,就很难理解通用 JavaScript,所以让我们构建一些毫无意义的东西。
毫无意义的演示
我的示例应用是一个单页应用,只有一个 XMLHTTPRequest (XHR) 请求,用于从 JSON 占位符 API 获取一些虚拟图片。我原本期待的是更好的虚拟图片,但免费的东西总不能抱怨吧。就像我嫂子租了一台玛格丽特鸡尾酒机,结果做出来的酒淡得像水一样。“听着,谢谢你提供的免费酒,但我很失望。”
以下是用于创建此页面的全部代码。
| <template> | |
| <div class="section"> | |
| <h1 class="is-size-1">Photos</h1> | |
| <div class="columns is-multiline"> | |
| <div | |
| v-for="photo in photos" | |
| :key="photo.id" | |
| class="column is-one-quarter" | |
| > | |
| <div class="card photo"> | |
| <div class="card-image"> | |
| <figure class="image"> | |
| <img :src="photo.url" alt="photo.title" /> | |
| </figure> | |
| </div> | |
| <div class="card-content"> | |
| <div class="content"> | |
| <p>{{ photo.title }}</p> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </template> | |
| <script> | |
| export default { | |
| async asyncData({ $axios }) { | |
| const { data } = await $axios.get( | |
| 'https://jsonplaceholder.typicode.com/photos?_limit=100' | |
| ) | |
| return { photos: data } | |
| } | |
| } | |
| </script> | |
| <style> | |
| .card.photo { | |
| height: 100%; | |
| } | |
| </style> |
虽然不算特别激动人心,但足以测试 Nuxt 在服务器端渲染应用的价值主张。第 29 行有一个 HTTP 请求,调用的是 `<except>` 端点axios。尽管这段代码位于组件内部,但 Nuxt 会在服务器端发起该请求并编译此模板。因此,我们最终看到的页面已经包含了所有标记。
但我们怎么能确定Nuxt真的在做这件事呢?万一它在骗我们呢?经历了left-pad事件之后,我还能相信任何人吗?
最简单的方法就是右键点击页面,然后选择“查看源代码”。“查看源代码”会显示页面从服务器请求时的样子,也就是在任何 JavaScript 代码有机会修改它之前的样子。我的意思是,修改它之前的样子。
没错——所有的标记都还在。而且看起来也不怎么样。不过没关系,因为它已经被压缩过了。在网页上,越小越好。真的是这样吗?
你也可以打开开发者工具,直接查找 XHR 请求。你会发现它明显缺失。
我目前为止还没遇到太多困难。Nuxt 的确……和标准的 Vue 应用有所不同,但也没那么难。搭建一个新应用相对容易,然后读一下“入门指南”页面的第一段,就可以默认自己已经掌握了所有知识。
然后我去部署它。
部署 Nuxt 应用
由于 Nuxt 的渲染工作在服务器端进行,因此 Nuxt 应用需要服务器。更准确地说,是一个 Node 服务器。我使用的是 Azure,所以需要AppService。Vue单页应用可以托管在Azure 存储上。
应用运行前必须先进行构建。理想情况下,我们希望在服务器端完成构建。首选工作流程是……
- 做出改变
- 查看 GitHub
- Azure 会自动引入代码
- Azure 执行构建
- Azure 启动站点
这种工作流程让你专注于编写代码,而不是部署。你只需将代码提交到源代码控制系统,网站就会自动更新。这可以说是最简单的 DevOps 形式。
要在 Azure 中设置这样的工作流,我首先需要决定我是更倾向于 Windows 还是 Linux。Azure 同时支持这两种操作系统,而你的选择至关重要。请稍等。
我们先从 Linux 开始。之所以要从 Linux 开始,是因为 Linux 是 Azure 中运行 Node 应用的首选方式。我特意强调了这一点,因为它非常重要。这意味着,Azure 中 Node 体验的改进工作主要围绕 Linux 展开。
部署到 Linux
得益于 Azure 中名为“Oryx”的全新构建工具,在适用于 Linux 的 AppService 上运行 Nuxt 应用程序“开箱即用”。事实上,Oryx 本月刚刚正式发布。欢迎来到这个世界,Oryx!抱歉,2019 年发生了很多事。
在 Azure 上部署和构建此项目,只需将站点配置为 Git 或 GitHub 部署,并将项目检入存储库即可。
Oryx 会拉取代码,运行一个命令npm install,然后执行操作npm run build。Git 日志会显示确实nuxt build发生了一次操作。
浏览该网站并……
Azure 返回此错误需要很长时间,而且我使用 Azure 的时间也足够长了,我知道出现这种情况通常是因为 Azure 无法绑定到某个端口或地址。如果应用程序尝试绑定到某个硬编码的地址(例如 localhost)或硬编码的端口(例如 3000),就会发生这种情况。
很多主机托管服务商都存在这个问题,包括 Heroku 上的网站,以及其他任何使用容器托管应用的平台,例如 Azure。Nuxt 文档建议在配置文件中添加一个nuxt.config.js绑定到 0.0.0.0 的部分来解决这个问题。
server: {
host: '0.0.0.0'
}
和…
太棒了!还不错。主机设置是唯一可能让你遇到问题的地方。
那是Linux。现在我们来聊聊Windows。
部署到 Windows
部署到 Windows 平台就有趣多了。Oryx 没有 Windows 版的构建工具,取而代之的是一个名为“Kudu”的工具。
默认情况下,Kudu 不会构建任何内容。您必须包含一个.deployment带有正确设置的文件才能使其执行构建。而这恰好就是所需的SCM_DO_BUILD_DURING_DEPLOYMENT设置。
[config]
SCM_DO_BUILD_DURING_DEPLOYMENT=true
问题在于你对构建的定义和 Kudu 对构建的定义可能不同。我说的构建是指先执行 `build` 命令,npm install然后执行 ` build`npm run build命令。Kudu 的定义止于 `build` 命令npm install。但由于 Kudu 已经在运行 `build` 命令npm install,我们可以通过将构建命令设置为钩子来让它也运行构建命令postinstall。
"postinstall": "npm run build"
成功了!等等。算是吧。
Kudu 的确执行了postinstall钩子,但构建失败了。失败的原因function是出现了一个意外的标记。任何时候看到“意外的标记”这样的错误,很可能是因为你的 Node 版本不正确。我向上滚动查看日志,看到了这个……
我猜测Node 6.9.1不支持async函数。
不,看来 7.10.1 是最低版本要求。为了安全起见,我们选择 Azure 支持的最高 Node 版本,截至撰写本文时,该版本为10.15.2。在 Azure 中设置该版本最可靠的方法WEBSITE_DEFAULT_NODE_VERSION是通过应用程序设置。根据我的经验,直接在应用程序设置engines中使用属性package.json没有任何效果。
成功!
现在我们只需浏览一下网站……
当某件事应该正常运行,但却无法正常运行,而你又不知道为什么时,该用什么词来形容呢?哦,对了,“编程”。
向上滚动查看输出结果,可以看到这个……
这并非无效的启动命令,但 Kudu 期望的格式是这样的node entry-point。下面还有一行有趣的内容……
Missing server.js/app.js files, web.config is not generated
这里发生的情况是,Windows 使用 IISNode 来运行应用程序。IISNode 需要一个文件web.config来设置入口点和根目录。如果你的应用程序根目录中有一个文件,Kudu 将使用该文件自动生成一个app.js文件。serverjsweb.config
所以我server.js向项目根目录添加了一个文件,该文件只需要引入我的实际启动文件即可。
require('./server/index.js');
重新部署和……
不算糟糕,但也谈不上特别直观。你不知道自己不知道什么。如果你之前不知道,现在你知道了。
看看你教了我什么
说实话,搞清楚Windows部分的配置可真够费劲的。既费耐心又费劲。不过,我现在对Azure AppService for Windows的理解比我想象的要深刻得多。至少足以写一篇博客文章了。
Oryx是新推出的,而且是一项非常受欢迎的改进。它的运行方式完全符合我的预期,这正是我们作为开发者所真正要求的。就像戴森的创始人以前说的那样……
文章来源:https://dev.to/azure/thank-u-nuxt-164j我只是觉得事情应该正常运转
——戴森吸尘器专家















