npmに公開してunpkg.comでCDN配信する手順を実例付きで徹底解説。

  • ✅ Webフォントをnpmに公開する詳細な手順
  • ✅ unpkg.com経由でCDN配信する方法
  • ✅ 実際に失敗したケースとその解決策
  • ✅ パッケージサイズの制限と分割方法
  • ✅ size-adjustプロパティの実装方法
  • ✅ Material Symbolsのコードポイント対応
  • ✅ セキュリティ対策(.gitignore / .npmignore)

Webフォントをnpmにアップロードして、176MBの失敗から学んだパッケージ分割のコツ、size-adjust対応、Material Symbolsのコードポイント実装まで。初心者でもわかるように詳細に解説します。

    1. なぜWebフォントをCDN化するのか

    従来の方法の問題点

    WordPressテーマに毎回フォントを同梱:

    テーマA/fonts/ ← 20MB
    テーマB/fonts/ ← 20MB
    テーマC/fonts/ ← 20MB
    
    合計60MB、管理が煩雑...
    

    unpkg.com経由のメリット

    @sarap422/font-shippori-mincho-otf@1.0.0
    ↓
    unpkg.com で自動CDN配信
    ↓
    全テーマで共通利用
    

    メリット:

    • ✅ テーマファイルの軽量化
    • ✅ 更新が一元管理できる
    • ✅ バージョン指定で確実に動作
    • ✅ Cloudflareの高速CDN
    • ✅ キャッシュ効率が高い

    2. 事前準備:必要なツールとアカウント

    2-1. Node.jsとnpmのインストール

    # インストール確認
    node -v   # v18.0.0 以上推奨
    npm -v    # v9.0.0 以上推奨
    

    Node.js公式サイトからダウンロード・インストール。

    2-2. npmアカウントの作成

    1. npmjs.com にアクセス
    2. 「Sign Up」からアカウント作成
    3. メール認証を完了

    2-3. フォントファイルの準備

    必要なファイル形式:

    fonts/
    ├── *.woff2   ← 最優先(モダンブラウザ)
    ├── *.woff    ← 補助的に
    └── *.ttf     ← 不要(サイズ大)
    

    推奨:woff2のみに絞る

    • ブラウザサポート率:96%以上
    • ファイルサイズ:ttfの約50%
    • 読み込み速度:最速

    3. 実践:Webフォントのnpm公開手順

    3-1. プロジェクト構造の準備

    # ディレクトリ作成
    mkdir font-shippori-mincho-otf
    cd font-shippori-mincho-otf
    

    推奨ディレクトリ構造:

    font-shippori-mincho-otf/
    ├── package.json
    ├── README.md
    ├── README.original.txt           # 元フォントのREADME
    ├── OFL.txt                       # ライセンスファイル
    ├── font-face.css                 # オリジナル版
    ├── font-face.adjusted.css        # size-adjust版
    ├── ShipporiMincho-OTF-Regular.woff
    ├── ShipporiMincho-OTF-Regular.woff2
    ├── ShipporiMincho-OTF-Bold.woff
    ├── ShipporiMincho-OTF-Bold.woff2
    └── ... (他のウェイト)
    

    3-2. package.jsonの作成

    npm init -y
    

    生成された package.json を編集:

    {
      "name": "@sarap422/font-shippori-mincho-otf",
      "version": "1.0.0",
      "description": "Shippori Mincho OTF webfont with size-adjust support for optimal typography balance",
      "main": "font-face.adjusted.css",
      "repository": {
        "type": "git",
        "url": "https://github.com/sarap422/font-shippori-mincho-otf.git"
      },
      "files": [
        "*.woff",
        "*.woff2",
        "font-face.css",
        "font-face.adjusted.css",
        "README.md",
        "README.original.txt",
        "OFL.txt"
      ],
      "keywords": [
        "font",
        "webfont",
        "shippori-mincho",
        "size-adjust",
        "woff",
        "woff2"
      ],
      "author": "sarap422",
      "license": "OFL-1.1"
    }
    

    重要なポイント:

    ① name(パッケージ名)

    "name": "@sarap422/font-shippori-mincho-otf"
    
    • @ユーザー名/パッケージ名 の形式(スコープ付き)
    • 注意: sarap422/fonts のようなスラッシュはNG
    • ハイフン - で単語を区切る

    ② main(エントリーポイント)

    "main": "font-face.adjusted.css"
    
    • size-adjustがメイン用途なら .adjusted.css を指定
    • オリジナル版メインなら .css を指定

    ③ files(公開ファイル)

    "files": [
      "*.woff",
      "*.woff2",
      "font-face.css",
      "font-face.adjusted.css"
    ]
    
    • ワイルドカード * が使用可能
    • ホワイトリスト方式:指定したファイルのみ公開
    • 指定しないファイルは npm publish で除外される

    ④ license(ライセンス)

    "license": "OFL-1.1"
    
    • フォントごとに正しいライセンスを記載
    • よくあるライセンス:
      • OFL-1.1 - SIL Open Font License
      • MIT - MIT License
      • Apache-2.0 - Apache License 2.0
      • CC0-1.0 - CC0(パブリックドメイン)

    3-3. CSSファイルの作成

    font-face.css(オリジナル版):

    @font-face {
      font-family: 'Shippori Mincho OTF';
      src: url('ShipporiMincho-OTF-Regular.woff2') format('woff2'),
           url('ShipporiMincho-OTF-Regular.woff') format('woff');
      font-weight: 400;
      font-style: normal;
      font-display: swap;
    }
    
    @font-face {
      font-family: 'Shippori Mincho OTF';
      src: url('ShipporiMincho-OTF-Bold.woff2') format('woff2'),
           url('ShipporiMincho-OTF-Bold.woff') format('woff');
      font-weight: 700;
      font-style: normal;
      font-display: swap;
    }
    

    font-face.adjusted.css(size-adjust版):

    @font-face {
      font-family: 'Shippori Mincho OTF';
      src: url('ShipporiMincho-OTF-Regular.woff2') format('woff2'),
           url('ShipporiMincho-OTF-Regular.woff') format('woff');
      font-weight: 400;
      font-style: normal;
      font-display: swap;
      size-adjust: 106%;  /* ← 英語フォントとのバランス調整 */
    }
    
    @font-face {
      font-family: 'Shippori Mincho OTF';
      src: url('ShipporiMincho-OTF-Bold.woff2') format('woff2'),
           url('ShipporiMincho-OTF-Bold.woff') format('woff');
      font-weight: 700;
      font-style: normal;
      font-display: swap;
      size-adjust: 106%;
    }
    

    3-4. README.mdの作成

    # @sarap422/font-shippori-mincho-otf
    
    Shippori Mincho OTF webfont with size-adjust support.
    
    ## Installation
    
    ``html
    <link href="https://unpkg.com/@sarap422/font-shippori-mincho-otf@1.0.0/font-face.adjusted.css" rel="stylesheet">
    ``
    
    ## Usage
    
    ``css
    body {
      font-family: 'Shippori Mincho OTF', serif;
    }
    ``
    
    ## License
    
    SIL Open Font License 1.1 (see OFL.txt)
    

    3-5. セキュリティファイルの作成

    .gitignore:

    node_modules/
    *.log
    .DS_Store
    .env
    *.pem
    *.key
    

    .npmignore:

    .git/
    .github/
    .gitignore
    .DS_Store
    *.log
    .env
    *.pem
    *.key
    *.cert
    .vscode/
    .idea/
    node_modules/
    test/
    tests/
    __tests__/
    coverage/
    .nyc_output/
    *.md~
    *.bak
    *.tmp
    .eslintrc*
    .prettierrc*
    tsconfig.json
    

    4. 失敗例1:176MBの巨大パッケージ問題

    最初のアプローチ(失敗)

    すべてのフォントを1つのパッケージにまとめてしまいました。

    @sarap422/fonts@1.0.0
    ├── size-adjust/
    │   ├── ShipporiMinchoOTF/
    │   ├── NotoSansJP/
    │   ├── OverusedGrotesk/
    │   └── ...
    ├── original/
    │   └── ...
    └── icons/
        ├── MaterialDesignIcons/  ← 30MB
        └── SimpleIcons/          ← 15MB
    
    合計: 176.7 MB
    

    実際のエラー

    npm publish --access public
    

    結果:

    npm notice Tarball Details
    npm notice package size: 176.7 MB
    npm notice unpacked size: 176.8 MB
    + @sarap422/fonts@1.0.0
    

    一応公開できましたが、重大な問題がありました。

    問題点

    1. 無駄なダウンロード

      <!-- ShipporiMinchoだけ使いたい -->
      <link href="https://unpkg.com/@sarap422/fonts@1.0.0/size-adjust/ShipporiMinchoOTF/font-face.css">
      
      <!-- でも176.7MB全体が対象に... -->
      
    2. npmの制限

      • 推奨: 10MB以下
      • 上限: 50MB程度(非公式)
      • 176MBは明らかに大きすぎる
    3. ユーザー体験の悪化

      • 読み込みが遅い
      • 帯域幅の無駄
    4. バージョン管理の複雑化

      • 1フォントだけ更新したくても全体を更新

    非推奨化の処理

    npm deprecate @sarap422/fonts@1.0.0 "Use individual font packages instead"
    
    @user fonts % npm deprecate @sarap422/fonts@1.0.0 "Use individual font packages instead"
    npm notice deprecating @sarap422/fonts@1.0.0 with message "Use individual font packages instead"
    

    5. 解決策:フォントごとに個別パッケージ化

    正しいアプローチ

    各フォントを独立したパッケージに:

    @sarap422/font-shippori-mincho-otf    ← 20.8 MB
    @sarap422/font-noto-sans-jp           ← 15 MB
    @sarap422/font-overused-grotesk       ← 0.2 MB
    @sarap422/font-material-symbols       ← 0.6 MB
    @sarap422/font-simple-icons           ← 26.7 MB
    

    メリット

    1. 必要なフォントだけダウンロード

      <link href="https://unpkg.com/@sarap422/font-shippori-mincho-otf@1.0.0/font-face.css">
      

      → 20.8MBのみダウンロード

    2. npmの制限内に収まる

      • 各パッケージが10-30MB
      • 問題なく公開できる
    3. バージョン管理が容易

      ShipporiMinchoのsize-adjustだけ変更
      → @sarap422/font-shippori-mincho-otf@1.0.1
      → 他のフォントは影響を受けない
      
    4. ユーザーフレンドリー

      # 必要なパッケージだけインストール
      npm install @sarap422/font-shippori-mincho-otf
      

    6. 失敗例2:命名規則の間違い

    よくある命名ミス

    ❌ ケース1: スラッシュの誤用

    {
      "name": "sarap422/fonts"
    }
    

    エラー:

    npm ERR! Invalid package name
    

    理由: スラッシュ / はスコープ専用。@ なしでは使えない。

    ❌ ケース2: スコープ内のハイフン

    {
      "name": "@sarap422-fonts/shippori-mincho"
    }
    

    エラー:

    npm ERR! Invalid scope name
    

    理由: スコープ名にハイフンは使えない。

    ❌ ケース3: 大文字の使用

    {
      "name": "@sarap422/Font-Shippori-Mincho"
    }
    

    警告:

    npm WARN name can no longer contain capital letters
    

    理由: パッケージ名はすべて小文字が推奨。

    正しい命名規則

    {
      "name": "@sarap422/font-shippori-mincho-otf"
    }
    

    ルール:

    • @ユーザー名/パッケージ名 の形式
    • すべて小文字
    • 単語区切りはハイフン -
    • スコープ名(@sarap422)にハイフンは使えない

    その他の有効な例:

    "@sarap422/font-overused-grotesk"
    "@sarap422/font-material-symbols"
    "@sarap422/font-simple-icons"
    

    7. 成功事例:実際に公開した3つのパッケージ

    📍 公開の実行

    cd font-shippori-mincho-otf
    
    npm login                    # ログイン
    npm pack --dry-run           # 事前確認
    npm publish --access public  # 公開の実行
    

    ケース1: @sarap422/font-shippori-mincho-otf

    公開ログ:

    📦  @sarap422/font-shippori-mincho-otf@1.0.0
    Tarball Contents
    4.4kB   OFL.txt
    1.8kB   README.md
    4.1kB   README.original.txt
    2.4MB   ShipporiMincho-OTF-Bold.woff
    1.8MB   ShipporiMincho-OTF-Bold.woff2
    2.4MB   ShipporiMincho-OTF-ExtraBold.woff
    1.8MB   ShipporiMincho-OTF-ExtraBold.woff2
    2.4MB   ShipporiMincho-OTF-Medium.woff
    1.8MB   ShipporiMincho-OTF-Medium.woff2
    2.3MB   ShipporiMincho-OTF-Regular.woff
    1.7MB   ShipporiMincho-OTF-Regular.woff2
    2.4MB   ShipporiMincho-OTF-SemiBold.woff
    1.8MB   ShipporiMincho-OTF-SemiBold.woff2
    1.3kB   font-face.adjusted.css
    1.1kB   font-face.css
    611B    package.json
    
    package size:   20.8 MB
    unpacked size:  20.8 MB
    total files:    16
    
    + @sarap422/font-shippori-mincho-otf@1.0.0
    

    使用方法:

    <link href="https://unpkg.com/@sarap422/font-shippori-mincho-otf@1.0.0/font-face.adjusted.css" rel="stylesheet">
    

    ケース2: @sarap422/font-material-symbols

    公開ログ:

    📦  @sarap422/font-material-symbols@1.0.0
    Tarball Contents
    11.4kB  LICENSE
    149.5kB MaterialIcons-Regular.codepoints.txt
    2.4kB   README.md
    7.6kB   README.original.md
    219.7kB material-symbols.css
    209.2kB material-symbols.min.css
    591B    package.json
    
    package size:   95.1 kB
    unpacked size:  600.4 kB
    total files:    7
    
    + @sarap422/font-material-symbols@1.0.0
    

    特徴:

    • Font Awesomeスタイルの記法
    • コードポイント方式でFOUC対策
    • 600KBと軽量

    使用方法:

    <!-- Google Fontsから本体を読み込み -->
    <link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Sharp:wght,FILL@100..700,0..1" rel="stylesheet">
    
    <!-- このパッケージのCSSを読み込み -->
    <link href="https://unpkg.com/@sarap422/font-material-symbols@1.0.0/material-symbols.min.css" rel="stylesheet">
    
    <!-- Font Awesomeスタイルで使用 -->
    <i class="mas ma-home"></i>
    <i class="mas ma-search"></i>
    

    ケース3: @sarap422/font-simple-icons

    公開ログ:

    📦  @sarap422/font-simple-icons@1.0.0
    Tarball Contents
    6.5kB   LICENSE.md
    1.7kB   README.md
    184.7kB SimpleIcons.codepoints.txt
    575.1kB dist/simple-icons.json
    485.1kB dist/simple-icons.min.json
    1.5MB   dist/SimpleIcons-Fit.eot
    1.5MB   dist/SimpleIcons-Fit.otf
    7.3MB   dist/SimpleIcons-Fit.svg
    1.5MB   dist/SimpleIcons-Fit.ttf
    1.0MB   dist/SimpleIcons-Fit.woff
    876.8kB dist/SimpleIcons-Fit.woff2
    1.4MB   dist/SimpleIcons.eot
    1.4MB   dist/SimpleIcons.otf
    5.1MB   dist/SimpleIcons.svg
    1.4MB   dist/SimpleIcons.ttf
    959.1kB dist/SimpleIcons.woff
    802.8kB dist/SimpleIcons.woff2
    556B    package.json
    316.9kB simple-icons.css
    274.9kB simple-icons.min.css
    
    package size:   15.0 MB
    unpacked size:  26.7 MB
    total files:    20
    
    + @sarap422/font-simple-icons@1.0.0
    

    注意点:

    • SVGファイルが大きい(7.3MB + 5.1MB)
    • 将来的にはwoff2のみに絞ることを検討

    8. 応用:size-adjust対応フォントの作り方

    size-adjustとは?

    英語フォントと日本語フォントは、同じ font-size でも見た目のサイズが異なります。

    問題の例:

    body {
      font-family: 'Overused Grotesk', 'Noto Sans JP', sans-serif;
      font-size: 16px;
    }
    
    Overused Grotesk: 16px → 視覚的に15px(小さく見える)
    Noto Sans JP:     16px → 視覚的に16px
    

    size-adjustによる解決

    @font-face {
      font-family: 'Overused Grotesk';
      src: url('OverusedGrotesk-VF.woff2') format('woff2');
      size-adjust: 106%;  /* 6%拡大 */
    }
    

    結果:

    Overused Grotesk: 16px × 106% = 視覚的に16.96px
    → Noto Sans JPと同じ見た目のサイズに
    

    実装方法

    ステップ1: 調整値の決定

    <!DOCTYPE html>
    <html>
    <head>
    <style>
    @font-face {
      font-family: 'Test Font';
      src: url('font.woff2') format('woff2');
      size-adjust: 100%;  /* ← ここを調整 */
    }
    
    .english { font-family: 'Arial', sans-serif; }
    .japanese { font-family: 'Test Font', sans-serif; }
    </style>
    </head>
    <body>
    <p class="english">The quick brown fox jumps</p>
    <p class="japanese">あのイーハトーヴォの</p>
    </body>
    </html>
    

    size-adjust を 100%, 105%, 106%, 110%... と変更して、
    見た目が揃う値を見つけます。

    ステップ2: 2つのCSSファイルを作成

    font-face.css(オリジナル):

    @font-face {
      font-family: 'Overused Grotesk';
      src: url('OverusedGrotesk-VF.woff2') format('woff2');
      size-adjust: 100%;  /* または記載しない */
    }
    

    font-face.adjusted.css(調整版):

    @font-face {
      font-family: 'Overused Grotesk';
      src: url('OverusedGrotesk-VF.woff2') format('woff2');
      size-adjust: 106%;  /* ← 調整値 */
    }
    

    ステップ3: package.jsonで両方を公開

    {
      "name": "@sarap422/font-overused-grotesk",
      "main": "font-face.adjusted.css",
      "files": [
        "font-face.css",
        "font-face.adjusted.css",
        "*.woff2"
      ]
    }
    

    ステップ4: 用途に応じて使い分け

    <!-- オリジナル版 -->
    <link href="https://unpkg.com/@sarap422/font-overused-grotesk@1.0.0/font-face.css" rel="stylesheet">
    
    <!-- 調整版 -->
    <link href="https://unpkg.com/@sarap422/font-overused-grotesk@1.0.0/font-face.adjusted.css" rel="stylesheet">
    

    9. 応用:Material SymbolsのFont Awesomeスタイル実装

    Google公式の問題点

    Google公式の使い方:

    <span class="material-symbols-sharp">home</span>
    

    問題: FOUC(Flash of Unstyled Content)

    フォント読み込み前: "home" というテキストが一瞬表示される ❌
    フォント読み込み後: 🏠 アイコンが表示される ✅
    

    Font Awesomeスタイルによる解決

    コードポイント方式:

    <i class="mas ma-home"></i>
    
    .mas.ma-home::before {
      content: "\e88a";  /* ← Unicodeコードポイント */
      font-family: 'Material Symbols Sharp';
    }
    

    メリット:

    フォント読み込み前: 何も表示されない(または□) ✅
    フォント読み込み後: 🏠 アイコンが表示される ✅
    

    実装手順

    ステップ1: コードポイント一覧の取得

    Material Design icons(github)から、または:

    # codepoints.txtをダウンロード
    curl -O https://github.com/google/material-design-icons/tree/master/font/MaterialIcons-Regular.codepoints
    

    ファイル内容:

    home e88a
    search e8b6
    settings e8b8
    favorite e87d
    chevron_right e5cc
    ...
    

    ステップ2: CSSの自動生成

    # Python スクリプト例
    cat MaterialIcons-Regular.codepoints | awk '{
      printf ".mas.ma-%s::before {content: \"\\%s\"}\n", $1, $2
    }' > material-symbols.css
    

    生成されるCSS:

    .mas.ma-home::before {content: "\e88a"}
    .mas.ma-search::before {content: "\e8b6"}
    .mas.ma-settings::before {content: "\e8b8"}
    .mas.ma-favorite::before {content: "\e87d"}
    .mas.ma-chevron_right::before {content: "\e5cc"}
    

    ステップ3: ベースCSSの追加

    [class*="ma-"]:is(.mao, .mar, .mas) {
      font-weight: normal;
      font-style: normal;
      letter-spacing: normal;
      text-transform: none;
      white-space: nowrap;
      word-wrap: normal;
      direction: ltr;
      -webkit-font-feature-settings: 'liga';
      -webkit-font-smoothing: antialiased;
      display: inline-flex;
      vertical-align: middle;
      place-content: center;
      place-items: center;
      line-height: 1;
      font-size: 133.3%;
    }
    
    .mas { font-family: 'Material Symbols Sharp'; }
    .mao { font-family: 'Material Symbols Outlined'; }
    .mar { font-family: 'Material Symbols Rounded'; }
    
    .mas.is-filled::before,
    .mao.is-filled::before,
    .mar.is-filled::before {
      font-variation-settings: 'FILL' 1, 'wght' 300;
    }
    

    ステップ4: ミニファイ版の作成

    # CSS圧縮
    npx cleancss -o material-symbols.min.css material-symbols.css
    

    ステップ5: package.jsonの設定

    {
      "name": "@sarap422/font-material-symbols",
      "version": "1.0.0",
      "description": "Material Symbols with Font Awesome-style syntax",
      "main": "material-symbols.min.css",
      "files": [
        "material-symbols.css",
        "material-symbols.min.css",
        "MaterialIcons.codepoints.txt",
        "README.md",
        "LICENSE"
      ],
      "keywords": [
        "material-symbols",
        "icons",
        "font-awesome-style",
        "google-icons"
      ],
      "license": "Apache-2.0"
    }
    

    10. セキュリティ対策:.gitignoreと.npmignore

    なぜ両方必要か?

    • .gitignore: Gitリポジトリから除外
    • .npmignore: npm公開から除外

    .gitignore(Git用)

    # Node.js
    node_modules/
    npm-debug.log*
    yarn-debug.log*
    yarn-error.log*
    
    # OS
    .DS_Store
    Thumbs.db
    Desktop.ini
    
    # IDE
    .vscode/
    .idea/
    *.swp
    *.swo
    *~
    
    # 環境変数
    .env
    .env.local
    .env.*.local
    
    # 認証情報(絶対に公開しない)
    *.pem
    *.key
    *.cert
    *.crt
    *.p12
    *.pfx
    .npmrc
    
    # ビルド成果物
    dist/
    build/
    *.tgz
    
    # テスト
    coverage/
    .nyc_output/
    
    # ログ
    *.log
    logs/
    
    # 一時ファイル
    *.tmp
    *.bak
    *.swp
    *~
    

    .npmignore(npm公開用)

    # Git関連
    .git/
    .github/
    .gitignore
    .gitattributes
    
    # 開発ファイル
    .eslintrc*
    .prettierrc*
    .editorconfig
    tsconfig.json
    rollup.config.js
    webpack.config.js
    vite.config.js
    
    # テスト
    test/
    tests/
    __tests__/
    *.test.js
    *.spec.js
    coverage/
    .nyc_output/
    
    # ドキュメント(開発用)
    docs/
    examples/
    .github/
    
    # IDE
    .vscode/
    .idea/
    *.sublime-*
    
    # OS
    .DS_Store
    Thumbs.db
    
    # ログ
    *.log
    
    # 認証情報
    .env
    *.pem
    *.key
    
    # その他
    *.md~
    *.bak
    *.tmp
    node_modules/
    

    package.jsonの"files"フィールドとの関係

    優先順位:

    1. package.json の "files" フィールド(ホワイトリスト)
    2. .npmignore(ブラックリスト)
    3. .gitignore(npmignoreがない場合のみ)
    

    推奨:filesフィールドでホワイトリスト管理

    {
      "files": [
        "*.woff2",
        "*.woff",
        "font-face.css",
        "font-face.adjusted.css",
        "README.md",
        "LICENSE"
      ]
    }
    

    これで、指定したファイル以外は自動的に除外されます。

    公開前の確認

    # 実際に公開されるファイルを確認
    npm pack --dry-run
    

    チェック項目:

    • ✅ 必要なフォントファイルが含まれているか
    • ✅ CSSファイルが含まれているか
    • ✅ README.mdとLICENSEが含まれているか
    • ❌ .envファイルが含まれていないか
    • ❌ 秘密鍵(.pem, .key)が含まれていないか
    • ❌ node_modules/が含まれていないか

    11. 公開後の確認とメンテナンス

    11-1. 公開直後の確認

    npmでの確認

    https://www.npmjs.com/package/@sarap422/font-shippori-mincho-otf
    

    確認項目:

    • ✅ パッケージ名、バージョンが正しいか
    • ✅ README.mdが表示されているか
    • ✅ ライセンスが正しいか
    • ✅ Keywords(キーワード)が適切か

    unpkg.comでの確認

    ディレクトリ一覧:

    https://unpkg.com/@sarap422/font-shippori-mincho-otf@1.0.0/
    

    個別ファイル:

    https://unpkg.com/@sarap422/font-shippori-mincho-otf@1.0.0/font-face.css
    https://unpkg.com/@sarap422/font-shippori-mincho-otf@1.0.0/ShipporiMincho-OTF-Regular.woff2
    

    確認項目:

    • ✅ CSSファイルが表示されるか
    • ✅ フォントファイルがダウンロードできるか
    • ✅ URLが意図通りか

    実際にHTMLで動作確認

    <!DOCTYPE html>
    <html lang="ja">
    <head>
      <meta charset="UTF-8">
      <link href="https://unpkg.com/@sarap422/font-shippori-mincho-otf@1.0.0/font-face.adjusted.css" rel="stylesheet">
      <style>
        body {
          font-family: 'Shippori Mincho OTF', serif;
          font-size: 16px;
          line-height: 1.66;
        }
      </style>
    </head>
    <body>
      <h1>見出しテスト</h1>
      <p>本文のテストです。あのイーハトーヴォのすきとおった風、夏でも底に冷たさをもつ青いそら。</p>
    </body>
    </html>
    

    確認項目:

    • ✅ フォントが正しく読み込まれるか
    • ✅ DevToolsのNetworkタブでエラーがないか
    • ✅ 表示が意図通りか

    11-2. バージョンアップの手順

    パッチバージョン(バグ修正): 1.0.0 → 1.0.1

    # CSSの軽微な修正など
    npm version patch
    npm publish
    

    マイナーバージョン(機能追加): 1.0.0 → 1.1.0

    # 新しいウェイトの追加など
    npm version minor
    npm publish
    

    メジャーバージョン(破壊的変更): 1.0.0 → 2.0.0

    # ファイル構造の大幅変更など
    npm version major
    npm publish
    

    11-3. 非推奨化・削除

    特定バージョンを非推奨に:

    npm deprecate @sarap422/font-name@1.0.0 "Please upgrade to 2.0.0"
    

    パッケージ全体を非推奨に:

    npm deprecate @sarap422/font-name "This package is no longer maintained"
    

    パッケージを削除(72時間以内のみ):

    npm unpublish @sarap422/font-name@1.0.0
    

    12. よくあるエラーと解決方法

    エラー1: E403 Forbidden

    npm ERR! code E403
    npm ERR! 403 Forbidden - PUT https://registry.npmjs.org/@sarap422/font-name
    

    原因:

    • npmにログインしていない
    • スコープ付きパッケージを公開する権限がない

    解決策:

    # 再ログイン
    npm logout
    npm login
    
    # スコープ付きパッケージは --access public が必要
    npm publish --access public
    

    エラー2: E413 Payload Too Large

    npm ERR! code E413
    npm ERR! 413 Payload Too Large
    

    原因:

    • パッケージサイズが大きすぎる(通常50MB超)

    解決策:

    方法1: 不要なファイルを除外

    {
      "files": [
        "*.woff2",  // woff2のみに絞る
        "*.css"
      ]
    }
    

    方法2: .npmignoreで除外

    *.ttf
    *.eot
    *.svg
    docs/
    examples/
    

    方法3: パッケージを分割

    大きいパッケージ
    ↓
    複数の小さいパッケージに分割
    

    エラー3: Invalid package name

    npm ERR! Invalid package name "Sarap422/Font-Name"
    

    原因:

    • パッケージ名に大文字を使用
    • スラッシュの誤用

    解決策:

    // ❌ NG
    "name": "Sarap422/Font-Name"
    "name": "sarap422/font-name"
    
    // ✅ OK
    "name": "@sarap422/font-name"
    "name": "sarap422-font-name"
    

    エラー4: バージョン重複エラー

    npm ERR! You cannot publish over the previously published versions
    

    原因:

    • 同じバージョン番号で再公開しようとした

    解決策:

    # package.jsonのversionを変更
    npm version patch  # 1.0.0 → 1.0.1
    npm publish
    

    エラー5: Repository URL Warning

    npm warn publish npm auto-corrected some errors in your package.json
    npm warn publish "repository.url" was normalized
    

    原因:

    • repository.urlの形式が不完全

    修正前:

    {
      "repository": {
        "url": "https://github.com/user/repo.git"
      }
    }
    

    修正後:

    {
      "repository": {
        "type": "git",
        "url": "git+https://github.com/user/repo.git"
      }
    }
    

    または:

    npm pkg fix
    

    エラー6: unpkg.comでファイルが見つからない

    https://unpkg.com/@sarap422/font-name@1.0.0/font.woff2
    → 404 Not Found
    

    原因:

    • package.jsonの"files"にファイルが含まれていない
    • .npmignoreで除外されている

    確認方法:

    npm pack --dry-run
    

    解決策:

    {
      "files": [
        "*.woff2",  // ← ワイルドカード追加
        "font-face.css"
      ]
    }
    

    エラー7: CSSでフォントが読み込めない

    ブラウザコンソール:

    Failed to load resource: net::ERR_FAILED
    

    原因:

    • CSSのURLパスが間違っている

    間違った例:

    @font-face {
      src: url('/fonts/font.woff2');  /* ← 絶対パス */
    }
    

    正しい例:

    @font-face {
      src: url('font.woff2');  /* ← 相対パス */
    }
    

    unpkg.comでは、CSSと同じディレクトリにフォントファイルがあるため、
    相対パスで指定します。


    まとめ:

    基本:

    • Webフォントをnpmに公開する手順
    • unpkg.com経由でCDN配信する方法

    失敗から学んだこと:

    • 176MBの巨大パッケージ問題 → フォントごとに分割
    • 命名規則の間違い → @user/package-name の形式

    応用:

    • size-adjust対応フォントの作り方
    • Material SymbolsのFont Awesomeスタイル実装
    • コードポイント方式でFOUC対策

    セキュリティ:

    • .gitignore / .npmignore の使い分け
    • filesフィールドでホワイトリスト管理

    成功のポイント

    1. パッケージは小さく保つ

      • 10-30MB以下が理想
      • フォントごとに分割
    2. 命名規則を守る

      • @ユーザー名/パッケージ名
      • すべて小文字、ハイフン区切り
    3. 公開前に必ず確認

      npm pack --dry-run
      
    4. バージョンは必ず固定

      <link href="https://unpkg.com/@user/font@1.0.0/font.css">
      
    5. セキュリティファイルは必須

      • .gitignore
      • .npmignore
      • package.jsonの"files"

    次のステップ

    1. 自分のフォントを公開してみる

      • 小さいフォントから試してみる
      • size-adjustの調整を試す
    2. バージョン管理を理解する

      • Semantic Versioning
      • 破壊的変更の扱い
    3. モニタリング

      • npmのダウンロード数を確認
      • unpkg.comでの利用状況を把握

    参考リンク


    この記事の実例パッケージ

    実際に公開したパッケージ:

    1. @sarap422/font-shippori-mincho-otf
    2. @sarap422/font-material-symbols
    3. @sarap422/font-simple-icons

    ぜひ参考にしてみてください!