在上一篇《制作静态网站模板如何选架构?》中,我们探讨了选择 Astro、Tailwind CSS、daisyUI 和 Alpine.js 作为现代化网站模板技术栈的理由。本文将承接上一篇的内容,手把手带你搭建一个集成了这些最新技术的开发环境。

重要提示:前端技术更新迭代迅速,本教程尽可能基于写作时(2025年中)的最新稳定版本。在实际操作时,请务必查阅各工具的官方文档,以获取最准确和最新的安装指令与配置方法。

接下来,我们来构建一个基础的环境。

一、环境准备

在开始之前,请确保你的开发环境中已安装以下软件:

  • Node.js: Astro 和其他多数前端工具都依赖 Node.js。建议安装最新的 LTS (长期支持) 版本或更高版本。你可以从 Node.js 官网 下载并安装。

  • npm / yarn / pnpm: Node.js 自带 npm。你也可以选择使用 yarn 或 pnpm 作为包管理工具。本教程将主要使用 npm 的命令,你可以根据自己的喜好替换。

你可以通过在终端运行以下命令来检查 Node.js 和 npm 是否已正确安装:

node -v
npm -v

二、创建全新的 Astro 项目

Astro 提供了便捷的脚手架工具,可以快速初始化一个新项目。

https://docs.astro.build/zh-cn/install-and-setup/#%E9%80%9A%E8%BF%87-cli-%E5%90%91%E5%AF%BC%E5%AE%89%E8%A3%85
  1. 创建项目:

    打开你的终端,运行以下命令来创建一个新的 Astro 项目。my-astro-site 是你的项目名称,你可以替换成自己喜欢的名字。

    npm create astro@latest sky-site1
  2. 根据提示进行配置:

    在创建过程中,Astro 的 CLI 会询问你一些问题,例如:

    • Where would you like to create your new project? (项目路径,默认为 ./sky-site1)

    • How would you like to start your new project? (选择一个模板,推荐选择 "Empty" 等基础模板开始)

    • Install dependencies? (是否安装依赖,选 Yes)

    • Initialize a new git repository? (是否初始化 Git 仓库,根据你的需求选择)

    根据提示完成选择即可。

  3. 进入项目目录并启动开发服务器

    cd sky-site1
    npm run dev

    启动成功后,你会在终端看到本地开发服务器的地址 (通常是 http://localhost:4321)。在浏览器中打开该地址,你应该能看到 Astro 的欢迎页面。

三、集成 Tailwind CSS

Astro 官方提供了对 Tailwind CSS 的集成支持,非常方便。

https://tailwindcss.com/docs/installation/framework-guides/astro
  1. 安装 Astro Tailwind 集成:

    在你的 Astro 项目根目录下,运行以下命令:

    npx astro add tailwind

    此命令会自动安装 tailwindcsstailwindcss/vite 等必要的依赖,同时在 astro.config.mjs 中添加 Tailwind 集成。按回车或是Y

  2. 配置 astro.config.mjs (自动配置好的)

    打开项目根目录下的astro.config.mjs 文件。Astro 的集成通常已经为你配置好了插件引用

    // @ts-check
    import { defineConfig } from 'astro/config';
    import mdx from '@astrojs/mdx';
    import sitemap from '@astrojs/sitemap';
    
    import tailwindcss from '@tailwindcss/vite';
    
    // https://astro.build/config
    export default defineConfig({
      site: 'https://example.com',
      integrations: [mdx(), sitemap()],
    
      vite: {
        plugins: [tailwindcss()],
      },
    });
  3. 创建全局 CSS 文件并引入 Tailwind 指令:(默认会自动创建一个)

    在 src/ 目录下创建一个全局 CSS 文件,例如 src/styles/global.css (如果模板中没有的话)。在该文件中添加 Tailwind CSS 的指令:

    /* src/styles/global.css */
    @import "tailwindcss";
    
  4. 在布局或页面中引入全局 CSS:

    为了让 Tailwind CSS 生效,你需要在你的主布局文件 (通常在 src/layouts/) 或直接在页面中引入这个全局 CSS 文件。

    例如,在 src/layouts/Layout.astro

    ---
    // src/layouts/Layout.astro
    import '../styles/global.css'; // 引入全局 CSS
    
    export interface Props {
      title: string;
    }
    
    const { title } = Astro.props;
    ---
    <!doctype html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta name="description" content="Astro description" />
        <meta name="viewport" content="width=device-width" />
        <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
        <meta name="generator" content={Astro.generator} />
        <title>{title}</title>
      </head>
      <body>
        <slot />
      </body>
    </html>
    
    
  5. 测试 Tailwind CSS:

    现在你可以在你的 .astro 文件或组件中使用 Tailwind CSS 的类名了。例如,修改 src/pages/index.astro:

    ---
    import Layout from '../layouts/Layout.astro';
    ---
    
    <Layout title="Welcome to Astro with Tailwind!">
      <main class="flex flex-col items-center justify-center min-h-screen bg-gradient-to-r from-purple-500 to-pink-500">
        <h1 class="text-5xl font-bold text-white mb-8">
          Hello, Astro + Tailwind CSS!
        </h1>
        <p class="text-xl text-gray-200">
          This is a test to see if Tailwind CSS is working.
        </p>
      </main>
    </Layout>
    
    

    启动开发服务器 (npm run dev),你应该能看到应用了 Tailwind CSS 样式的页面。

四、添加 daisyUI 组件库

daisyUI 是一个基于 Tailwind CSS 的插件,可以快速提供预设的 UI 组件。.

https://daisyui.com/docs/install/astro/
  1. 安装 daisyUI:

    在项目根目录下运行:

    npm install -D daisyui@latest
  2. 在 Tailwind CSS 配置中启用 daisyUI:

    v4新版本并不需要配置 tailwind.config.mjs 文件,只需要在css下面增加在 plugins 数组中添加 daisyui:

    /* src/styles/global.css */
    @import "tailwindcss";
    @plugin "daisyui";
    

    你可以根据 daisyUI 官方文档按需配置其选项。

  3. 使用 daisyUI 组件:

    现在你可以在你的 Astro 组件中使用 daisyUI 提供的组件类名了。例如,在 src/pages/index.astro 中添加一个按钮:

    ---
    import Layout from '../layouts/Layout.astro';
    ---
    
    <Layout title="Astro + Tailwind + daisyUI">
      <main class="flex flex-col items-center justify-center min-h-screen p-4">
        <h1 class="text-4xl font-bold mb-6">Welcome!</h1>
        <button class="btn btn-primary">Primary Button</button>
        <button class="btn btn-secondary mt-4">Secondary Button</button>
      </main>
    </Layout>
    
    

    启动开发服务器,你应该能看到 daisyUI 样式的按钮。

五、集成 Alpine.js

Alpine.js 是一个轻量级的 JavaScript 框架,非常适合为静态页面添加交互性。Astro 也对其有良好的支持。

https://docs.astro.build/zh-cn/guides/integrations-guide/alpinejs/
  1. 安装 Alpine.js:

    在项目根目录下运行:

    npx astro add alpinejs
    # 此命令会自动安装 astrojs/alpinejs、types/alpinejs alpinejs等必要的依赖
  2. 配置 astro.config.mjs (自动配置好的)

    打开项目根目录下的astro.config.mjs 文件。Astro 的集成通常已经为你配置好了插件引用

    // @ts-check
    import { defineConfig } from 'astro/config';
    
    import tailwindcss from '@tailwindcss/vite';
    
    import alpinejs from '@astrojs/alpinejs';
    
    // https://astro.build/config
    export default defineConfig({
      vite: {
        plugins: [tailwindcss()]
      },
    
      integrations: [alpinejs()]
    });
  3. 在布局或页面中准备 Alpine.js (如果需要全局 store 或自定义初始化): 对于大多数 Alpine.js 的使用场景,通过 @astrojs/alpinejs 集成后,你可以直接在你的 Astro 组件的 HTML 部分使用 Alpine 指令。 如果你需要在 Alpine.js 初始化时注册全局 store 或执行其他自定义设置,可以在你的主布局文件 (src/layouts/Layout.astro) 的 <head> 中添加一个内联脚本:

    ---
    // src/layouts/Layout.astro
    import '../styles/global.css';
    export interface Props {
      title: string;
    }
    const { title } = Astro.props;
    ---
    <!doctype html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta name="description" content="Astro description" />
        <meta name="viewport" content="width=device-width" />
        <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
        <meta name="generator" content={Astro.generator} />
        <title>{title}</title>
        <script is:inline>
          // is:inline 确保这段脚本在 Alpine.js 初始化之前执行
          document.addEventListener('alpine:init', () => {
            console.log('Alpine.js initialized!');
            // 例如,注册一个全局 store
            // window.Alpine.store('darkMode', {
            //   on: false,
            //   toggle() {
            //     this.on = !this.on;
            //   }
            // });
          });
        </script>
      </head>
      <body>
        <slot />
        {/* Alpine.js 会由 @astrojs/alpinejs 集成自动注入和启动 */}
      </body>
    </html>
    
    

    注意:你之前在 <body> 底部手动 import('alpinejs').then(...) 的方式,在使用 @astrojs/alpinejs 集成后通常不再需要,因为集成会处理 Alpine.js 的加载和启动。

使用 Alpine.js - 下拉菜单示例: 现在你可以在 HTML 中使用 Alpine.js 的指令了。这里是一个简单的下拉菜单示例,替换掉之前的计数器,放在 src/pages/index.astro 中:

---
import Layout from '../layouts/Layout.astro';
---

<Layout title="Astro + Tailwind + daisyUI + Alpine.js">
  <main class="flex flex-col items-center justify-center min-h-screen p-4 bg-gray-50">
    <h1 class="text-4xl font-bold mb-8 text-gray-800">Alpine.js Dropdown Demo</h1>

    <div class="relative" x-data="{ isOpen: false }">
      <button
        @click="isOpen = !isOpen"
        @keydown.escape="isOpen = false"
        class="btn btn-info"
      >
        <span>选项</span>
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="w-5 h-5 ml-2 transition-transform duration-200" :class="{'rotate-180': isOpen}">
          <path fill-rule="evenodd" d="M5.23 7.21a.75.75 0 011.06.02L10 10.94l3.71-3.71a.75.75 0 111.06 1.06l-4.25 4.25a.75.75 0 01-1.06 0L5.23 8.27a.75.75 0 01.02-1.06z" clip-rule="evenodd" />
        </svg>
      </button>

      {/* Dropdown Panel */}
      <div
        x-show="isOpen"
        x-transition:enter="transition ease-out duration-100"
        x-transition:enter-start="opacity-0 scale-95"
        x-transition:enter-end="opacity-100 scale-100"
        x-transition:leave="transition ease-in duration-75"
        x-transition:leave-start="opacity-100 scale-100"
        x-transition:leave-end="opacity-0 scale-95"
        @click.outside="isOpen = false"
        class="absolute right-0 mt-2 w-48 bg-white rounded-md shadow-lg overflow-hidden z-10"
        style="display: none;" {/* Alpine.js 会控制显示 */}
      >
        <a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-blue-500 hover:text-white">个人资料</a>
        <a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-blue-500 hover:text-white">设置</a>
        <a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-blue-500 hover:text-white">退出登录</a>
      </div>
    </div>

    <p class="mt-8 text-sm text-gray-600">点击 "选项" 按钮来切换下拉菜单的显示。</p>

  </main>
</Layout>

代码解释:

  • x-data="{ isOpen: false }": 初始化组件的状态,isOpen 用于控制下拉菜单的显示和隐藏。

  • @click="isOpen = !isOpen": 点击按钮时,切换 isOpen 的值。

  • @keydown.escape="isOpen = false": 按下 Esc 键时,关闭下拉菜单。

  • :class="{'rotate-180': isOpen}": 根据 isOpen 的状态动态添加 CSS 类来旋转箭头图标。

  • x-show="isOpen": 根据 isOpen 的值来显示或隐藏下拉面板。

  • x-transition:...: 为下拉面板的显示和隐藏添加过渡动画效果。

  • @click.outside="isOpen = false": 当点击下拉菜单外部区域时,关闭下拉菜单。

  • style="display: none;": 初始隐藏下拉面板,Alpine.js 会通过 x-show 来控制其 display 属性。

重启开发服务器,你应该能看到这个 Alpine.js 下拉菜单正常工作,并且有平滑的过渡动画。