Gridsome 生成靜態站點基礎
1. Gridsome是什麼
- 一個免費、開源、基於VUE.js技術棧的靜態網站生成器
- 官方網址:https://gridsome.org
- GitHub: https://github.com/gridsome/gridsome
2. 什麼是靜態網站生成器
- 靜態網站生成器是使用一系列配置、模板以及資料,生成靜態HTML檔案及相關資源的工具
- 這個功能也叫做預渲染
- 生成的網站不需要類似PHP這樣的伺服器
- 只需要放到支援靜態資源的WebServer或者CDN上即可執行
3. 靜態網站的好處
- 省錢:不需要專業的伺服器,只要能託管靜態檔案的空間即可
- 快速:不經過後端伺服器的處理,只傳輸內容
- 安全:沒有後端程式的支援,自然會更安全
4. 常見的靜態網站生成器
- Jekyll(Ruby)
- Hexo(Node)
- Hugo(Golang)
- Gatsby(Node/React)
- Gridsome(Node/Vue)
- 另外,Next.js/Nuxt.js也能生成靜態網站,但它們更多被認為是SSR(服務端渲染)框架
5. JAMStack
- 這類靜態網站生成器還有個漂亮的名字叫做JAMStack
- JAMStack的JAM是JavaScript、API和Markup的首字母組合
- 本質上是一種胖前端,通過呼叫各種API來實現更多的功能
- 其實也是一種前後端的模式,只不過離的比較開,甚至前後端來自多個不同的廠商。
6. 靜態應用的使用場景
- 不適合有大量路由頁面的應用
- 如果您的站點有成百上千條路由頁面,則預渲染將非常緩慢。當然,您每次更新之需要做一次,但是可能要花一些時間。大多數人不會最終獲得數千條靜態路由頁面,而只是以防萬一。
- 不適合有大量動態內容的應用
- 如果渲染路由中包含特定於使用者檢視其內容或其他動態源的內容,則應確保您具有可以顯示的佔位符元件,直到動態內容載入到客戶端為止,否則可能有點怪異。
7. Gridsome學習建議
- 使用Gridsome需要有一定的Vue基礎,如果有基礎,看過文件,只會覺得它比Vue本身更簡單一些。
二、Gridsome基礎
1. 建立Gridsome專案
Gridsome依賴sharp,國內的使用者很難安裝成功sharp,所以使用淘寶映象安裝sharp。
npm config set sharp_binary_host "https://npm.taobao.org/mirrors/sharp"
npm config set sharp_libvips_binary_host "https://npm.taobao.org/mirrors/sharp-libvips"
sharp是C++語言編寫的,所以還要安裝C++環境。
sharp官網
安裝node-gyp,編譯C++擴充套件包
npm install -g node-gyp
根據node-gyp的官方文件 https://github.com/nodejs/node-gyp 的說明對不同作業系統進行安裝命令:
On Unix
- Python v2.7, v3.5, v3.6, v3.7, or v3.8
make
- A proper C/C++ compiler toolchain, like GCC
On macOS
ATTENTION: If your Mac has been upgraded to macOS Catalina (10.15), please read macOS_Catalina.md.
- Python v2.7, v3.5, v3.6, v3.7, or v3.8
- Xcode
- You also need to install the
XCode Command Line Tools
by runningxcode-select --install
. Alternatively, if you already have the full Xcode installed, you can find them under the menuXcode -> Open Developer Tool -> More Developer Tools...
. This step will installclang
,clang++
, andmake
.
- You also need to install the
On Windows
Install the current version of Python from the Microsoft Store package.
Install all the required tools and configurations using Microsoft’s windows-build-tools using npm install --global windows-build-tools
(搜尋cmd,然後右鍵“以管理員身份執行”,然後再安裝) from an elevated PowerShell or CMD.exe (run as Administrator).
然後根據Gridsome官網https://gridsome.org/docs/的教程安裝gridsome,
npm install --global @gridsome/cli
拉取遠端模板到本地:
gridsome create my-gridsome-site
如果安裝不成功,修改host檔案
安裝依賴的時候比較慢,又沒有進度條,可以按ctrl+C中斷掉,然後進入已經生成的my-gridsome-site
目錄下,執行rm -rf node_modules
刪除半成品node_modules,然後重新執行npm install
,此時就能看到進度了。
安裝好依賴之後,可以在package.json裡檢視命令。
執行npm run develop
啟動專案
訪問http://localhost:8080/看到以下頁面就證明啟動成功了。
2. 預渲染
建立一個Foo.vue頁面
<template>
<div>
<h1>Foo Page</h1>
</div>
</template>
<script>
export default {
name: 'FooPage'
}
</script>
<style>
</style>
然後執行npm run build
進行打包,打包後生成了一個dist檔案
然後起一個靜態服務:serve dist
如果沒有serve,要全域性安裝下npm i serve -g
然後訪問http://localhost:5000就可以看到頁面是由服務端渲染好了返回的,然後客戶端的互動都是單頁面應用形式。
3. 目錄結構
src/main.js
是整個專案的啟動入口,裡面載入了/layouts/Default.vue
// This is the main.js file. Import global CSS and scripts here.
// The Client API can be used here. Learn more: gridsome.org/docs/client-api
import DefaultLayout from '~/layouts/Default.vue'
export default function (Vue, { router, head, isClient }) {
// Set default layout as a global component
Vue.component('Layout', DefaultLayout)
}
Default.vue
中有個特別之處:
<static-query>
query {
metadata {
siteName
}
}
</static-query>
這個query是查詢gridsome資料給元件用的。
src/templates
資料夾是放集合的節點。
src/pages
是路由頁面。
src/layouts
放佈局元件。
src/components
放公共元件。
src/.temp
放打包過程生成的檔案。
.catch
是快取的一些內容
node_modules
放第三方包
static
放不需要打包編譯的檔案,指靜態的資源
gridsome.config.js
gridsome的配置檔案
gridsome.server.js
也是girdsome的配置檔案,是配置服務端的,Gridsome內部的服務配置。
4. 專案配置
gridsome.config.js
// This is where project configuration and plugin options are located.
// Learn more: https://gridsome.org/docs/config
// Changes here require a server restart.
// To restart press CTRL + C in terminal and run `gridsome develop`
module.exports = {
siteName: '肖戰', // 頁面上的名稱
pathPrefix: '/my-app', // 路徑字首, 部署是否有子目錄
templates: {}, // 定義路由模版
configgureWebapck: {}, // type Object | Function webpack 配置
siteDescription: '大前端', // meta 名稱
plugins: [] // 配置外掛
}
5. Pages
pages 就是我們專案當中的路由元件,最終會生成路由頁面,在編譯的時候會成為靜態的HTML
(1) 基於檔案形式建立
直接在src/pages目錄下建立一個檔案,就是一個新的路由了
(2) 基於程式設計方式通過createPage
gridsome.server.js
api.createPages(({ createPage }) => {
// Use the Pages API here: https://gridsome.org/docs/pages-api/
createPage({
path: '/my-page',
component: './src/templates/MyPage.vue'
})
})
src/templates/MyPage.vue
<template>
<div>
<h1>
MyPage
</h1>
</div>
</template>
<script>
export default {
name: 'MyPage',
metaInfo: {
title: 'MyPage' // 配置header中的title
}
}
</script>
<style>
</style>
重啟專案後訪問http://localhost:8080/my-page
就可以看到MyPage頁面。
6. 動態路由
(1) pages下面建立的頁面檔名稱用方括號括起來,作為動態路由引數
src/pages/user/[id].vue
<template>
<div>
<h1>
User {{ $route.params.id }} Page
</h1>
</div>
</template>
<script>
export default {
name: 'UserPage'
}
</script>
<style>
</style>
重啟後訪問:http://localhost:8080/user/1
就可以看到 User 1 Page 這個內容了
(2) 程式設計方式
gridsome.server.js
api.createPages(({ createPage }) => {
createPage({
path: '/user/:id(\\d+)',
component: './src/templates/User.vue'
})
})
7. 新增集合
定義一個頁面Posts1.vue
<template>
<Layout>
<h1>Posts1</h1>
<ul>
<li v-for="post in posts" :key="post.id">{{ post.title }}</li>
</ul>
</Layout>
</template>
<script>
import axios from 'axios'
export default {
name: 'Posts1',
data () {
return {
posts: []
}
},
async created () {
const { data } = await axios.get('https://jsonplaceholder.typicode.com/posts')
this.posts = data
}
}
</script>
<style>
</style>
資料是在客戶端動態載入請求過來的,不是預渲染生成的。
想要資料預渲染,得使用Gridsome中的集合Collections
// 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://jsonplaceholder.typicode.com/posts')
for (const item of data) {
collection.addNode({
id: item.id,
title: item.title,
content: item.body
})
}
})
}
8. 在GraphQL中查詢資料
9. 在頁面中查詢GraphQL查詢資料
Posts2.vue,靜態頁面,服務端渲染的
<template>
<Layout>
<h1>Posts2</h1>
<ul>
<li v-for="edge in $page.posts.edges" :key="edge.node.id">
<g-link to="/">{{edge.node.title}}</g-link>
</li>
</ul>
</Layout>
</template>
<script>
export default {
name: 'Posts2',
}
</script>
<style>
</style>
<page-query>
query {
posts: allPost {
edges {
node {
id
title
}
}
}
}
</page-query>
10. 使用模板渲染結點
配置動態路由模板
// gridsome.config.js
module.exports = {
siteName: '拉鉤教育',
siteDescription: '大前端',
plugins: [],
templates: {
Post: [
{
path: '/posts/:id',//gridsome.serve裡面新增集合資料裡面唯一主鍵這裡是id
component: './src/templates/Post.vue'
}
]
}
}
模板頁面src/template/Post.vue,預渲染頁面,從GraphQL獲取的資料
<template>
<Layout>
<h1>{{$page.post.title}}</h1>
<p>{{$page.post.content}}</p>
</Layout>
</template>
<page-query>
query($id: ID!) { # 動態路由引數會自動傳入進來
post(id: $id) {
id
title
content
}
}
</page-query>
<script>
export default {
name: 'PostPage',
metaInfo () {
return {
title: this.$page.post.title
}
}
}
</script>
<style>
</style>
metaInfo寫成函式形式可以通過this.$page
獲取到graphQL返回的資料。
三、Gridsome案例
1. 建立專案
gridsome create blog-with-gridsome
當進入install的時候按ctrl C中斷,然後進入資料夾執行npm install來安裝第三方包
cd blog-with-gridsome
npm install
2. 處理首頁模板
Fork Bootstrap
的一個模板:https://github.com/StartBootstrap/startbootstrap-clean-blog
然後blog-with-gridsome平級目錄執行git clone https://github.com/cloveryuan/startbootstrap-clean-blog.git --depth=1
,只克隆最後一個版本就行了。
然後回到我們的專案中,安裝需要的依賴
npm i bootstrap
npm i @fortawesome/fontawesome-free
建立src/assets/css/index.css
@import url('https://fonts.googleapis.com/css?family=Lora:400,700,400italic,700italic');
@import url('https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800');
/* 下面將startbootstrap-clean-blog裡面的css/clean-blog.css裡面的內容複製到此處 */
在src/main.js中開始位置增加:
import 'bootstrap/dist/css/bootstrap.min.css'
import '@fortawesome/fontawesome-free/css/all.min.css'
import './assets/css/index.css'
把startbootstrap-clean-blog中的img資料夾拷貝到我們的專案中的static中,作為靜態資源使用。
把startbootstrap-clean-blog中的index.html裡面的body部分的HTML程式碼拷貝到我們的專案中的src/pages/Index.vue中
3. 處理其他頁面模板
將Index.vue中的頭部、尾部程式碼剪下到layouts/Default.vue中,注意頭尾程式碼塊中間要放一個<slot/>
插槽
然後將Index.vue的最外層元件由div改為Layout。Layout已經在全域性註冊過了,可以直接使用
然後寫Post.vue、About.vue、Contact.vue頁面,把startbootstrap-clean-blog中的post.html、about.html、contact.html中的程式碼拿過來即可。圖片載入不了,記得在img前面加上/,從根路徑出發
4. 使用本地md檔案管理文章內容
npm i @gridsome/source-filesystem
npm i @gridsome/transformer-remark # 轉換MD檔案
建立兩個md檔案, content/blog/article1.md、contetn/blog/artcle2.md
//gridsome.config.js
module.exports = {
siteName: 'blog',
plugins: [
{
use: '@gridsome/source-filesystem',
options: {
typeName: 'BlogPost',
path: './content/blog/**/*.md',
}
}
]
}
在GraphQL中查詢資料:
5. Strapi介紹
網址:https://strapi.io/
strapi是一個通用的內容管理系統。
執行建立strapi命令
yarn create strapi-app my-project --quickstart
建立一個Content Type
6. 使用strapi資料介面
預設是Restful API
https://strapi.io/documentation/v3.x/content-api/api-endpoints.html#get-an-entry
給使用者配置許可權:設定下也可配置許可權
使用Postman進行介面測試:
7. 訪問受保護的API
建立一個使用者:admin, 123456
註冊、登入的API:https://strapi.io/documentation/v3.x/plugins/users-permissions.html#concept
使用Postman測試登入介面 拿到token就是Authorization
請求其他介面時,http頭部要增加授權資訊Authorization: Bearer ${token}
8. 將Strapi資料預取到Gridsome應用中
安裝
npm install @gridsome/source-strapi
使用
// gridsome.config.js
export default {
plugins: [
{
use: '@gridsome/source-strapi',
options: {
apiURL: 'http://localhost:1337',
queryLimit: 1000, // Defaults to 100
contentTypes: ['post','tag'],//後面在strapi上建的集合
//singleTypes: ['impressum'],
// Possibility to login with a Strapi user,
// when content types are not publicly available (optional).
loginData: {
identifier: '',
password: ''
}
}
}
]
}
重啟應用,才會拉取最新資料。
9. 設計文章標籤資料模型
刪除原來的測試資料:
建立新的Content Type,名稱為Post,有四個欄位
再建立一個新的Content Type,名稱為Tag,有兩個欄位,其中欄位posts為引用型別,為多對多的關係
新增一個Tag,標題為HTML
然後修改post裡面的標題為post 1的資料,選擇Tags為HTML
然後回到Tags表中的HTML資料的編輯屏,還可以再關聯別的Posts
10. 展示文章列表、分頁
src/pages/Index.vue
<template>
<Layout>
<!-- Page Header -->
<header class="masthead" style="background-image: url('/img/home-bg.jpg')">
<div class="overlay"></div>
<div class="container">
<div class="row">
<div class="col-lg-8 col-md-10 mx-auto">
<div class="site-heading">
<h1>Clean Blog</h1>
<span class="subheading">A Blog Theme by Start Bootstrap</span>
</div>
</div>
</div>
</div>
</header>
<!-- Main Content -->
<div class="container">
<div class="row">
<div class="col-lg-8 col-md-10 mx-auto">
<div class="post-preview" v-for="edge in $page.posts.edges" :key="edge.node.id">
<g-link :to="'post/'+edge.node.id">
<h2 class="post-title">
{{edge.node.title}}
</h2>
</g-link>
<p class="post-meta">
Posted by
<a href="#">{{edge.node.created_by.firstname + edge.node.created_by.lastname}}</a>
on {{edge.node.created_at}}
</p>
<p>
<span v-for="tag in edge.node.tags" :key="tag.id">
<a href="">{{tag.title}}</a>
</span>
</p>
<hr />
</div>
<Pager :info="$page.posts.pageInfo" />
</div>
</div>
</div>
</Layout>
</template>
<page-query>
query ($page: Int) {
posts: allStrapiPost (perPage: 2, page: $page) @paginate {
pageInfo {
totalPages
currentPage
}
edges {
node {
id
title
created_at
created_by {
id
firstname
lastname
}
tags {
id
title
}
}
}
}
}
</page-query>
<script>
import { Pager } from 'gridsome'
export default {
name: 'HomePage',
components: {
Pager
},
metaInfo: {
title: "Hello, world!",
},
};
</script>
11. 展示文章詳情
gridsome.config.js
module.exports = {
siteName: 'Gridsome',
plugins: [
{
use: '@gridsome/source-filesystem',
options: {
typeName: 'BlogPost',
path: './content/blog/**/*.md'
}
},
{
use: '@gridsome/source-strapi',
options: {
apiURL: 'http://localhost:1337',
queryLimit: 1000, // Defaults to 100
contentTypes: ['post', 'tag'], // StrapiPost
// typeName: 'Strapi,
// singleTypes: ['impressum'],
// Possibility to login with a Strapi user,
// when content types are not publicly available (optional).
// loginData: {
// identifier: '',
// password: ''
// }
}
}
],
templates: {
// StrapiPost為上面Plugin中配置的typeName和contentTypes的組合
StrapiPost: [
{
path: '/post/:id',
component: './src/templates/Post.vue'
}
]
}
}
src/templates/Post.vue
<template>
<Layout>
<!-- Page Header -->
<header
class="masthead"
:style="{backgroundImage: `url(http://localhost:1337${$page.post.cover.url})`}"
>
<div class="overlay"></div>
<div class="container">
<div class="row">
<div class="col-lg-8 col-md-10 mx-auto">
<div class="post-heading">
<h1>{{$page.post.title}}</h1>
<span class="meta"
>Posted by
<a href="#">{{$page.post.created_by.firstname + $page.post.created_by.lastname}}</a>
on {{$page.post.created_at}}</span
>
</div>
</div>
</div>
</div>
</header>
<!-- Post Content -->
<article>
<div class="container">
<div class="row">
<div class="col-lg-8 col-md-10 mx-auto">
{{$page.post.content}}
</div>
</div>
</div>
</article>
</Layout>
</template>
<page-query>
query($id: ID!) {
post: strapiPost(id: $id) {
id
title
content
cover {
url
}
tags {
id
title
}
created_at
created_by {
id
firstname
lastname
}
}
}
</page-query>
<script>
export default {
name: 'PostPage'
}
</script>
<style></style>
12. 處理Markdown格式的文章內容
安裝markdown處理器:npm install markdown-it
src/templates/Post.vue
<div class="col-lg-8 col-md-10 mx-auto" v-html="mdToHtml($page.post.content)">
</div>
<script>
import MarkDownIt from 'markdown-it'
const md = new MarkDownIt()
export default {
name: 'PostPage',
methods: {
mdToHtml (markdown) {
return md.render(markdown)
}
}
}
</script>
13. 文章標籤處理
src/templates/Tag.vue
<template>
<Layout>
<!-- Page Header -->
<header class="masthead" style="background-image: url('/img/home-bg.jpg')">
<div class="overlay"></div>
<div class="container">
<div class="row">
<div class="col-lg-8 col-md-10 mx-auto">
<div class="site-heading">
<h1># {{$page.tag.title}}</h1>
</div>
</div>
</div>
</div>
</header>
<!-- Main Content -->
<div class="container">
<div class="row">
<div class="col-lg-8 col-md-10 mx-auto">
<div class="post-preview" v-for="post in $page.tag.posts" :key="post.id">
<g-link :to="'post/'+post.id">
<h2 class="post-title">
{{post.title}}
</h2>
</g-link>
<p class="post-meta">
Posted by
on {{post.created_at}}
</p>
<hr />
</div>
</div>
</div>
</div>
</Layout>
</template>
<page-query>
query($id: ID!) {
tag: strapiTag(id: $id) {
title
id
posts {
id
title
created_at
}
}
}
</page-query>
<script>
export default {
name: 'TagPage'
}
</script>
<style>
</style>
gridsome.config.js
module.exports = {
siteName: 'Gridsome',
plugins: [
{
use: '@gridsome/source-filesystem',
options: {
typeName: 'BlogPost',
path: './content/blog/**/*.md'
}
},
{
use: '@gridsome/source-strapi',
options: {
apiURL: 'http://localhost:1337',
queryLimit: 1000, // Defaults to 100
contentTypes: ['post', 'tag'], // StrapiPost
}
}
],
templates: {
// StrapiPost為上面Plugin中配置的typeName和contentTypes的組合
StrapiPost: [
{
path: '/post/:id',
component: './src/templates/Post.vue'
}
],
StrapiTag: [
{
path: '/tag/:id',
component: './src/templates/Tag.vue'
}
]
}
}
14. 網站基本設定
建立Single Type
建立一個名為general的Single Type,有三個欄位,如下:
配置general資料:
gridsome.config.js的source-strapi外掛增加singleTypes: ['general']
配置,就可以獲取general資料,重啟專案就生效。
src/pages/Index.vue
<!-- Page Header -->
<header
class="masthead"
:style="{
backgroundImage: `url(http://localhost:1337${general.cover.url})`
}"
>
<div class="overlay"></div>
<div class="container">
<div class="row">
<div class="col-lg-8 col-md-10 mx-auto">
<div class="site-heading">
<h1>{{general.title}}</h1>
<span class="subheading">{{general.subtitle}}</span>
</div>
</div>
</div>
</div>
</header>
<page-query>
query ($page: Int) {
# ----
general: allStrapiGeneral {
edges {
node {
title
subtitle
cover {
url
}
}
}
}
}
</page-query>
<script>
import { Pager } from 'gridsome'
export default {
// ----
computed: {
general () {
return this.$page.general.edges[0].node
}
}
};
</script>
15. 聯絡我 Contact頁面
建立一個contact的Content Type
使用Postman建立一條資料
頁面中使用傳統客戶端表單提交功能
src/pages/Contact.vue
<input v-model="form.name" type="text" class="form-control" placeholder="Name" id="name" required data-validation-required-message="Please enter your name.">
<input v-model="form.email" type="email" class="form-control" placeholder="Email Address" id="email" required data-validation-required-message="Please enter your email address.">
<input v-model="form.phone" type="tel" class="form-control" placeholder="Phone Number" id="phone" required data-validation-required-message="Please enter your phone number.">
<textarea v-model="form.message" rows="5" class="form-control" placeholder="Message" id="message" required data-validation-required-message="Please enter a message."></textarea>
<button type="submit" class="btn btn-primary" id="sendMessageButton" @click.prevent="onSubmit">Send</button>
<script>
import axios from 'axios'
export default {
name: 'ContactPage',
data () {
return {
form: {
name: '',
email: '',
phone: '',
message: ''
}
}
},
methods: {
async onSubmit () {
try {
const { data } = await axios({
method: 'POST',
url: 'http://localhost:1337/contacts',
data: this.form
})
window.alert('傳送成功')
} catch (e) {
alert('傳送失敗,請稍後重試')
}
}
}
}
</script>
16. 部署strapi
先部署strapi、再部署Gridsome。strapi部署環境依賴於node環境的伺服器,而Gridsome只需要支援靜態網頁的伺服器就行。
(1) 配置為strapi後臺服務配置資料庫為MySQL
其他資料庫配置可以參考這裡:https://strapi.io/documentation/v3.x/concepts/configurations.html#database
config/database.js
module.exports = ({ env }) => ({
defaultConnection: 'default',
connections: {
default: {
connector: 'bookshelf',
settings: {
client: 'mysql',
host: env('DATABASE_HOST', 'localhost'),// strapi部署的伺服器與MySQL所在的伺服器是同一個伺服器,主機就直接寫localhost
port: env.int('DATABASE_PORT', 3306),
database: env('DATABASE_NAME', 'blog'),
username: env('DATABASE_USERNAME', 'blog'),
password: env('DATABASE_PASSWORD', 'oPqc0Am9lfhWKNuT'),
},
options: {},
},
},
});
安裝MySQL資料的依賴
npm install mysql
(2) 將程式碼上傳到gitee上
git init
echo node_modules > .gitignore
git add .
git commit -m"第一次提交"
git remote add origin git@gitee.com:jiailing/blog-backend.git
git push -u origin master
(3) 登入到伺服器進行部署
- ssh root@47.110.10.236進入伺服器,
- 拉去遠端程式碼(git clone https://gitee.com/cloveryuan/blog-backend.git),
- cd blog-backend
- 安裝依賴包(npm i)
- 打包(npm run build)
- pm2 start npm – run start – name blog-backend (通過pm2啟動,blog-backend是起的別名)
先進入MySQL
mysql -uroot -p
建立使用者blog,和資料庫blog,並且給該使用者授權操作該資料庫
CREATE USER 'blog'@'%' IDENTIFIED BY 'oPqc0Am9lfhWKNuT';
CREATE DATABASE blog;
FLUSH PRIVILEGES;
GRANT ALL ON blog.* TO 'blog'@'%';
exit;
然後回到存放程式碼的目錄下,拉取gitee上的程式碼,並且安裝專案依賴
git clone https://gitee.com/jiailing/blog-backend
cd blog-backend
npm config set sharp_binary_host "https://npm.taobao.org/mirrors/sharp"
npm config set sharp_libvips_binary_host "https://npm.taobao.org/mirrors/sharp-libvips"
npm install
npm run build
npm run start
或者執行npm run develop
也可以啟動專案。
如果執行build時命令列卡在了90%進度時,直接中斷掉執行start就可以了。
然後就可以通過 主機地址+1337埠號來訪問頁面了。
start 此時命令列被佔用,退出命令列服務就會停止,所以使用pm2守護程式,讓一個node應用啟動在後臺
pm2 start --name blog-backend npm -- run start
或者
pm2 start --name blog-backend npm -- run develop
記得去伺服器的例項安全組新增埠1337
依舊是通過 主機地址+1337埠號來訪問頁面。
登入後別忘了給使用者分配許可權
17. 把本地服務連通遠端應用
grid.config.js中的strapi外掛的配置中的URL介面要改為線上介面,
apiURL: process.env.GRIDSOME_API_URL
為了區分開發介面和生產介面,可以配置環境變數
.env.production
GRIDSOME_API_URL=http://jiailing.com:1337
.env.development
GRIDSOME_API_URL=http://localhost:1337
在src/main.js中注入環境變數到頁面模板中使用:
export default function (Vue, { router, head, isClient }) {
Vue.mixin({
data () {
return {
GRIDSOME_API_URL: process.env.GRIDSOME_API_URL
}
}
})
// Set default layout as a global component
Vue.component('Layout', DefaultLayout)
}
將頁面中之前用到localhost:1337的路徑都替換掉,如背景圖片:
:style="{backgroundImage: `url(${GRIDSOME_API_URL+$page.post.cover.url})`}"
18. 部署Gridsome應用
vercel可以使得在Gridsome程式碼發生了改變,或者strapi的資料發生了改變時,都可以觸發Gridsome的自動部署。
Vercel網址:vercel.com
使用GitHub登入,GitHub的郵箱是QQ郵箱會出問題,我改成了sina郵箱就可以了。
匯入blog前端倉庫的地址,我已經將專案上傳到了GitHub上了。
飄下了成功的綵帶~
建立自動部署鉤子
複製鉤子到strapi裡
在strapi的設定裡新增webHook,請求地址為剛才複製的Vercel的裡部署鉤子地址。
修改程式碼提交或者是strapi資料變化都會觸發Vercel裡的專案重新部署:
相關文章
- 新手必會的靜態站點生成器——Gridsome
- 基於React的SSG靜態站點渲染方案React
- Rust 的靜態網站生成器「GitHub 熱點速覽」Rust網站Github
- 前端靜態站點部署方案前端
- [譯] 2018 年,如何選擇最好的靜態站點生成器
- Spring Boot 2.x基礎教程:Swagger靜態文件的生成Spring BootSwagger
- Hugo -最好用的靜態網站生成器Go網站
- 使用Java和Maven(JBake)生成靜態網站 - optaplannerJavaMaven網站
- 靜態庫生成
- 靜態PDO基礎操作封裝封裝
- Java基礎系列-靜態代理和動態代理Java
- Pelican 入門:一個 Python 靜態網站生成器Python網站
- Java逆向基礎之靜態變數存取Java變數
- Django基礎二靜態檔案和ORMDjangoORM
- 靜態點分治
- cmake:生成靜態庫和動態庫
- 基於 Svelte 的通用靜態網站開發模板網站
- nuxt-generate 靜態站UX
- 網站偽靜態配置網站
- 網站靜態化思想網站
- ZBlogPHP怎麼生成偽靜態?PHP
- Linux 靜態庫生成及呼叫Linux
- Nuxtjs實現服務端渲染和靜態化站點UXJS服務端
- 零基礎用GitHub page搭建靜態部落格Github
- blog-engine-06-pelican 靜態網站生成 支援 markdown 和 reST 語法網站REST
- Django+nginx+靜態網站DjangoNginx網站
- 關於php生成靜態問題PHP
- 如何打造一款靜態開源站點搭建工具
- Hexo、VitePress、Docusaurus,哪個最適合你的靜態網站生成器?HexoVite網站
- 前後端,靜態網站和動態網站, 的理解後端網站
- 【python基礎】什麼是動態IP?與靜態ip有什麼不同?Python
- [譯] 用 Workers 讓靜態網站動態化網站
- 【URLOS應用開發基礎】10分鐘製作一個nginx靜態網站環境應用Nginx網站
- PbootCMS網站IIS偽靜態規則boot網站
- PbootCMS網站apache偽靜態規則boot網站Apache
- PbootCMS網站nginx偽靜態規則boot網站Nginx
- Serverless實踐-靜態網站託管Server網站
- docker容器中佈置靜態網站Docker網站