- 投稿日:2019-02-09T23:14:36+09:00
nodeでcliツールを作る
ターミナルで
my-cli --env=productionみたいな感じで起動できる対話型のcliツールを作るやり方です。
対話型cli
enquirerというnpmを使えば対話型のcliツールは簡単に作れます。
標準入力からもらう引数
標準入力から引数をもらうにはyargsというnpmを使えば簡単にできます。
独自コマンド
node index.jsみたいに起動させるのではなく、my-cliのような独自コマンドでプログラムを動かすにはpackage.jsonのbinを使います。
package.jsonに以下のように書いて"bin": { "my-cli": "./index.js" }index.jsの先頭に
#!/usr/bin/env nodeを書いて、
npm install -gを実行します。
これでターミナルでmy-cliと実行することで./index.jsが動くようになります。
- 投稿日:2019-02-09T22:16:23+09:00
Lineで匿名チャットルームを作ってみた
開発のきっかけ
お腹が痛い時にどことない孤独を感じるのでどうにかしたい
↓
その時の気持ちを共有できる匿名チャットルームがあれば良いのでは?
↓
作るか概要
匿名で会話が出来るLineBotを作っていきます。
なぜLineBotかと言うと、Lineの仕様上匿名のグループチャットは作れない為です。使用技術
Node.js
Heroku公式リファレンス
https://developers.line.biz/ja/reference/messaging-api/#common-properties事前準備
すでにLineBotでメッセージの送受信ができている前提で話を進めさせていただきます。
こちらの記事を参考にしてとりあえず動くと状態まで開発を進めておいてください。
https://qiita.com/nkjm/items/38808bbc97d6927837cd
コードの編集
今回主に編集するファイルはindex.jsです。
紹介した記事の通りに作成すると、このようになっているかと思います。index.js// ----------------------------------------------------------------------------- // モジュールのインポート const server = require("express")(); const line = require("@line/bot-sdk"); // Messaging APIのSDKをインポート // ----------------------------------------------------------------------------- // パラメータ設定 const line_config = { channelAccessToken: process.env.LINE_ACCESS_TOKEN, // 環境変数からアクセストークンをセットしています channelSecret: process.env.LINE_CHANNEL_SECRET // 環境変数からChannel Secretをセットしています }; // ----------------------------------------------------------------------------- // Webサーバー設定 server.listen(process.env.PORT || 3000); // ----------------------------------------------------------------------------- // ルーター設定 server.post('/webhook', line.middleware(line_config), (req, res, next) => { res.sendStatus(200); console.log(req.body); }); const bot = new line.Client(line_config); // ----------------------------------------------------------------------------- // ルーター設定 server.post('/webhook', line.middleware(line_config), (req, res, next) => { // 先行してLINE側にステータスコード200でレスポンスする。 res.sendStatus(200); // すべてのイベント処理のプロミスを格納する配列。 let events_processed = []; // イベントオブジェクトを順次処理。 req.body.events.forEach((event) => { // この処理の対象をイベントタイプがメッセージで、かつ、テキストタイプだった場合に限定。 if (event.type == "message" && event.message.type == "text"){ // ユーザーからのテキストメッセージが「こんにちは」だった場合のみ反応。 if (event.message.text == "こんにちは"){ // replyMessage()で返信し、そのプロミスをevents_processedに追加。 events_processed.push(bot.replyMessage(event.replyToken, { type: "text", text: "これはこれは" })); } } }); // すべてのイベント処理が終了したら何個のイベントが処理されたか出力。 Promise.all(events_processed).then( (response) => { console.log(`${response.length} event(s) processed.`); } ); });このコードに
・ユーザーidの追加機能
・ユーザーidの削除機能
・登録しているユーザー全員へメッセージを転送する機能これらの機能を追加する為このように変更します。
index.jsvar fs = require('fs'); const server = require("express")(); const line = require("@line/bot-sdk"); const line_config = { channelAccessToken: process.env.LINE_ACCESS_TOKEN, channelSecret: process.env.LINE_CHANNEL_SECRET }; server.listen(process.env.PORT || 3000); const bot = new line.Client(line_config); // サーバー設定 server.post('/webhook', line.middleware(line_config), (req, res, next) => { res.sendStatus(200); var user_ids = require('./user_ids.json'); function unlink(path) { fs.unlink(path, function (err) { if (err) { throw err; } }); } function writeFile(path, data) { fs.writeFile(path, data, function (err) { if (err) { throw err; } }); } req.body.events.forEach((event) => { if (event.type == 'follow'){ function getUniqueStr(myStrong){ var strong = 1000; if (myStrong) strong = myStrong; return new Date().getTime().toString(16) + Math.floor(strong*Math.random()).toString(16) } let uuid = getUniqueStr(); let line_user_id = event.source.userId; user_ids[uuid] = line_user_id; unlink('./user_ids.json'); writeFile('./user_ids.json', JSON.stringify(user_ids)); console.log('------updated follow function------'); console.log(user_ids); console.log('------updated follow function------'); } if (event.type == 'unfollow'){ for(key in user_ids){ if(user_ids[key] == event.source.userId){ delete user_ids[key] writeFile('./user_ids.json', JSON.stringify(user_ids)); console.log('------updated unfollow function------'); console.log(user_ids); console.log('------updated unfollow function------'); } } } if (event.type == "message" && event.message.type == "text"){ let message = { type: 'text', text: event.message.text }; for(key in user_ids){ if(user_ids[key] != event.source.userId){ bot.pushMessage(user_ids[key], message); } } } }); });これプラス
ユーザーデータを保存しておくファイルである、user_ids.jsonをindex.htmlと同じ階層に追加しておいてくださいuser_ids.json{}編集が完了したら
$ ./deploy.sh
このコマンドでデプロイしてみましょう。
デプロイが完了したら、一度Botをブロックしてから友達追加してみましょう。
正しく編集出来ていたらメッセージの送受信が出来るようになっていると思います。
(一人では確認できないので、友達を招待してください)ただし、お頭が少々残念な方々を招待しすぎると2chのようなカオスな空間が出来てしまうので注意が必要です。
※ルームにそぐわない方は後でBotから排除させて頂きました☆
コードの説明
追加した処理ごとに説明をしていきます。
ユーザーの追加機能
index.jsif (event.type == 'follow'){ function getUniqueStr(myStrong){ var strong = 1000; if (myStrong) strong = myStrong; return new Date().getTime().toString(16) + Math.floor(strong*Math.random()).toString(16) } let uuid = getUniqueStr(); let line_user_id = event.source.userId; user_ids[uuid] = line_user_id; unlink('./user_ids.json'); writeFile('./user_ids.json', JSON.stringify(user_ids)); console.log('------updated follow function------'); console.log(user_ids); console.log('------updated follow function------'); }イベントのタイプがfollow(友達追加)だった場合
ランダムに作成した番号とユーザーのLineIdをセットにしたHashを、パースしたuser_idsに追加し、その値を元にuser_ids.jsonを更新しています。ユーザーの削除機能
index.jsif (event.type == 'unfollow'){ for(key in user_ids){ if(user_ids[key] == event.source.userId){ delete user_ids[key] writeFile('./user_ids.json', JSON.stringify(user_ids)); console.log('------updated unfollow function------'); console.log(user_ids); console.log('------updated unfollow function------'); } } }イベントのタイプがunfollow(ブロック)だった場合
ブロックしてきたユーザーのLineIdをuser_ids.jsonから削除しています。登録しているユーザー全員へメッセージを転送する機能
index.jsif (event.type == "message" && event.message.type == "text"){ let message = { type: 'text', text: event.message.text }; for(key in user_ids){ if(user_ids[key] != event.source.userId){ bot.pushMessage(user_ids[key], message); } } }イベントのタイプがmessageでしかもそのtypeがtextだった場合(メッセージを送信した場合)
user_ids.jsonに保存していた、メッセージを送信したユーザー以外のLineIdに向かいメッセージを送信しています。動作確認方法
「どんな仕組みで動いてんの?」
「なぜか動かない」
そんな方は
Herokuのログをリアルタイムで見ながら、Lineを操作する事がおすすめです。
下記コマンドで吐き出されたログを絶えず見ることができます。heroku logs --tail
データ管理
このままだと、gitを更新するたびにuser_ids.jsonが初期化されてしまうので、user_ids.jsonをgitの対象外にしておきましょう
git rm --cached user_ids.json最後に
もし興味があったら、お腹が痛い人たちBotにぜひ参加してみませんか?
QRコードはこれです。
何か面白い匿名チャットを思いついたらぜひ作ってみてください!!
- 投稿日:2019-02-09T19:17:50+09:00
JavascriptでJSON
はじめに
JavascriptでJSONを扱う機会が多いのでまとめてみます。mapとかreduceとかそろそろ使いこなせるようになりたいです。
前提
扱うJSONは下のような感じにしました。気分です。最近iPod卒業して以下の3つを品定め中だからです。ランキングは一部抜粋、今Apple Musicに傾きつつあるので、他のやつのランキングはスキップで。まあだいたい同じですし。
var sample = { Music_Services:[ { Service: "Apple Music", Company: "Apple", Top_Song_Ranking:{ observation_date: "2019-02-09", ranking:[ { artist: "あいみょん", song: "マリーゴールド", rank: 1 }, { artist: "ONE OK ROCK", song: "Stand Out Fit In", rank: 2 }, { artist: "あいみょん", song: "今夜このまま", rank: 3 }, { artist: "エド・シーラン", song: "Shape of You", rank: 7 }, { artist: "あいみょん", song: "愛を伝えたいだとか", rank: 9 } ] } }, { Service: "Google Play Music", Company: "Google", Top_Song_Ranking: null }, { Service: "Spotify", Company: "Spotify AB", Top_Song_Ranking: null } ] }* データ構造は適当に作ったものでApple MusicのAPI定義とかに合わせたりしてません。
参照
レコード参照
「音楽サービスのどんなデータ入ってるのかザーッと見たい」
sample["Music_Services"].forEach((item) => { console.log(item) })↓
{ Service: 'Apple Music', Company: 'Apple', Top_Song_Ranking: { observation_date: '2019-02-09', ranking: [ [Object], [Object], [Object], [Object], [Object] ] } } { Service: 'Google Play Music', Company: 'Google', Top_Song_Ranking: null } { Service: 'Spotify', Company: 'Spotify AB', Top_Song_Ranking: null }[Object]の中身表示したかったら
console.log(JSON.stringify(item))
にすれば見れますね。プロパティ参照
「一覧だと見づらいからどんな属性があるかだけ見たい」
var firstService = sample["Music_Services"][0] Object.keys(firstService).forEach((data) => { console.log(data); })↓
Service Company Top_Song_Ranking「もっと深い属性が見たい」
Object.keys(firstService["Top_Song_Ranking"]).forEach((data) => { console.log(data); }) console.log("====") var firstSong = firstService["Top_Song_Ranking"]["ranking"][0] Object.keys(firstSong).forEach((data) => { console.log(data); })↓
observation_date ranking ==== artist song rank基本的に1つ目のレコードだけサンプル的にとってきて中を覗く感じです。レコードによってプロパティに過不足ある場合とかは対象外で。
検索
単一検索
「Apple Musicの情報だけ欲しい」
const AppleMusic = sample["Music_Services"].find((item, index) => { return (item.Service === "Apple Music") }) /*こっちでもおなじ const AppleMusic = sample["Music_Services"].find((item, index) => { if(item.Service === "Apple Music") return true }) */ console.log(AppleMusic)↓
{ Service: 'Apple Music', Company: 'Apple', Top_Song_Ranking: { observation_date: '2019-02-09', ranking: [ [Object], [Object], [Object], [Object], [Object] ] } }ここからはApple Musicしか眼中に入れません。
なので、変数 "AppleMusic"を使いまわします。複数検索
「あいみょんの曲ってどんぐらいランキング入ってるんだろ」
const Aimyon_Songs = AppleMusic["Top_Song_Ranking"]["ranking"].filter((item, index) => { return (item.artist === "あいみょん") }) console.log(Aimyon_Songs)↓
[ { artist: 'あいみょん', song: 'マリーゴールド', rank: 1 }, { artist: 'あいみょん', song: '今夜このまま', rank: 3 }, { artist: 'あいみょん', song: '愛を伝えたいだとか', rank: 9 } ]*本当は他にももっと入ってますよ
「英語タイトルの曲どんくらいランキング入ってるんだろ」
const English_Titles = AppleMusic["Top_Song_Ranking"]["ranking"].filter((item, index) => { return (item.song.match(/[a-zA-Z]/)) }) console.log(English_Titles)↓
[ { artist: 'ONE OK ROCK', song: 'Stand Out Fit In', rank: 2 }, { artist: 'エド・シーラン', song: 'Shape of You', rank: 7 } ]*おまけ
filterは複数検索の時ですね。findも兼ねますが、なんとなく使い分けたいなと。
制限
「曲名だけ一覧でバーっと見たい」
const song_names = AppleMusic["Top_Song_Ranking"]["ranking"].map(x => x["song"]) console.log(song_names)↓
[ 'マリーゴールド', 'Stand Out Fit In', '今夜このまま', 'Shape of You', '愛を伝えたいだとか' ]mapって主にこういうときに使うイメージですね。他にもあるかな。
集約
「結局ランキングにどういうアーティストが何曲ずつくらい入ってるんだろ」
const summary = AppleMusic["Top_Song_Ranking"]["ranking"].reduce((accum, current)=> { //同じアーティスト名がaccumの中にあるか検索 const element = accum.find((item) => {return item.artist === current.artist}); //あったらカウントだけする if(element){ element.count ++} //なかったらaccumに追加してあげる else{ accum.push({ artist: current.artist, count: 1 }); } return accum }, []); console.log(summary)↓
[ { artist: 'あいみょん', count: 3 }, { artist: 'ONE OK ROCK', count: 1 }, { artist: 'エド・シーラン', count: 1 } ]reduceは集約するときに使う感じですね。forEachで足していくほうがわかりやすいんですけどreduceが使えたらかっこいいなと。まだまだ慣れません。
おわりに
reduceはやはり小難しい。あいみょんすごい。もう少し追記していきたいと思っているところです。
- 投稿日:2019-02-09T18:47:18+09:00
image-minによる画像圧縮
1~11のコマンドを実行すると画像の圧縮がすぐに行えるようになります
自分で導入する際にgulpやimageminを調べたりして
大変だったのでコピペだけで使えるようにまとめました。ターミナルでコマンドを実行してください。
1 - nodebrewをインストール
brew install nodebrew2 - yarnをインストール
brew install yarn3 - npm init (npmを使うための設定)
npm init4 - srcファイルを作成
mkdir src5 - distファイルを作成
mkdir dist6 - gulpfile.jsを作成
touch gulpfile.js7 - gulpをインストール
npm install gulp8 - imageminをインストール
npm i gulp-imagemin9 - imagemin-mozjpegをインストール
npm i imagemin-mozjpeg10 - imagemin-pngquantをインストール
npm i imagemin-pngquantここまで実行するとこのようなディレクトリ構造になっています。
├ dist ・圧縮した画像が置かれる (ディストリビューションの略) ├ gulpfile.js ・gulpの設定を行う ├ node_modules ・nodeの設定が補完される ├ package-lock.json ・nodeのバージョンを表記する ├ package.json ・nodeの設定を記述する └ src ・圧縮前の画像を保管する11 - gulpfile.jsに下記をコピぺする
gulpfile.jsconst gulp = require('gulp'); const distDir = 'dist'; const srcDir = 'src'; const imagemin = require('gulp-imagemin'); const pngquant = require('imagemin-pngquant'); const mozjpeg = require('imagemin-mozjpeg'); gulp.task('img', () => { return gulp.src(srcDir + '/*.{png,jpg,gif}') .pipe(imagemin([ pngquant('65-80'),// 配列を渡すと文字列を渡すようにエラーが出たので画質のみを設定 mozjpeg({ quality: 85, progressive: true }), imagemin.svgo(), imagemin.optipng(), imagemin.gifsicle() ])) .pipe(gulp.dest(distDir)); });実行
gulp imgpng画像を圧縮
圧縮前 (37KB)
Using gulpfile ~/test_gulp/gulpfile.js Starting 'img'... gulp-imagemin: Minified 1 image (saved 25 kB - 67%) Finished 'img' after 527 ms圧縮後 (12KB)
jpg画像を圧縮
スマホで撮った写真を圧縮してみる。
圧縮前 (1.9MB)
Using gulpfile ~/test_gulp/gulpfile.js Starting 'img'... gulp-imagemin: Minified 1 image (saved 25 kB - 67%) Finished 'img' after 571 ms圧縮後 (1.2MB)
まとめ
画像容量を6割近く削減することができました。
デザイナーではない素人目ですが画像の劣化などあまり気になりませんでした。・基本的に
gulpfile.js
を変更すれば設定を変更可能です。
・細かい圧縮の設定などを変更したい場合はリンクの公式のオプションを参考にしてみてください。ここまでお読みいただきありがとうございました。
雑談:iPhoneXの画質すごい
- 投稿日:2019-02-09T18:47:18+09:00
コピペですぐに使えるimage-minによる画像圧縮
1~11のコマンドを実行すると画像の圧縮がすぐに行えるようになります
自分で導入する際にgulpやimageminを調べたりして
大変だったのでコピペだけで使えるようにまとめました。ターミナルでコマンドを実行してください。
1 - nodebrewをインストール
brew install nodebrew2 - yarnをインストール
brew install yarn3 - npm init (npmを使うための設定)
npm init4 - srcファイルを作成
mkdir src5 - distファイルを作成
mkdir dist6 - gulpfile.jsを作成
touch gulpfile.js7 - gulpをインストール
npm install gulp8 - imageminをインストール
npm i gulp-imagemin9 - imagemin-mozjpegをインストール
npm i imagemin-mozjpeg10 - imagemin-pngquantをインストール
npm i imagemin-pngquantここまで実行するとこのようなディレクトリ構造になっています。
├ dist ・圧縮した画像が置かれる (ディストリビューションの略) ├ gulpfile.js ・gulpの設定を行う ├ node_modules ・nodeの設定が補完される ├ package-lock.json ・nodeのバージョンを表記する ├ package.json ・nodeの設定を記述する └ src ・圧縮前の画像を保管する11 - gulpfile.jsに下記をコピぺする
gulpfile.jsconst gulp = require('gulp'); const distDir = 'dist'; const srcDir = 'src'; const imagemin = require('gulp-imagemin'); const pngquant = require('imagemin-pngquant'); const mozjpeg = require('imagemin-mozjpeg'); gulp.task('img', () => { return gulp.src(srcDir + '/*.{png,jpg,gif}') .pipe(imagemin([ pngquant('65-80'),// 配列を渡すと文字列を渡すようにエラーが出たので画質のみを設定 mozjpeg({ quality: 85, progressive: true }), imagemin.svgo(), imagemin.optipng(), imagemin.gifsicle() ])) .pipe(gulp.dest(distDir)); });実行
gulp imgpng画像を圧縮
圧縮前 (37KB)
Using gulpfile ~/test_gulp/gulpfile.js Starting 'img'... gulp-imagemin: Minified 1 image (saved 25 kB - 67%) Finished 'img' after 527 ms圧縮後 (12KB)
jpg画像を圧縮
スマホで撮った写真を圧縮してみる。
圧縮前 (1.9MB)
Using gulpfile ~/test_gulp/gulpfile.js Starting 'img'... gulp-imagemin: Minified 1 image (saved 25 kB - 67%) Finished 'img' after 571 ms圧縮後 (1.2MB)
まとめ
画像容量を6割近く削減することができました。
デザイナーではない素人目ですが画像の劣化などあまり気になりませんでした。・基本的に
gulpfile.js
を変更すれば設定を変更可能です。
・細かい圧縮の設定などを変更したい場合はリンクの公式のオプションを参考にしてみてください。ここまでお読みいただきありがとうございました。
雑談:iPhoneXの画質すごい
- 投稿日:2019-02-09T18:47:18+09:00
【コピペですぐに使える】画像圧縮機能
1~11のコマンドを実行すると画像の圧縮がすぐに行えるようになります
自分で導入する際にgulpやimageminを調べたりして
大変だったのでコピペだけで使えるようにまとめました。ターミナルでコマンドを実行してください。
1 - nodebrewをインストール
brew install nodebrew2 - yarnをインストール
brew install yarn3 - npm init (npmを使うための設定)
npm init4 - srcファイルを作成
mkdir src5 - distファイルを作成
mkdir dist6 - gulpfile.jsを作成
touch gulpfile.js7 - gulpをインストール
npm install gulp8 - imageminをインストール
npm i gulp-imagemin9 - imagemin-mozjpegをインストール
npm i imagemin-mozjpeg10 - imagemin-pngquantをインストール
npm i imagemin-pngquantここまで実行するとこのようなディレクトリ構造になっています。
├ dist ・圧縮した画像が置かれる (ディストリビューションの略) ├ gulpfile.js ・gulpの設定を行う ├ node_modules ・nodeの設定が補完される ├ package-lock.json ・nodeのバージョンを表記する ├ package.json ・nodeの設定を記述する └ src ・圧縮前の画像を保管する11 - gulpfile.jsに下記をコピぺする
gulpfile.jsconst gulp = require('gulp'); const distDir = 'dist'; const srcDir = 'src'; const imagemin = require('gulp-imagemin'); const pngquant = require('imagemin-pngquant'); const mozjpeg = require('imagemin-mozjpeg'); gulp.task('img', () => { return gulp.src(srcDir + '/*.{png,jpg,gif}') .pipe(imagemin([ pngquant('65-80'),// 配列を渡すと文字列を渡すようにエラーが出たので画質のみを設定 mozjpeg({ quality: 85, progressive: true }), imagemin.svgo(), imagemin.optipng(), imagemin.gifsicle() ])) .pipe(gulp.dest(distDir)); });実行
gulp imgpng画像を圧縮
圧縮前 (37KB)
Using gulpfile ~/test_gulp/gulpfile.js Starting 'img'... gulp-imagemin: Minified 1 image (saved 25 kB - 67%) Finished 'img' after 527 ms圧縮後 (12KB)
jpg画像を圧縮
スマホで撮った写真を圧縮してみる。
圧縮前 (1.9MB)
Using gulpfile ~/test_gulp/gulpfile.js Starting 'img'... gulp-imagemin: Minified 1 image (saved 25 kB - 67%) Finished 'img' after 571 ms圧縮後 (1.2MB)
まとめ
画像容量を6割近く削減することができました。
デザイナーではない素人目ですが画像の劣化などあまり気になりませんでした。・基本的に
gulpfile.js
を変更すれば設定を変更可能です。
・細かい圧縮の設定などを変更したい場合はリンクの公式のオプションを参考にしてみてください。ここまでお読みいただきありがとうございました。
雑談:iPhoneXの画質すごい
- 投稿日:2019-02-09T15:45:39+09:00
GitHub Link Card Creatorがカッコいいのでnpm scriptsに組み込む
はじめに
みんなにOSSを見てもらいたい人の為に、GitHubリポジトリのOGP的画像を自動生成してくれるサービスを作った
こちらの記事で紹介されているGitHub Link Card Creatorが素晴らしくカッコいいので、node.jsのnpm scriptsに組み込む方法を模索してみました。
対象とするユーザー
- Go?なにそれ?
- 普段はnode.jsを使っている。
- ターミナルを触ったことがある。
- 自作のGitHubリポジトリにリンクカードをつけたい。
- macユーザーである。
この記事の環境
この記事は以下の環境を想定しています。各ソフトのバージョンが異なると、記事の内容は適用できない場合があります。ご注意ください。
- macOS 10.14.3
- node 8.11.4
- go 1.11.5 darwin/amd64
- Homebrew 2.0.0
この記事で解消したい問題
GitHub Link Card CreatorにはオフィシャルのWebアプリケーションがあります。
GitHub Link Card CreatorこちらのWebアプリケーションを利用すれば、画像の生成からリンクコードの出力までが一気にできます。
しかし、出力された画像URLがQiitaでは直接利用できないという問題があります。(参考 :issue#4)現状では、生成された画像をQiitaの記事内にアップロードし、生成されたリンクURLを書き換えることで対応が可能です。
しかしQiitaに画像をアップロードしてしまうと、カード情報の更新のたびに再アップロードが必要になります。この問題を解消するため
- GitHub Link Card Creatorをローカル環境で動かす。
- npm scriptsのタスクに組み込む。
- 生成された画像をGitHub Pagesにプッシュする。
- Qiitaの記事から画像を読み込む。
という組み込み作業を行ってみます。
Goとは
GoはGoogleが主導して開発しているプログラム言語およびその環境です。
正式な名称はGoですが、golangと呼ばれることもあります。
開発環境はオープンソースで、パッケージをインストールすればマルチプラットフォームで動作します。設定
macOS環境で、Homebrewを経由してGoパッケージをインストールします。
Homebrewのインストール
Homebrew
HomebrewはmacOS用のパッケージマネージャーです。Homebrewからさまざまなパッケージをインストールできます。
すでにHomebrewを導入している人は、この項目をスキップしてください。このスクリプトをターミナルに入力すると、Homebrewがインストールされます。
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"インストールが成功したか確認するためにバージョンを表示してみます。
brew -v Homebrew 2.0.0
バージョン番号が表示されたら無事インストール成功です。
Go環境の構築
インストール
先ほどインストールしたHomebrewを利用して、Goのパッケージをインストールします。
brew install go
パッケージのサイズが100MB以上ありますので、少し処理に時間がかかります。ゆっくりお待ちください。
go version go version go1.11.5 darwin/amd64こちらもバージョン情報が表示できればインストール成功です。
GitHub Link Card Creatorのインストール
GitHub Link Card Creatorパッケージは、以下のコマンドでインストールできます。
go get github.com/po3rin/github_link_creator/cmd/repoimgホームディレクトリ直下のgoフォルダーの中にファイルが保存されていれば、インストールは成功です。
パスの設定
GitHub Link Card Creatorはターミナルからコマンド
repoimg
で呼び出すことができます。
このコマンドが通るように、ターミナルにパスを通す必要があります。このパスはホームディレクトリ直下の
.bash_profile
というファイルに保存されています。
このファイルに以下の2行のパスを追加します。export GOPATH=$HOME/go export PATH=$PATH:$GOPATH/binターミナルから
.bash_profile
を編集する方法はこちらの記事をご参照ください。
MacでPATHを通すまた、Finderとお好きなテキストエディターを使って編集することもできます。
Finderから「移動」→「フォルダへ移動…」を選択し
~/.bash_profile
へ移動します。
ここで表示されたファイルをお好きなテキストエディターで編集してください。ターミナルの再起動
.bash_profile
の変更はそのままでは反映されません。再読み込みのコマンドを実行するか、ターミナルを再起動する必要があります。再読み込みのコマンドは以下の通りです
source ~/.bash_profile
.bashrcや.bash_profileなどの変更設定をすぐに反映させたい
WebStormやVS Codeなどのターミナルを内包しているソフトも、再起動をする必要があります。
以下のようなエラーが出る場合は、
.bash_profile
の反映ができていません。ソフトやmacの再起動を試してみてください。bash: repoimg: command not found
ここまでの作業でGitHub Link Card Creatorがターミナルから呼び出せるようになりました。
repoimg -n <GitHubのユーザー名>/<リポジトリ名>
で画像が生成されれば成功です。
GitHub Pagesの設定
次に、GitHub Pagesの公開設定を行います。
まずは作成済みのリポジトリのWebページにアクセスし、Settingsを開きます。
次に、GitHub Pagesの設定項目に移動し、Sourceをmaster Branch /docs folder
に変更します。これでリポジトリの
./docs
以下がhttps://<ユーザー名>.github.io/<リポジトリ名>/
でアクセスできます。npm scriptsに統合
最後に、npm scriptsに
repoimg
コマンドを組み込みます。package.json"scripts": { "doc:card": "repoimg -n <GitHubのユーザー名>/<リポジトリ名> -o ./docs/card.png" }このスクリプトで
./docs/card.png
が生成されます。
このファイルをプッシュすると以下のURLでアクセスができます。https://<ユーザー名>.github.io/<リポジトリ名>/card.pngこのURLをGitHub Link Card Creatorで生成される埋め込みコードに組み込むと
無事Qiitaの記事からGitHub Pagesの画像ファイルが読み込めました!以上、ありがとうございました。