建立一个 Astro 静态网站

建立一个 Astro 网站

独立博客的价值

在现代的数字化世界中,媒体平台如Medium、Facebook、微信公众号等无疑提供了一个方便的方式让我们分享和传播自己的想法。然而,随着时间的推移,这些平台的弊端也暴露无遗。首先,这些平台会对你的内容进行审查,限制自由表达。其次,这些平台的算法会对你的文章的可见性产生影响,使得你的文章难以到达你的目标受众。此外,这些平台可能会因为商业原因,随时更改其规则或策略,导致你的努力白费。

相比之下,拥有一个独立的博客可以克服上述问题。独立博客提供了一个自由,可控的环境,你可以随心所欲地发布你的内容,不受第三方平台的限制和审查。此外,你可以完全控制你的博客的设计和布局,这也有助于建立你的个人品牌形象。拥有一个独立的博客也可以让你更好地与你的读者互动,构建一个更深度的社区。

不仅如此,拥有一个自己的博客还会带来一种成就感。每当你发布一篇新的文章,你都会感到自己的成就,这会激励你继续创作和分享更多的内容。这种成就感可能会成为你继续提高自己,不断进步的动力。

总之,建立独立博客可以为你提供更多的自由,更好的控制权,同时也可以帮助你建立个人品牌形象,并提供一种成就感。虽然创建和维护一个博客需要时间和努力,但是从长远来看,非常值得。

建站的一般步骤

  1. 确定目标和主题:明确你的博客的目标和主题,确定你想要分享的内容和定位。

  2. 选择合适的域名:选择一个简洁、易记且与你的博客内容相关的域名。

  3. 选择静态网站生成器:选择一个适合你的需求和技能水平的建站程序,例如 WordPress 、Jekyll、Hugo、Gatsby、Astro等。

  4. 设置开发环境:安装和配置所选静态网站生成器的开发环境,包括相关的编程语言和工具。

  5. 创建网站结构:根据你的需求和主题,设计和创建博客网站的基本结构,包括页面、布局和导航等。

  6. 编写内容:开始撰写和整理你的博客内容,使用合适的标记语言(如 Markdown)来格式化和组织文章。

  7. 选择合适的主题或模板:根据你的喜好和需求,选择一个适合的主题或模板来美化你的博客网站。

  8. 优化网站性能:使用优化技术(如压缩图像、代码和资源)来提升网站的加载速度和性能。

  9. 配置网站部署:选择一个适合的托管平台,如 GitHub Pages、Netlify 或 Vercel,并进行网站部署的相关设置。

  10. 测试和发布:在正式发布之前,确保对你的网站进行全面测试,包括在不同设备和浏览器上的兼容性测试。

  11. 推广和维护:将你的博客分享给你的受众群体,并维护更新你的内容和网站功能。

最佳选择

与此相比,静态网站框架具有明显优势。首先,静态网站的加载速度快,因为它们是预先生成的 HTML 文件,无需动态生成内容或查询数据库。其次,静态网站的安全性更高,因为它们没有数据库或服务器端脚本,这大大减少了被黑客攻击的风险。此外,静态网站的托管成本可能更低,因为你只需要托管静态文件,而不需要一个能运行服务器端脚本的复杂的托管环境。

尽管静态网站生成器可能不适合需要复杂动态功能的网站,但对于大多数个人博客来说,这些功能通常是不必要的。它们提供了优秀的性能、高度的安全性以及低廉的托管成本,静态网站框架是一种既方便又高效的选择。

考虑的因素

  1. 易用性:某些静态网站生成器比其他的更容易使用。如果你是网页开发的新手,你可能想选择一个有着用户友好界面的生成器。
  2. 性能:静态网站生成器可以通过生成在浏览器中快速加载的HTML页面来提高网站性能。
  3. 自定义:某些静态网站生成器提供的自定义选项比其他的更多。如果你想更好地控制你的网站设计和功能,你可能想选择一个允许更多自定义的生成器。
  4. 社区支持:强大的社区可以在使用静态网站生成器时提供有用的资源和支持。
  5. 文档:良好的文档可以让学习如何使用静态网站生成器变得更容易。

流行的静态生成器

  1. Hugo:Hugo 是一个快速且灵活的静态网站生成器,易于使用并且拥有大量的用户社区。
  2. Jekyll:Jekyll 是一个简单的静态网站生成器,易于使用并且有良好的文档。
  3. Gatsby:Gatsby 是一个现代化的静态网站生成器,使用 React 来构建网站。
  4. Eleventy:Eleventy 是一个简单的静态网站生成器,易于使用并且有良好的文档。
  5. Astro 是一个使用 React 来构建网站的静态网站生成器。它被设计为简单易用,并且有详细的文档。Astro 也高度可定制,这使得它成为希望更深度控制他们的网站设计和功能的开发者的好选择。

为什么选择使用 Astro

Astro 是一个简单易用的静态网站生成器,它使用 React 构建网站。Astro 的优点包括:

  1. 速度快:Astro 比其他静态网站生成器更快,因为它使用更小的运行时和更少的依赖项。
  2. 易于使用:Astro 的配置系统非常简单,适合初学者。
  3. 高度可定制:Astro 可以高度定制,可以满足开发人员对网站设计和功能的需求。
  4. 文档齐全:Astro 的文档非常详细,可以帮助开发人员快速上手。

使用 Astro 框架的准备

如果你决定使用 Astro 作为独立博客网站生成器,以下是一些准备工作你可能需要考虑:

  1. 了解基本的前端开发技术:作为网站开发者,你需要具备一定的前端开发知识,例如HTML、CSS 和 JavaScript。这将有助于你理解和修改 Astro 生成的网站。如果你是零基础的小白,也没关系,可以借助 ChatGPT 完整辅助工作。但是,不要盲目相信 ChatGPT,它的信息不及时,而且容易误判,最重要的是看官方文档。

  2. 熟悉 React 框架:Astro 使用 React 来构建网站,因此熟悉 React 的基本概念和语法将有助于你更好地使用 Astro。

  3. 安装和设置 Astro 环境:在开始之前,你需要在你的开发环境中安装和配置 Astro。请遵循 Astro 的官方文档,按照指引完成安装和设置。主要在本地安装 nodejs,git 等开发工具。

  4. 选择编辑器或开发环境:选择一个适合你的编辑器或开发环境,例如 Visual Studio Code、Atom 或 Sublime Text。确保你对所选工具有基本的熟悉程度。这里推荐使用Visual Studio Code,可以与 GitHub 无缝对接,便于部署和调试。

  5. 熟悉 Astro 的文档和使用方式:详细阅读 Astro 的官方文档,了解 Astro 的功能、用法和配置方式。掌握 Astro 的核心概念和工作原理,以便正确使用和配置你的博客网站。 Astro 的官方文档非常详细,而且还有社区翻译的中文版。

  6. 准备博客内容:准备好你的博客内容,包括文章、图片、标签等。你可以使用 Markdown 等格式来编写和组织你的博客文章。静态博客有个特点,主题多为第三方开发,在 Markdown 的元数据格式上会有些差别,需要根据主题要求对 Markdown 文本格式进行调整。

  7. 选择和定制主题:选择一个适合的 Astro 主题或模板,或者根据你的需求进行定制。熟悉主题的结构和配置方式,根据需要进行样式和布局的调整。现在 Astro 的主题还不是特别多,可以在官方和 GitHub 上找到这些开源主题,按需调整使用,不建议开始就用付费主题。

  8. 了解静态网站部署和托管:学习关于静态网站的部署和托管方式,例如使用 GitHub Pages、Netlify、Vercel 等平台。了解如何将你的 Astro 博客网站部署到所选的托管平台。当前最流行的是 Vercel,不仅好用,还有免费额度。

练习

基础配置

这里我们使用 Mac 电脑作为本地工具,使用 homebrew 安装 nodejs 和 git,需要特别注意,如果是国内网络,在安装 homebrew 时,要配置网络代理后,才能顺利安装homebrew。如果你使用的时 clash pro,可以方便的把终端代理命令复制到命令行终端,然后再安装 homebrew ,下面是一个终端代理命令示例。

export https_proxy=http://127.0.0.1:7890 http_proxy=http://127.0.0.1:7890 all_proxy=socks5://127.0.0.1:7890

然后把选择的 Astro clone 到本地,以下以Bookworm Light为例。clone 到本地后,按其说明安装依赖并启用开发调试,首先对开发者建议的配置进行个性化修改。修改完成后推送到 GitHub,并部署到 Vercel , 以上过程,都可以在官方文档找到详细的说明,具体过程不在赘述。成功后再进行其他开发定制。

网站文本的处理

如前所述,Astro 不同主题使用不同 Markdown 元数据,为了成功迁移原有 Markdown 文件,手动修改费时费力,可以借用 ChatGPT 写一个 nodejs 脚本,批量修改 Markdown 文件。以下是一个示例。

提示词(prompt):我有一批 Markdown 文件,需要修改 frontmatter 元数据,请帮我写一个 nodejs 脚本,完成任务。具体要求如下:

  • 将日期转换为 YYYYDDMM 格式
  • title, description 的引号改为双引号
  • category 修改为 categories 并将其值的格式修改为数组形式
  • author 修改为 authors 并将其值修改为 ["XXX"]
  • 添加 image 字段
  • 添加 draft 字段并设置其值为 false
  • 删除layout、 slug 、 cover 、 theme 、 meta 字段及其值

ChatGPT:这个新的脚本应该可以满足你的所有需求。

const fs = require('fs');
const path = require('path');
const matter = require('gray-matter');

const directoryPath = path.join(__dirname, 'your-directory');  // 'your-directory' 替换为你的 markdown 文件夹的路径

fs.readdir(directoryPath, function (err, files) {
    if (err) {
        return console.log('Unable to scan directory: ' + err);
    }

    files.forEach(function (file) {
        if (path.extname(file) === '.md' || path.extname(file) === '.markdown') {
            const filePath = path.join(directoryPath, file);
            const fileContent = fs.readFileSync(filePath, 'utf8');
            const data = matter(fileContent);

            // 根据需求修改 frontmatter
            delete data.data.layout;
            delete data.data.slug;
            delete data.data.cover;
            delete data.data.theme;
            delete data.data.featured;
            delete data.data.meta;
            delete data.data.keywords;

            const pubDate = new Date(data.data.pubDate);
            const isoDate = pubDate.toISOString().replace('.000', '');
            data.data.date = isoDate;
            delete data.data.pubDate;

            if (data.data.title) {
                data.data.title = `"${data.data.title}"`;
            }

            if (data.data.description) {
                data.data.description = `"${data.data.description}"`;
            }

            if (data.data.category) {
                data.data.categories = `[\"${data.data.category}\"]`;
                delete data.data.category;
            }

            data.data.authors = ["Osi"];
            delete data.data.author;

            data.data.image = "https://www.apple.com.cn/newsroom/images/product/homepod/standard/Apple-HomePod-hero-230118_big.jpg.large_2x.jpg";
            data.data.draft = false;

            const updatedContent = matter.stringify(data.content, data.data);

            fs.writeFileSync(filePath, updatedContent, 'utf8');
            console.log(`Modified: ${filePath}`);
        }
    });
});

网站图片的处理

GitHub 官方建议每个 Repo 大小不超过 1G,我们最好选择把图片放在第三方图床,同时使用 .webp.avif等格式的图片以节省空间、流量并提升网站访问速度。这里推荐使用 PicGo 作为图床管理工具。

添加 Waline 插件

没有评论系统的博客网站没有灵魂,添加了评论系统便于博主与访客交流。静态网站生成器很少自带评论系统,这里我们选择使用 Waline 作为评论系统。 准备,按照官网指导,完成客户端、服务端配置,并在 Vercel 设置邮件通知等环境变量。 然后,将 Waline 添加到 Astro 项目中,可以参考在 React 中使用 Waline 的方法。

首先,在 Astro 项目中安装 Waline 客户端:

npm install @waline/client

然后,在src/layouts/components创建一个新的 Astro 组件,例如 Waline.astro,并在其中使用 Waline:

---
// 无需导入依赖,只需确保 Waline 的样式被正确引入
---

<div id='waline' style='margin-left: -7.5px; margin-right: -7.5px' not-prose></div>

<script>
  class WalineComponent extends HTMLElement {
    constructor() {
      super();
      this.initWaline = this.initWaline.bind(this);
    }

    connectedCallback() {
      document.addEventListener('astro:after-swap', this.initWaline);
      this.initWaline();
    }

    disconnectedCallback() {
      document.removeEventListener('astro:after-swap', this.initWaline);
    }

    async initWaline() {
      if (document.getElementById('waline')) {
        try {
          const { init } = await import('https://unpkg.com/@waline/client@v2/dist/waline.mjs');
          init({
            el: '#waline',
            dark: 'auto',
            pageview: true,
            copyright: false,
            serverURL: 'https://comment.yoursite.com',
            locale: {
              placeholder: '留言无需注册,接收回复提醒,留下邮箱',
              level0: '青铜',
              level2: '黄金',
              level3: '铂金',
              level4: '钻石',
              level5: '星耀',
            },
          });
        } catch (e) {
          console.error('Waline initialization failed:', e);
        }
      }
    }
  }

  customElements.define('waline-component', WalineComponent);
</script>

<style>
  body #waline {
    --waline-theme-color: #262626;
    --waline-active-color: #262626;
    --waline-bgcolor: #fff;
  }
  @media (prefers-color-scheme: dark) {
    body #waline {
      --waline-theme-color: #fafafa;
      --waline-active-color: #fafafa;
      --waline-bgcolor: #171717;
    }
  }
</style>

<waline-component></waline-component>

在上述代码中,你需要将 'your Waline server URL' 替换为你的 Waline 服务器 URL,你也可以设置其他 Waline 选项。

然后,你可以在你的 Astro 页面中使用这个 Waline 组件:

---
import Waline from "@components/Waline.astro"; // 引入 Waline 组件
---

<Waline />

这样,Waline 就应该可以在你的 Astro 页面中正常工作了。

添加 Google 分析

统计跟踪代码会拖慢网站访问速度,我们使用 Partytown解决这个问题。Partytown是一个延迟加载的库,用于将资源密集型脚本移到Web Worker中,并从主线程中移出。这对于使用第三方脚本进行分析或广告的情况非常有用,Partytown可以确保脚本不会拖慢你的网站。

使用Partytown的思路如下:

  1. 在Astro项目中安装和配置Partytown有两种方法:使用astro add命令行工具自动安装,或手动安装@astrojs/partytown包并在astro.config.*文件中应用此集成。

  2. 使用Partytown时,你可以通过在脚本标签中添加type="text/partytown"属性来将现有的第三方脚本标记为需要通过Partytown处理的脚本。

  3. 可以通过在astro.config.mjs中的partytown()函数调用中传递一个config对象来配置此集成​。

  4. 将Google Analytics与Partytown集成,需要将Google Analytics脚本标记为type="text/partytown"并将GA_MEASUREMENT_ID替换为你的追踪ID 。

具体步骤如下:

首先,安装@astrojs/partytown库,可以通过npm或yarn来安装:

使用npm:

npm install @astrojs/partytown

使用yarn:

yarn add @astrojs/partytown

然后,在astro.config.mjs文件中引入@astrojs/partytown,并在integrations属性中应用它。

import partytown from "@astrojs/partytown"; // 引入partytown

integrations属性中应用它:

integrations: [partytown()],

对于Google Analytics,在partytown配置中添加forward选项,以便将所有事件转发到Google Analytics:

partytown({
  config: {
    forward: ["dataLayer.push"],
  },
}),

然后在你的网页中添加Google Analytics脚本,设置type属性为text/partytown

<!-- Global site tag (gtag.js) - Google Analytics -->
<script
  type="text/partytown"
  src="https://www.googletagmanager.com/gtag/js?id=GA_MEASUREMENT_ID"
></script>
<script type="text/partytown">
  window.dataLayer = window.dataLayer || [];
  function gtag() {
    dataLayer.push(arguments);
  }
  gtag("js", new Date());
  gtag("config", "GA_MEASUREMENT_ID");
</script>

请注意将上面的GA_MEASUREMENT_ID替换为你的Google Analytics追踪

下面是你添加 Partytown 集成和配置相关选项后的 astro.config.mjs 文件的完整代码。

import image from "@astrojs/image";

import mdx from "@astrojs/mdx";

import react from "@astrojs/react";

import sitemap from "@astrojs/sitemap";

import tailwind from "@astrojs/tailwind";

import { defineConfig } from "astro/config";

import config from "./src/config/config.json";

import vercel from "@astrojs/vercel/static"; // 引入 Vercel 适配器

import partytown from "@astrojs/partytown"; // 引入 partytown,添加Google 分析和广告适配器

export default defineConfig({
  integrations: [
    partytown({
      config: {
        forward: ["dataLayer.push"],
      },
    }),
  ],
});

在这段代码中,我向 integrations 数组中的 partytown 对象添加了一个配置对象。这个配置对象包含一个 forward 数组,该数组包含一个字符串 “dataLayer.push”。这会使 Partytown 将所有事件转发到 Google Analytic。 此外,你也需要在 HTML 的 head 部分添加一段代码,这段代码会启用 Partytown,并将 Google Analytics 的脚本移至 Web Worker。

添加 Google Adsense

  1. 创建 Adsense 组件 创建一个新的 Astro 组件来显示你的 Google Adsense 广告。在你的组件目录中(例如 src/components),创建一个新文件,例如 Adsense.astro,并添加以下代码:
<head>
  <script type="module">
    import { init } from "@astrojs/partytown";
    init();
    const adsbygoogle = window.adsbygoogle || [];
    adsbygoogle.push({});
  </script>
  <script
    type="text/partytown"
    src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-你的广告客户ID"
    crossorigin="anonymous"></script>
</head>
<body>
  <ins
    class="adsbygoogle"
    style="display:block"
    data-ad-client="ca-pub-你的广告客户ID"
    data-ad-slot="你的广告位ID"
    data-ad-format="auto"
    data-full-width-responsive="true"></ins>
</body>

请将 你的广告客户ID你的广告位ID 替换为你从 Google Adsense 获得的实际值。

  1. 在页面中使用 Adsense 组件

最后,你可以在你的 Astro 页面中使用你刚刚创建的 Adsense 组件。例如,如果你想在你的主页中显示广告,你可以在 src/pages/index.astro 中添加以下代码:

---
import Adsense from "../components/Adsense.astro";
---

<Adsense />

这样,每次你的主页被访问时,都会显示一个 Google Adsense 广告。

本地文件管理

我们使用 Obsidian 作为本地文件管理器,同时利用其插件Obsidian Git 与远程 GitHub Repo 建立关联。

优化设置

为了防止频繁文件更改导致 Github Actions 和 Vercel 的频繁执行,可以在对应功能上进行执行限制。比如设置 Github Actions 和 Vercel 在指定文件夹下有文件更改时才执行。

发表于2023-07-02, 更新于2024-05-18