Gridsome 入门指南

900 阅读15分钟

1. 前言

1.1. 什么是JAMstack?

JAMstack是指使用JavaScript、API和Markup构建的技术堆栈,JAM是JavaScript、API和Markup的简称,前面第一个字母缩写,JAMstack一种基于客户端JavaScript,可重用API和预构建Markup的现代Web开发架构,需要符合下面三个标准:

  • JavaScript:请求/响应周期中的任何动态编程都由JavaScript处理,完全在客户端上运行。这可以是任何前端框架,库,甚至是轻量JavaScript。
  • API:所有服务器端进程或数据库操作都被抽象为可重用的API,使用JavaScript通过HTTPS访问。这些可以是定制的或利用第三方服务。
  • Markup:模板化标记应该在部署时预先构建,通常使用内容站点的站点生成器或Web应用程序的构建工具。

当我们谈论“堆栈”时,我们不再谈论操作系统,特定Web服务器,后端编程语言或数据库。JAMstack与特定技术无关。这是一种构建网站和应用程序的新方法,可提供更好的性能,更高的安全性,更低的扩展成本以及更好的开发人员体验。

1.2. 什么不是JAMstack?

依赖于客户端和服务器之间紧密耦合的任何项目都不是使用JAMstack构建的。包括:

  • 使用服务器端CMS构建的站点,如WordPress,Drupal,Joomla或Squarespace。
  • 一个单片服务器运行的Web应用程序,它依赖于Ruby,Node或其他后端语言。
  • 单页应用程序,使用同构呈现在运行时在服务器上构建视图。

1.3. 为何选择JAMstack?

  • 更好的性能:为什么要在部署时生成页面时等待页面动态构建?当谈到最小化第一个字节的时间时,没有什么能比通过CDN提供的预构建文件更好。

  • 快速的部署:可以轻松部署JAMstack网站,而无需经历配置数据库,保护.htaccess等麻烦,只需处理静态文件,因此可以快速在CDN上部署运行。

  • 安全性更高:将服务器端进程抽象为微服务API,可以减少攻击的表面区域。您还可以利用专业第三方服务的专业知识。

  • 更便宜,更容易扩展:当您的部署相当于可以在任何地方提供服务的一堆文件时,扩展就是在更多地方提供这些文件的问题。CDN是完美的,通常包括扩展他们的所有计划。

  • 更好的开发者体验:松散耦合和控制分离允许更有针对性的开发和调试,并且为站点生成器扩展选择CMS选项消除了为内容和营销维护单独堆栈的需要。

1.4. 最佳实践

在构建JAMstack项目时,如果您坚持一些最佳实践,您可以真正获得最大的收益。

1.4.1. 整个项目放在CDN上

因为JAMstack项目不依赖于服务器端代码,所以可以分发它们而不是保存在单个服务器上。直接从CDN服务可以解锁无法超越的速度和性能。您可以推送到边缘的应用程序越多,用户体验就越好。

1.4.2. 一切都在Git中

使用JAMstack项目,任何人都应该能够使用git clone标准过程(如npm install)安装任何所需的依赖项,并准备好在本地运行整个项目。没有要克隆的数据库,没有复杂的安装。这减少了贡献者的摩擦,并且还简化了分段和测试工作流程。

1.4.3. 现代构建工具

充分利用现代构建工具的世界。它可以成为一个面向丛林的丛林,它是一个快速移动的空间,但你希望今天能够使用明天的网络标准,而无需等待明天的浏览器。目前这意味着Babel,PostCSS,Webpack是朋友。

1.4.4. 自动构建

由于JAMstack标记是预先构建的,因此在运行其他构建之前,内容更改不会生效。自动化此过程将为您节省很多挫折感。您可以使用webhook自行完成此操作,也可以使用自动包含该服务的发布平台。

1.4.5. 原子部署

随着JAMstack项目变得非常庞大,新的更改可能需要重新部署数百个文件。一次上载这些一个可能会在进程完成时导致不一致的状态。您可以使用允许您执行“原子部署”的系统来避免这种情况,在上传所有已更改的文件之前,不会进行任何更改。

1.4.6. 即时缓存失效

当构建到部署周期变得经常发生时,您需要知道当部署上线时,它真的会上线。通过确保您的CDN可以处理即时缓存清除来消除任何疑问。

1.5. 如何开始?

使用成熟可靠的静态站点生成器可以在几分钟内构建JAMstack网站和应用,推荐以下几款流行的,新美文使用过,且模板选择较多。

  • Jekyll:一个最早、简单、可扩展的静态站点生成器,得到Github全面支持,可方便免费部署在Github。

  • Hexo:是一个快速、简洁且高效的博客框架。Hexo 使用 Markdown(或其他渲染引擎)解析文章,在几秒内,即可利用靓丽的主题生成静态网页。

  • Hugo:使用go语言开发,最受欢迎的开源静态站点生成器之一,凭借其惊人的速度和灵活性,使用Hugo制作网站变得轻松和灵活。

  • Gatsby:一个基于React的免费开源框架,可以帮助开发人员构建超快速的网站和应用程序,用过之后会对浏览速度发出惊叹。

  • Gridsome:一个Vue.js驱动的现代站点生成器。

2. 简介

Gridsome是一个开源超8K+基于Vue.js超快速创建现代化网站的工具栈,用于创建可在任何地方部署的快速安全的网站。

它使开发人员可以轻松构建现代JAMstack网站。

Gridsome捆绑了一些难以错过的功能,这使它成为最受欢迎的静态站点生成器之一。其中一些功能包括:

  • 基于Vue.js - 最简单,最易用的前端框架。
  • 通过热加载进行本地开发 - 在开发过程中实时查看更改。
  • 基于文件的页面路由 - src/pages中的任何Name.vue文件都是静态路由。
  • 动态路由 - src/pages中的任何[param].vue文件都是动态路由。
  • 静态文件生成 - 安全,快速地部署到任何CDN或静态Web主机。
  • 数据来源 - 从任何Headless CMS,API或Markdown文件中添加数据。
  • GraphQL数据层 - 具有集中式数据层的简单数据管理。
  • 自动代码拆分 - 将超高性能构建到每个页面中。
  • 自动优化的代码 - 开箱即用的代码分割和资产优化。
  • 自动页面预取 - 页面在后台加载以便快速浏览。
  • 渐进式图像支持 - 自动调整大小,优化和延迟加载图像。
  • 插件生态系统 - 查找适合任何工作的插件。

2.1 原理

Gridsome是一个现代的网站开发框架,用于创建可以部署在任何地方的快速,安全的网站。生成静态HTML文件以创建SEO友好的标记,一旦将其加载到浏览器中,该标记就会合并到由Vue.js驱动的SPA中。

源插件从本地文件或外部API获取内容,并将数据存储在本地数据库中。统一的GraphQL数据层使您可以仅从数据库中提取所需的数据,并在Vue.js组件中使用它们。数据在构建时生成并存储为静态JSON。

首先只加载关键的HTML,CSS和JavaScript。接下来的页面会被预取,这样用户就可以在不重新加载页面的情况下快速点击,即使离线时也是如此。

Gridsome会自动优化前端以加载和快速执行blazing。你可以得到代码分割,图像优化,延迟加载,几乎完美的灯塔得分开箱即用。

Gridsome站点通常不连接到任何数据库,并且可以完全托管在全局CDN上。它可以处理数千到数百万次点击,并且不需要昂贵的服务器成本。

Gridsome使用超快速静态站点生成器,JavaScript和API的强大功能来创建令人惊叹的动态Web体验。

Gridsome站点在转换成一个完全由Vue.js支持的SPA之前作为静态HTML加载。这使得搜索引擎能够抓取内容并给出更好的搜索引擎优化排名,并且仍然拥有Vue.js的所有功能。

3. 快速入门

3.1. 先决条件

您应该具有有关HTML,CSS,Vue.js以及如何使用Terminal的基本知识。了解GraphQL的工作原理是有好处的,但不是必需的。

Gridsome需要Node.js(v8.3 +)。

3.2. 安装Gridsome CLI工具

npm install --global @gridsome/cli

3.3. 创建一个Gridsome项目

gridsome create my-gridsome-site #创建一个新项目
cd my-gridsome-site #进入文件夹
gridsome develop #在以下位置启动本地开发服务器 http://localhost:8080

如果我们尝试更改此布局页面上的任何内容,那么我们将看到它会自动更改屏幕上的内容。这是我们之前谈到的Gridsome Hot Reloading功能的结果。

4. 目录结构

基本的Gridsome项目的结构如下:

.
├── package.json
├── gridsome.config.js
├── gridsome.server.js
├── static/
└── src/
    ├── main.js
    ├── index.html
    ├── App.vue
    ├── layouts/
    │   └── Default.vue
    ├── pages/
    │   ├── Index.vue
    │   └── Blog.vue
    └── templates/
        └── BlogPost.vue

4.1. root 目录

  • package.json 包含有关项目中安装了哪些插件的信息。

  • gridsome.config.js 该文件包含已安装插件的配置和选项。

  • gridsome.server.js 该文件是可选的,用于挂接到Gridsome服务器的各个部分。该文件必须导出可以访问API的函数。

4.2. /src 目录

  • Main.js 在此处导入全局样式和脚本。该文件还具有可以访问Client API的导出功能。该文件是安装Vue插件,注册组件和指令等的地方。

  • Layouts目录 如果要共享页面或模板的一个或多个布局,请在此目录中创建组件。

  • Pages目录 该目录中的所有组件均成为您网站的页面。每个页面将根据其.vue文件的位置获得其路径。 src/pages/Index.vue将成为您网站的主页,而src/pages/AboutUs.vue将成为example.com/about-us

  • Templates目录 如果要将外部数据源(例如来自WordPress博客的帖子)导入到项目中,则每个帖子都会在此目录中寻找其模板的组件。组件文件的名称必须与GraphQL模式中的节点类型匹配。

  • 自定义index.html 有时,您将需要覆盖Gridsome用于生成页面的基本HTML模板。Gridsome使这变得非常容易。您要做的就是在src目录中创建一个新的index.html文件。

  • 自定义App.vue 该App.vue文件是包装所有页面和模板的主要组件。您可以通过App.vue在src目录中拥有自己的文件来覆盖默认文件。如果要在所有页面之间共享布局,则覆盖默认值很有用。

了解有关覆盖App.vue的更多信息

4.3. /static 目录

此目录中的文件将dist在构建期间直接复制到。例如,/ static / robots.txt将位于yoursite.com/robots.txt

  • Aliases 在Gridsome中,您可以使用别名~或@链接到文件/src夹内的文件。例如,您可以使用以下命令导入Vue组件import Card from '~/components/Card'

4.4. 其他目录

  • Assets 全局样式,图像,字体和图标通常添加到src/assets目录中。

  • Shared or global components 您可以在多个页面或模板中使用的组件可以存储在src/components目录中。

  • Data files 您可以将诸如.json或.yaml想要导入到组件中的数据文件存储在src/data目录中。

5. 项目配置

Gridsome需要gridsome.config.js才能工作。插件配置和项目设置都是在这个文件当中。基本配置文件如下所示:

module.exports = {
  siteName: 'Gridsome',
  siteUrl: 'https://www.gridsome.org',
  plugins: []
}
  • siteName 为您的项目设置一个名称。该名称通常在标题标签中使用

  • siteDescription 为您的项目设置描述

  • siteUrl 通常用于设置站点的域的根目录

  • host 运行时主机

  • port 运行时端口

  • outputDir 当运行gridsome build时,将在其中生成生产构建文件的目录

  • pathPrefix Gridsome假定您的项目是从域的根目录提供的。如果您的项目将托管在名为/my-app的子目录中,请更改此选项my-app

  • titleTemplate 默认 %s - <siteName>,用于设置标题的模板。在页面中设置的元信息,会替换这个%s占位符

  • plugins 通过将插件添加到plugins数组来激活插件

module.exports = {
  plugins: [
    {
      use: '@gridsome/source-filesystem',
      options: {
        path: 'blog/**/*.md',
        route: '/blog/:year/:month/:day/:slug',
        typeName: 'Post'
      }
    }
  ]
}
  • templates 定义集合的路由和模板

  • metadata 将全局元数据添加到GraphQL schema

  • icon 默认情况下会使用位于src/favicon.png作为favicon和touchicon。但也可以定义其他路径或大小,图标应为正方形,最小16个像素

module.exports = {
  icon: './src/my-icon.png'
}
  • configureWebpack 如果该选项是一个对象,它将与内部配置合并。
module.exports = {
  configureWebpack: {
    // merged with the internal config
  }
}

如果该选项是一个函数,它将获得内部配置作为其第一个参数。您可以修改参数或返回一个新的配置对象,该对象将覆盖内部webpack配置。

const merge = require('webpack-merge')

module.exports = {
  configureWebpack(config) {
    return merge({ /* custom config */ }, config)
  }
}
  • chainWebpack 该函数将接收由webpack-chain提供支持的ChainableConfig实例

  • runtimeCompiler 在运行时包括Vue模板编译器

  • configureServer 配置开发服务器

  • permalinks.trailingSlash 启用此选项后,具有动态路由的页面将不包含斜杠,并且服务器上必须具有额外的重写规则才能正常工作。此外,的静态路径不会自动包含尾部斜杠,而应包含在路径中:

<g-link to="/about-us/">About us</g-link>
  • permalinks.slugify 使用自定义的Slugify方法。默认slugifyer是@sindresorhus/slugify
module.exports = {
  permalinks: {
    slugify: {
      use: 'another-slugify-library',
      options: {}
    }
  }
}
  • css.split 将CSS分成多个块。默认情况下禁用拆分。拆分CSS可能会导致奇怪的行为

  • css.loaderOptions 将选项传递给与CSS相关的加载程序。例如:

module.exports = {
  css: {
    loaderOptions: {
      scss: {
        // options here will be passed to sass-loader
      },
      less: {
        // options here will be passed to less-loader
      }
    }
  }
}

6. 页面

页面负责在URL上显示您的数据。

每个页面将静态生成,并具有自己的index.html带有标记的文件。

在Gridsome中创建页面有两个选择:

  1. 使用file system - 用单文件组件创建页面。
  2. 使用Pages API - 用编程方式创建页面。

6.1. 基于文件的页面

src/pages目录中的单文件组件将自动转换成它的URL。

文件位置用于生成URL,以下是一些基本示例:

  • src/pages/Index.vue 变成 /(首页)
  • src/pages/AboutUs.vue 变成 /about-us
  • src/pages/about/Vision.vue 变成 /about/vision
  • src/pages/blog/Index.vue 变成 /blog

一个简单的页面组件可能看起来像这样:

<template>
  <div>
    <h1>Hello, world!</h1>
  </div>
</template>

src/pages中的页面通常用于固定网址,例如/about;或用于列出博客文章,例如/blog

6.2. 编程方式创建页面

可以使用gridsome.server.js中的createPages钩子,以编程方式创建页面。

如果您想从外部API手动创建页面而不使用GraphQL数据层,这很有用。

module.exports = function (api) {
  api.createPages(({ createPage }) => {
    createPage({
      path: '/my-page',
      component: './src/templates/MyPage.vue'
    })
  })
}

6.3. 动态路由

页面可以具有动态路由。对于仅需要客户端路由的页面,动态路由很有用。

例如,用户页面根据URL中的片段,从外部API获取信息。

6.4. 页面元信息

Gridsome使用vue-meta处理有关页面的元信息。

<template>
  <div>
    <h1>Hello, world!</h1>
  </div>
</template>

<script>
export default {
  metaInfo: {
    title: 'Hello, world!',
    meta: [
      { name: 'author', content: 'John Doe' }
    ]
  }
}
</script>

6.5. 自定义404页面

创建一个src/pages/404.vue组件,即可自定义404页面。

7. 集合

集合是一组节点,每个节点都包含带有自定义数据的字段。如果您要在网站上放置博客文章,标签,产品等,则集合很有用。

7.1. 添加集合

集合可以通过Source plugins添加,也可以使用Data Store API自己完成。

集合在development和build期间存储在本地内存数据存储中。

节点可以来自本地文件(Markdown,JSON,YAML等)或任何外部的API。

7.2. 使用Source plugins添加集合

将集合添加到Gridsome的最简单方法是使用Source plugins

本示例从WordPress网站创建集合。Source pluginstypeName选项通常用于集合名称添加前缀。

// gridsome.config.js
module.exports = {
  plugins: [
    {
      use: '@gridsome/source-wordpress',
      options: {
        baseUrl: 'YOUR_WEBSITE_URL',
        typeName: 'WordPress',
      }
    }
  ]
}

您可以在 https://gridsome.org/plugins 上浏览源插件。

7.3. 使用Data Store API添加集合

您可以从任何外部API手动添加集合。

本示例创建一个名为Post的集合,该集合从API获取内容,并将结果作为节点添加到该集合。

// gridsome.server.js
const axios = require('axios')

module.exports = function (api) {
  api.loadSource(async actions => {
    const collection = actions.addCollection('Post')

    const { data } = await axios.get('https://api.example.com/posts')

    for (const item of data) {
      collection.addNode({
        id: item.id,
        title: item.title,
        content: item.content
      })
    }
  })
}

7.4. 在GraphQL中的集合

每个集合将向 GraphQL Schema 添加两个根字段,这些根字段用于检索页面中的节点。

字段名称是根据集合名称自动生成的。如果为集合命名Post,则在 Schema 中将具有以下可用字段:

  • post 通过单个id获取节点。
  • allPost 获取节点列表。(可以排序和过滤。)

7.4.1. 自动生成Schema

Schema中的每个集合类型都将具有基于启动时发现的数据自动生成的字段。

这对于简单的项目非常有用,但由于内容已从外部源中删除,因此通常会导致错误,例如缺少字段。您可以使用Schema API定义自己的架构,该架构在数据更改时将保留。

集合的自定义架构类型必须实现该Node接口。

7.4.2. 探索可用的类型和字段

您可以通过在GraphQL资源管理器中打开Schema选项卡来浏览可用字段。

slugify
GitHub:github.com/sindresorhu…
对于URLs、文件名和IDs很实用的Js处理类。它正确处理德语变音符号,越南语,阿拉伯语,俄语,罗马尼亚语,土耳其语等。
安装
npm install @sindresorhus/slugify
用法
const slugify = require('@sindresorhus/slugify'); slugify('I ♥ Dogs');
//=> 'i-love-dogs'
slugify(' Déjà Vu! ');
//=> 'deja-vu'
slugify('fooBar 123 $#%');
//=> 'foo-bar-123'

image.png