Open18

pnpmで複数のSlidevプロジェクトを管理する

mafuyumafuyu

まずは適当にプロジェクトのディレクトリを用意

mkdir talks
cd talks
git init
pnpm init
🖥️
package.json
{
  "name": "talks",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

mafuyumafuyu

slidesディレクトリ配下にプロジェクトを作成

mkdir slides
cd slides
pnpm create slidev@latest

ポイントはInstall and start it now?という質問にはnoで答えること(yesでも行けるかもだけど)
後でルートでpnpm iする

🖥️
$ pnpm create slidev@latest
  ●■▲
  Slidev Creator  v0.50.0-beta.7

✔ Project name: … example
  Scaffolding project in example ...
  Done.

✔ Install and start it now? … no

  start it later by:

  cd example
  pnpm install
  pnpm run dev

  ● ■ ▲
mafuyumafuyu

ルートに移動してpnpm-workspace.yamlを追加する

pnpm-workspace.yaml
packages:
  - "slides/*"
mafuyumafuyu

ルートに.gitignoreを追加

.gitignore
node_modules
dist
.wrangler
.DS_Store

ルートで以下のコマンドを叩けばnode_modulesなどが生成される

pnpm i

作成したslidevプロジェクトに移動してサーバーを起動できるか確認

cd slides/example
pnpm dev
📷

mafuyumafuyu

ルートのdistディレクトリに出力させたいのでスクリプトを修正する
ついでにexportslides配下に出力させる

slides/example/package.json
{
    ...
    "scripts": {
-      "build": "slidev build",
+      "build": "slidev build --base /example/ --out ../../dist/example",
        "dev": "slidev --open",
-      "export": "slidev export"
+      "export": "slidev export --output ../output/example.pdf",
+      "export:pptx": "slidev export --output ../output/example --format pptx"
    },
    ...
}

pptxのexportで空フォルダができちゃうけど何故か分かんない(聞いてる)
https://github.com/slidevjs/slidev/discussions/1960

mafuyumafuyu

ルートからビルドできるようにする

package.json
{
    ...
    "scripts": {
-      "test": "echo \"Error: no test specified\" && exit 1"
+      "build": "pnpm -r build"
    },
    ...
}
mafuyumafuyu

次にルートページを用意する
ルートに移動して以下のコマンドを実行

pnpm create vite@latest

Project name は home にした

🖥️
$ pnpm create vite@latest

✔ Project name: … home
✔ Select a framework: › React
✔ Select a variant: › TypeScript + SWC

Scaffolding project in /Users/namidapoo/Projects/slidev/talks/home...

Done. Now run:

  cd home
  pnpm install
  pnpm run dev
mafuyumafuyu

ルートのpnpm-workspace.yamlにhomeを追加する

pnpm-workspace.yaml
 packages:
+  - "home"
   - "slides/*"
mafuyumafuyu

ルートで依存関係をインストール

pnpm i

homeに移動して開発サーバーを起動できることを確認

cd home
pnpm dev
🖥️

mafuyumafuyu

ルートのdistディレクトリに出力させたいのでvite.config.tsを修正する

vite.config.ts
 import { defineConfig } from 'vite'
 import react from '@vitejs/plugin-react-swc'

 // https://vite.dev/config/
 export default defineConfig({
   plugins: [react()],
+  build: {
+    outDir: '../dist'
+  }
 })
mafuyumafuyu

Cloudflare Pagesにデプロイする
まずはルートにwranglerを入れる

pnpm add -D -w wrangler 

ルートのpackage.jsonにデプロイ用のスクリプトを追加する
※ 2回目以降はworkflowで動かすので基本使わないけど...

package.json
 {
     "scripts": {
         "build": "pnpm run -r build",
+        "deploy": "pnpm build && wrangler pages deploy dist"
     },
 }
🖥️
$ pnpm run deploy

> talks@1.0.0 deploy /Users/user/Projects/slidev/talks
> pnpm run build && wrangler pages deploy dist

> talks@1.0.0 build /Users/user/Projects/slidev/talks
> pnpm run -r build

Scope: 2 of 3 workspace projects
home build$ tsc -b && vite build
[2 lines collapsed]
│ Use --emptyOutDir to override.
│ transforming...
│ ✓ 34 modules transformed.
│ rendering chunks...
│ computing gzip size...
│ ../dist/index.html                   0.46 kB │ gzip:  0.30 kB
│ ../dist/assets/react-CHdo91hT.svg    4.13 kB │ gzip:  2.14 kB
│ ../dist/assets/index-n_ryQ3BS.css    1.39 kB │ gzip:  0.72 kB
│ ../dist/assets/index-Dxp5zAIY.js   143.20 kB │ gzip: 46.03 kB
│ ✓ built in 405ms
└─ Done in 1.8s
slides/example build$ slidev build --base /slide1/ --out ../../dist/example
[257 lines collapsed]../../dist/example/assets/index-D3raTp7X.js                                                          120.22 kB │ gzip:    41.95 kB
│ ../../dist/example/assets/architectureDiagram-HYWTPRMU-DKckFLo5.js                                   150.60 kB │ gzip:    42.49 kB
│ ../../dist/example/assets/modules/vue-B8yUepVU.js                                                    251.70 kB │ gzip:    94.36 kB
│ ../../dist/example/assets/katex-Y6PQNQVE-BQO_O8cr.js                                                 266.17 kB │ gzip:    78.89 kB
│ ../../dist/example/assets/gitGraph-YCYPL57B-5MQDGNWY-axwuLrqr.js                                     327.81 kB │ gzip:    87.08 kB
│ ../../dist/example/assets/chunk-OAVEIKCL-BEY0q78r.js                                                 400.35 kB │ gzip:   128.04 kB
│ ../../dist/example/assets/md-BZIAzsmn.js                                                             532.89 kB │ gzip:   154.98 kB
│ ../../dist/example/assets/modules/shiki-DZTIr5q0.js                                                1,376.57 kB │ gzip:   353.07 kB
│ ../../dist/example/assets/monaco/bundled-types-Cgi9cLU6.js                                         9,100.20 kB │ gzip: 2,181.52 kB
│ ✓ built in 27.51s
└─ Done in 32.2s
✔ No project specified. Would you like to create one or use an existing project? › Create a new project
✔ Enter the name of your new project: … my-talks
✔ Enter the production branch name: … main
✨ Successfully created the 'my-talks' project.
▲ [WARNING] Warning: Your working directory is a git repo and has uncommitted changes

  To silence this warning, pass in --commit-dirty=true


✨ Success! Uploaded 257 files (4.13 sec)

🌎 Deploying...
✨ Deployment complete! Take a peek over at https://xxx.my-talks.pages.dev
mafuyumafuyu

これでデプロイすれば以下のように見れる
あとはルートページにスライドへのリンクを置けばいい

mafuyumafuyu

ワークフロー書いてみた

.github/workflows/deploy.yml
name: Deploy to Cloudflare Pages

on:
  push:
    branches:
      - "*"

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup pnpm
        uses: pnpm/action-setup@v4.0.0
        with:
          version: latest

      - name: Install dependencies
        run: pnpm i

      - name: Build the project
        run: pnpm run build

      - name: Deploy to Cloudflare Pages
        uses: cloudflare/wrangler-action@v3.12.1
        with:
          apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
          accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
          command: pages deploy ./dist --project-name=${{ secrets.CLOUDFLARE_PROJECT_NAME }}

mafuyumafuyu

secretの登録

gh secret set CLOUDFLARE_PROJECT_NAME -b xxxxxx
gh secret set CLOUDFLARE_API_TOKEN -b xxxxxxxxxxxxxxxxxx
gh secret set CLOUDFLARE_ACCOUNT_ID -b xxxxxxxxxxxx