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アカウントの作成
- npmjs.com にアクセス
- 「Sign Up」からアカウント作成
- メール認証を完了
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 LicenseMIT
- MIT LicenseApache-2.0
- Apache License 2.0CC0-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
一応公開できましたが、重大な問題がありました。
問題点
-
無駄なダウンロード
<!-- ShipporiMinchoだけ使いたい --> <link href="https://unpkg.com/@sarap422/fonts@1.0.0/size-adjust/ShipporiMinchoOTF/font-face.css"> <!-- でも176.7MB全体が対象に... -->
-
npmの制限
- 推奨: 10MB以下
- 上限: 50MB程度(非公式)
- 176MBは明らかに大きすぎる
-
ユーザー体験の悪化
- 読み込みが遅い
- 帯域幅の無駄
-
バージョン管理の複雑化
- 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
メリット
-
必要なフォントだけダウンロード
<link href="https://unpkg.com/@sarap422/font-shippori-mincho-otf@1.0.0/font-face.css">
→ 20.8MBのみダウンロード
-
npmの制限内に収まる
- 各パッケージが10-30MB
- 問題なく公開できる
-
バージョン管理が容易
ShipporiMinchoのsize-adjustだけ変更 → @sarap422/font-shippori-mincho-otf@1.0.1 → 他のフォントは影響を受けない
-
ユーザーフレンドリー
# 必要なパッケージだけインストール 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フィールドでホワイトリスト管理
成功のポイント
-
パッケージは小さく保つ
- 10-30MB以下が理想
- フォントごとに分割
-
命名規則を守る
@ユーザー名/パッケージ名
- すべて小文字、ハイフン区切り
-
公開前に必ず確認
npm pack --dry-run
-
バージョンは必ず固定
<link href="https://unpkg.com/@user/font@1.0.0/font.css">
-
セキュリティファイルは必須
- .gitignore
- .npmignore
- package.jsonの"files"
次のステップ
-
自分のフォントを公開してみる
- 小さいフォントから試してみる
- size-adjustの調整を試す
-
バージョン管理を理解する
- Semantic Versioning
- 破壊的変更の扱い
-
モニタリング
- npmのダウンロード数を確認
- unpkg.comでの利用状況を把握
参考リンク
この記事の実例パッケージ
実際に公開したパッケージ:
ぜひ参考にしてみてください!