nuxt1迁移奥nuxt2_使用新的Nuxt为Jamstack供电

nuxt1迁移奥nuxt2

Been waiting for Nuxt 3.0 to build Jamstack (static) apps? No need for that. The latest Nuxt version, v2.14, may be just what you are looking for.

一直在等待Nuxt 3.0生成Jamstack(静态)应用程序吗? 没必要。 Nuxt的最新版本v2.14可能正是您想要的。

Curious? Let’s start.

好奇? 开始吧。

什么是Jamstack? (What Is Jamstack?)

For anyone who was not familiar, Jamstack (or JAMstack) is a web development architecture in which JAM stands for client-side JavaScript, reusable APIs (instead of multiple web servers), and prebuilt markups (static HTML files).

对于不熟悉的人来说, Jamstack (或JAMstack)是一种Web开发体系结构,其中JAM代表客户端JavaScript,可重用的API(而不是多个Web服务器)和预建的标记(静态HTML文件)。

Image for post

Jamstack aims to deliver faster, scalable, and more secured apps by having them built as static. The trend of Jamstack starts in 2019, and we expect it to continue its popularity in 2020.

Jamstack旨在通过将其构建为静态来交付更快,可扩展且更安全的应用程序。 Jamstack的趋势始于2019年,我们预计它将在2020年继续流行。

So how does Nuxt — a server-side (SSR) Vue framework — currently perform with Jamstack?

那么,Nuxt(一种服务器端(SSR)Vue框架)目前在Jamstack中的性能如何?

Let’s find out.

让我们找出答案。

Nuxt for Jamstack的状态(v2.13之前) (The Status of Nuxt for Jamstack (Before v2.13))

Nuxt is a super-cool framework. It offers the two following build modes for a single codebase:

Nuxt是一个超酷的框架。 它为单个代码库提供以下两种构建mode

  • universal SSR (Server-side rendering)

    universal SSR(服务器端呈现)

  • spa single-page application

    spa单页应用程序

Later on, to support Jamstack, the Nuxt team offers the additional build command nuxt generate to act as a static site generator (SSG).

后来,为了支持Jamstack,Nuxt团队提供了附加的构建命令nuxt generate来充当静态站点生成器(SSG)。

Nevertheless, its static site generator mechanism is not exactly 100% expected for a standard static site generator (SSG), with some following limitations:

但是,对于标准静态站点生成器(SSG),其静态站点生成器机制并不完全符合100%的要求,但存在以下限制:

  • Unlike normal SSGs, where all data for a page are pre-fetched on build time, the Nuxt engine pre-renders templates and contents on build time but retrieves external data on runtime using fetch and asyncData. Thus, the generated pages are only half static. Also, by relying on external calls to complete data fetching and rendering on the client side, there may be delays in displaying content to the user, affecting the app's overall performance.

    与正常的SSG不同,在页面上所有数据都是在构建时预取的,Nuxt引擎在构建时预呈现模板和内容,但在运行时使用fetchasyncData检索外部数据。 因此,生成的页面只有一半是静态的。 此外,通过依赖外部调用来完成客户端上的数据提取和呈现,可能会延迟向用户显示内容的时间,从而影响应用程序的整体性能。

  • Since Nuxt doesn’t have any built-in data layer like GraphQL, the Nuxt engine doesn’t know how to auto-generate all dynamic routes for contents from an external database. Developers have to specify how to generate these routes using the generate.routes property in the nuxt.config.js file. This extra work leads to complexity and possible slow building time, resulting in cost efficiency, especially when most hosting services like Netlify charges based on building time.

    由于Nuxt没有像GraphQL这样的内置数据层,因此Nuxt引擎不知道如何为外部数据库的内容自动生成所有动态路由。 开发人员必须使用nuxt.config.js文件中的generate.routes属性指定如何生成这些路由。 这些额外的工作会导致复杂性并可能缩短构建时间,从而导致成本效益,尤其是当大多数托管服务(如Netlify)基于构建时间收费时。

  • There is no built-in Markdown support. We can use the @nuxtjs/markdownit module; however, this module proves to be difficult for developers to perform extra customization.

    没有内置的Markdown支持。 我们可以使用@nuxtjs/markdownit模块; 但是,事实证明,此模块对开发人员来说很难执行额外的自定义。

Thus, the power of static sites on performance, in this case, is unleashed halfway.

因此,在这种情况下,静态站点对性能的影响被释放了一半。

But with Nuxt 2.13 onwards and Nuxt Content Module, these limitations are finally over.

但是从Nuxt 2.13开始和Nuxt Content Module开始,这些限制终于结束了。

从构建过程开始的全静态 (Full Static Starting From the Build Process)

For a better developer experience, since v2.13, Nuxt introduces a new property, target: static, while mode remains universal (as default) or spa within nuxt.config.js, to inform the Nuxt engine. Our application aims to be entirely static.

为了获得更好的开发人员体验,自v2.13起,Nuxt引入了一个新属性target: static ,而modenuxt.config.js保持universal (默认)或spa ,以通知Nuxt引擎。 我们的应用程序旨在完全静态。

/* nuxt.config.js */
export default {
mode: 'universal', // default mode
target: 'static', // enable full static mode
//...
}

使用n uxt generate优化构建 (Optimize build with nuxt generate)

Before Nuxt v2.13, to build a code project as static, we used nuxt generate. By calling nuxt generate, the Nuxt engine actually triggers nuxt build to start the build process and then exports the application's pages to static HTMLs before deploying.

在Nuxt v2.13之前,为了将代码项目构建为静态,我们使用了nuxt generate 。 通过调用nuxt generate ,Nuxt引擎实际上会触发nuxt build以启动构建过程,然后在部署之前将应用程序的页面导出为静态HTML。

Image for post
Build process when using nuxt generate
使用nuxt generate时的构建过程

From version 2.14 on, nuxt generate is smarter. It detects when there is no code changed and skips the build step. Instead, it reuses the previous build cache and continues to generate static HTMLs.

从2.14版开始, nuxt generate变得更加智能。 它检测何时没有代码更改,并跳过构建步骤。 取而代之的是,它重用了以前的构建缓存,并继续生成静态HTML。

Also, the Nuxt engine knows to detect and separate any extra async API call on the client side (by asyncData or fetch) from the generated HTML pages into payload .js file(s) accordingly. Hence it reduces the size of the generated HTML pages served significantly. Simultaneously, on runtime, the payload files will then be pre-loaded, making the app performance-optimized and eliminating the extra API calls on client-side navigation.

同样,Nuxt引擎知道可以检测到并通过生成HTML页面将客户端上任何额外的异步API调用(通过asyncDatafetch )分离到有效载荷.js文件中。 因此,它大大减少了生成HTML页面的大小。 同时,在运行时,有效负载文件将被预加载,从而使应用性能得以优化,并消除了客户端导航上的额外API调用。

Image for post
Improved with payload file for asyncData calls
改进了用于asyncData调用的有效负载文件

Great, isn’t it? The next question is: Why do we need to keep the cache for building static apps?

很好,不是吗? 下一个问题是:为什么我们需要保留用于构建静态应用程序的缓存?

Adding cache support to the build process reduces unnecessary repetitive work for redeployments. The first deployment requires a full-build building of code and templates into application files using and exporting them to required static HTMLs for deploying.

在构建过程中添加缓存支持可以减少不必要的重复部署工作。 第一次部署需要使用它们并将其导出到所需的静态HTML进行部署,从而将代码和模板完整构建为应用程序文件。

Image for post
First deployment process of an app
应用程序的首次部署过程

However, the full build is not optimal to run in later redeployments unless there is a change in code and templates. In most circumstances, there will be changes in the site contents, such as adding a new blog post, modifying product content, etc. We will only need to re-generate the dynamic routes or/and HTML for this specific content. Hence running a full build can lead to cost inefficiency, especially when static hosting services mainly charge us based on the building time. For such use cases, to optimize the building time for redeployment, using the cache of the previous build and only generating the new content updates is sufficient, rather than the full cycle.

但是,除非在代码和模板上进行了更改,否则完整版本并不是在以后的重新部署中运行的最佳选择。 在大多数情况下,网站内容会发生变化,例如添加新的博客文章,修改产品内容等。我们只需要为该特定内容重新生成动态路由或HTML。 因此,运行完整的构建可能会导致成本效率低下,尤其是当静态托管服务主要根据构建时间向我们收取费用时。 对于此类用例,为了优化重新部署的构建时间,使用先前构建的缓存并仅生成新的内容更新就足够了,而不是整个周期。

Image for post
Smart deployment when no code change
无需更改代码即可进行智能部署

您提到了动态路线,Nuxt会自动对其进行爬网 (You mention the dynamic route, Nuxt auto-crawls it)

Since v2.13, Nuxt brings in something more powerful than the need of one data layer, and generate.routes. As long as you mention your dynamic route on any page (list of blog posts on the main page, for instance), the Nuxt crawler will detect and make sure all the mentioned routes are pre-generated during build and deployment.

从v2.13开始,Nuxt带来了比一个数据层更强大的功能,并generate.routes .routes。 只要您在任何页面上都提到了动态路由(例如,主页上的博客文章列表),Nuxt搜寻器就会检测并确保所有提及的路由都是在构建和部署期间预先生成的。

By default, the Nuxt crawler is auto-enabled. Nevertheless, if we want to use our logic for generating routes, we can turn it off by setting crawler: false and continue implementing export.routes in nuxt.config.js.

默认情况下,Nuxt搜寻器是自动启用的。 然而,如果我们想用我们的逻辑生成路径,我们可以通过设置将其关闭crawler: false ,并继续实施export.routesnuxt.config.js

Cool, isn’t it? And there is more. Nuxt v2.14 is excellent, and with its Nuxt content module, its static power is even higher.

不错,不是吗? 还有更多。 Nuxt v2.14非常出色,借助Nuxt内容模块,其静态功耗甚至更高。

Let’s check out Nuxt content, shall we?

让我们看看Nuxt的内容,好吗?

您编写内容,Nuxt负责渲染 (You Write the Content, Nuxt Takes Care of Rendering)

The Nuxt content module, @nuxt/content, is a new module developed by Benjamin Canac from the Nuxt team. At the time of writing this post, Nuxt Content release is version 1.4.1.

Nuxt内容模块@nuxt/content是Nuxt团队的Benjamin Canac开发的新模块。 在撰写本文时,Nuxt Content版本是1.4.1版。

In short, this content module acts as a Git-based headless CMS (content management service) to fetch and handle content from different file types located in a local project directory, to use in your Nuxt application.

简而言之,该内容模块充当基于Git的无头CMS(内容管理服务),以从本地项目目录中的不同文件类型中获取并处理内容,以在Nuxt应用程序中使用。

To start using Nuxt Content, run one of the following commands:

要开始使用Nuxt Content,请运行以下命令之一:

yarn add @nuxt/content
#OR
npm i @nuxt/content

Then add the module to the modules list in nuxt.config.js:

然后将模块添加到nuxt.config.jsmodules列表中:

modules: [
'@nuxt/content'
]

And the module is ready for you to use.

该模块已准备就绪,可以使用。

一种简单的使用方法 (A simple way to use)

By default, the Nuxt engine will use content/ part as the main directory for all the Markdown files.

默认情况下,Nuxt引擎将使用content/ part作为所有Markdown文件的主目录。

The content module globally injects the$content function instance to our application so we can use it to fetch content from a given path directly. For example, we can retrieve a list of blog posts from content/blog directory, as below:

内容模块将$content函数实例全局注入到我们的应用程序中,因此我们可以使用它直接从给定路径中获取内容。 例如,我们可以从content/blog目录中检索博客文章列表,如下所示:

This $content instance receives two arguments: path and an additional object options, which provides extra configuration for the module to override the default settings for that given path. For instance, we only need to enable deep: true to fetch files from subdirectories, as in the following code:

$content实例接收两个参数: path和一个附加对象options ,它为模块提供了额外的配置,以覆盖该给定路径的默认设置。 例如,我们只需要启用deep: true即可从子目录中获取文件,如以下代码所示:

Or to fetch a single file, we can either pass the file name to the path argument or directly as options:

或者,要提取单个文件,我们可以将文件名传递给path参数,也可以直接作为options传递:

Both approaches are legitimate. $content() returns a chain sequence of type QueryBuilder . We then can call its method fetch() to start retrieving the content using Promise.

两种方法都是合法的。 $content()返回QueryBuilder类型的链序列。 然后,我们可以调用其方法fetch()以开始使用Promise检索内容。

When fetch() resolves, it returns either an object (if path is a single file path), or an array of objects (if path is a directory). Each object has a similar structure as in the screenshot below, with the auto-generated properties as body (the main content), createdAt, dir, extension, path, slug (name of the file), toc (table of contents), and updatedAt.

fetch()解析时,它返回一个对象(如果path是单个文件路径)或一个对象数组(如果path是目录)。 每个对象的结构与下面的屏幕快照类似,具有自动生成的属性,包括body (主要内容), createdAtdirextensionpathslug (文件名), toc (目录)和updatedAt

Image for post

Once we have the return content object, we can simply use the nuxt-content component in the template section to display the content's body:

有了返回内容对象后,我们可以简单地使用模板部分中的nuxt-content组件来显示内容的主体:

That’s it. The content module will take care of the rendering and have your page content displayed, as in the below example:

而已。 内容模块将负责渲染并显示页面内容,如以下示例所示:

Image for post

As you can see from the screenshot, Nuxt Content only displays the content with the most basic stylings (i.e. no styling), to avoid creating complexity when applying CSS style customization. Nuxt provides us with the .nuxt-content class selector for the <nuxt-content> component, and we can start customizing the styles from there, such as:

从屏幕截图中可以看到,Nuxt Content仅显示具有最基本样式(即没有样式)的内容,以避免在应用CSS样式自定义时产生复杂性。 Nuxt为我们提供了<nuxt-content>组件的.nuxt-content类选择器,我们可以从此处开始自定义样式,例如:

And our content page now looks much more organized

现在我们的内容页面看起来更有条理

Image for post

And that’s it. We have our content from a Markdown file rendered to a page using Nuxt Content module with only three simple steps:

就是这样。 我们只需要三个简单的步骤,就可以使用Nuxt Content模块将Markdown文件中的内容呈现到页面上:

  1. Fetch the content using $content().fetch().

    使用内容$content().fetch()

  2. Render the fetched content using <nuxt-content> and its prop document accordingly.

    相应地使用<nuxt-content>及其支持document 渲染获取的内容。

  3. Add CSS styles to the displayed content using the class selector .nuxt-content.

    使用类选择器.nuxt-content 将CSS样式添加到显示.nuxt-content

Great? Indeed. So any other unique features Nuxt Content offers besides?

大? 确实。 因此,Nuxt Content还提供其他独特功能吗?

搜索和过滤内容结果 (Search and filter content results)

Since Nuxt Content is using LokiJS and MongoDB-like query syntax, we can achieve high performance in searching and filtering a certain set of content results with a sequence chain of methods. For example, if we want to pick only the title, slug, and updatedAt properties of each content object and sort the posts by the edit time (in descending order), we can do so as follows:

由于Nuxt Content使用的是LokiJS类似 MongoDB的查询语法,因此我们可以使用一系列方法序列来搜索和过滤一组特定的内容结果,从而实现高性能。 例如,如果我们只选择每个内容对象的titleslugupdatedAt属性,并按编辑时间(按降序排列)对帖子进行排序,则可以如下所示:

Here only receives an array of keys to pick from each returned content object and sortBy accepts two arguments, a key to sort and the sorting direction.

这里only接收从每个返回的内容对象中选择的键数组, sortBy接受两个参数,即要排序的键和排序方向。

You can also filter for posts that match certain condition(s) using where, such as:

您还可以使用where来过滤符合特定条件的帖子,例如:

Or you can perform a full-text search on a field with search(key, value):

或者,您可以使用search(key, value)在字段上执行全文搜索:

Also, you can implement pagination by limiting the results received by limit():

另外,您可以通过限制limit()接收到的结果来实现分页:

You can explore other useful chaining methods in Nuxt Content documentation and LokiJS for query syntax supported in these methods.

您可以在Nuxt Content文档和LokiJS中探索其他有用的链接方法,以获取这些方法支持的查询语法。

Note: All the sequence chaining has to end with fetch() to collect the needed data through Promise API.

注意:所有序列链都必须以fetch()结尾,以通过Promise API收集所需的数据。

PrismJS突出显示代码 (Code highlighting with PrismJS)

Nuxt Content uses PrismJS as its built-in handler for code highlighting in Markdown content. The default theme is pretty decent; however, we can always install prism-themes and chose a different theme from the available theme list (24 different themes) to use in our application:

Nuxt Content使用PrismJS作为其内置处理程序在Markdown内容中突出显示代码。 默认主题很不错。 但是,我们始终可以安装prism-themes并从可用主题列表中选择一个不同的主题(24个不同的主题)以在我们的应用程序中使用:

yarn add prism-themes

Then define the desired theme under content.markdown.prism field in nuxt.config.js, as shown in the example below:

然后在nuxt.config.js content.markdown.prism字段下定义所需的主题,如下例所示:

And your rendered content with code highlighting will look like this:

带有代码突出显示的渲染内容将如下所示:

Image for post

Beautiful, isn’t it? No more complicated workaround for supporting code highlighting for Markdown. Also, you can always create your custom theme as the prism-themes repo is open-source.

美丽,不是吗? 没有更复杂的解决方法来支持Markdown的代码突出显示。 另外,您可以随时创建自定义主题,因为prism-themes回购是开源的。

Markdown内部的YAML (YAML inside Markdown)

One nice feature of Nuxt Content is the ability to support YAML front matter block within a Markdown file, as long as it appears at the top and takes the valid form of YAML set between triple-dashed lines:

Nuxt Content的一个不错的功能是能够在Markdown文件中支持YAML前端块,只要它出现在顶部并采用三点之间的有效形式的YAML集即可:

--- 
title: Hello World description: Hello to Nuxt content demo img: nuxt_demo/DSC00856
author: Maya Shavin
---

The Nuxt Content module will inject these fields as properties into the content object passed to document of the nuxt-content component, as shown in the example below:

Nuxt Content模块会将这些字段作为属性注入到传递给nuxt-content组件document的内容对象中,如以下示例所示:

Image for post

Writing YAML block inside the Markdown file enables us to easily add more custom information, such as author details, for a blog post.

在Markdown文件中编写YAML块使我们能够轻松地为博客文章添加更多自定义信息,例如作者详细信息。

自动生成目录 (Autogenerating table of content)

When fetching a Markdown file, Nuxt content autogenerates a table of content (TOC), which consists of all the heading titles inside the file. The TOC is an array and appears as a property of the return content object. Each element of the toc array is an object with three main fields:

提取Markdown文件时,Nuxt内容会自动生成一个目录(TOC),该目录由文件内的所有标题组成。 TOC是一个数组,显示为返回内容对象的属性。 toc数组的每个元素都是一个具有三个主要字段的对象:

  • id — the heading title itself in lowercase and free of whitespace, for linking

    id —标题标题本身为小写字母,没有空格,用于链接

  • depth — type of heading (1=h1, 2 =h2, etc.)

    depth —航向的类型(1 = h1、2 = h2等)

  • text — the actual text of the heading title

    text -标题的实际文字

Here’s an example of a Markdown file with the following content:

这是具有以下内容的Markdown文件的示例:

# Hello World## Hello Heading 1
Lorem ipsum dolor sit amet

Nuxt Content will generate TOC as the following:

Nuxt Content将生成如下的TOC:

And from this TOC structure, we can build and display our TOC component accordingly.

从这个TOC结构中,我们可以相应地构建和显示TOC组件。

Awesome. What else?

太棒了 还有什么?

全部与钩有关! (It’s all about hooks!)

Currently, Nuxt Content offers two main hooks:

当前,Nuxt Content提供了两个主要的挂钩:

  • content:file:beforeInsert allows adding extra data to a document before storing it for rendering. For example, it is useful to add external logic, like reading time calculation on build time, hence optimizing the client-side performance.

    content:file:beforeInsert允许在存储文档以进行渲染之前向文档中添加额外的数据。 例如,添加外部逻辑(如在构建时间上读取时间计算)非常有用,因此可以优化客户端性能。

  • content:update when a content file is updated. This hook is useful when you want to implement hot-reload or live-edit.

    content:update内容文件时更新。 当您要实现热重载或实时编辑时,此挂钩非常有用。

We can add the desired hooks by using the hooks properties in nuxt.config.js, as in the following example:

我们可以使用nuxt.config.jshooks属性来添加所需的钩子,如以下示例所示:

And that’s all we need. Now the documents fetched will also have an additional field readingTime indicating how much time it takes to read the blog post, and all of these are done entirely on the build time. No extra work needed on the client side, even for reading time calculation.

这就是我们所需要的。 现在,获取的文档还将具有一个额外的字段readingTime指示读取博客文章需要多少时间,所有这些都完全在构建时间上完成。 客户端不需要额外的工作,即使是阅读时间的计算。

Cool, isn’t it? With these features, we can set up a fully static site, either a blog or an ecommerce store using Markdown files and Nuxt only.

不错,不是吗? 借助这些功能,我们可以仅使用Markdown文件和Nuxt来建立一个完全静态的站点,无论是博客还是电子商务商店。

Indeed, these are not the only features Nuxt Content can offer. And making a performant and beautiful static site requires a combination of efficient tools, in which Nuxt and Nuxt Content is the core.

实际上,这些并不是Nuxt Content可以提供的唯一功能。 要打造一个性能卓越且美观的静态网站,需要结合高效的工具,其中以Nuxt和Nuxt Content为核心。

演示版 (Demo)

For experimenting, I made a demo PWA for a travel company, using Nuxt, Nuxt Content, TailwindCSS, Cloudinary, and deployed automatically using Netlify.

为了进行试验,我使用NuxtNuxt ContentTailwindCSSCloudinary为旅游公司制作了演示PWA,并使用Netlify自动进行了部署。

Image for post

You can check out the app here: https://tfh-tours.netlify.app/

您可以在此处签出该应用程序: https : //tfh-tours.netlify.app/

And the code behind is, as always, open-source and available in this repo: https://github.com/mayashavin/tours-nuxt-full-static

和往常一样,背后的代码是开源的,可以在此仓库中找到: https : //github.com/mayashavin/tours-nuxt-full-static

结论 (Conclusion)

Nuxt v2.1x and Nuxt Content, in my opinion, are remarkable releases from the Nuxt team. Apart from the build improvements for static sites mentioned, the new Nuxt also provides other features, which aim to make developer life more comfortable, such as components for auto-detection, run-time config, telemetry, and theming support.

在我看来,Nuxt v2.1x和Nuxt Content是Nuxt团队的杰出作品。 除了提到的静态站点的构建改进之外,新的Nuxt还提供了其他功能,旨在使开发人员的生活更加舒适,例如用于自动检测,运行时配置,遥测和主题支持的组件。

Also, Nuxt Content is an absolute win, where you can interact with the content in real time and fully take advantage of what Markdown content offers while keeping the UI beautiful according to your app’s target look and feel.

同样,Nuxt Content是绝对的胜利,您可以在其中与内容进行实时交互,并充分利用Markdown内容提供的优势,同时根据应用程序的目标外观保持UI美观。

If you reach this line (I appreciate that), why not try out Nuxt (if you haven’t) and see how it empowers your next Jamstack project?

如果您达到这条线(我很感激),为什么不尝试Nuxt(如果您还没有这样做),看看它如何为您的下一个Jamstack项目提供支持?

翻译自: https://medium.com/better-programming/power-up-your-jamstack-with-the-new-nuxt-9b5c3d449876

nuxt1迁移奥nuxt2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值