- 投稿日:2020-02-11T22:48:42+09:00
【個人メモ】Node.js LINEBOT雛形
プロジェクト作成とハローワールド
$ mkdir linebot $ cd linebot $ npm init -y$ npm i @line/bot-sdk express$ npm install dotenv --save$ touch index.js $$ .env$ code .index.js'use strict'; const express = require('express'); const line = require('@line/bot-sdk'); const PORT = process.env.PORT || 3000; const dotenv = require('dotenv') dotenv.config() const config = { channelAccessToken: process.env.CHANNEL_ACCESS_TOKEN, channelSecret: process.env.CHANNEL_SECRET }; const app = express(); app.get('/', (req, res) => res.send('Hello(GET)')); app.post('/webhook', line.middleware(config), (req, res) => { console.log(req.body.events); if(req.body.events[0].replyToken === '00000000000000000000000000000000' && req.body.events[1].replyToken === 'ffffffffffffffffffffffffffffffff'){ res.send('Hello!(POST)'); console.log('疎通確認用'); return; } Promise .all(req.body.events.map(handleEvent)) .then((result) => res.json(result)); }); const client = new line.Client(config); function handleEvent(event) { if (event.type !== 'message' || event.message.type !== 'text') { return Promise.resolve(null); } return client.replyMessage(event.replyToken, { type: 'text', text: event.message.text }); } app.listen(PORT); console.log(`Server running at ${PORT}`);.env.sampleCHANNEL_ACCESS_TOKEN = "xxxxxxxxxxxxxxxxxxx" CHANNEL_SECRET = "xxxxxxxxxxxxxx" BASE_URL = 'xxxxxxxxxxxxx.ngrok.io'$ ngrok http 3000BASE_URLの書き換え
$ node index.jswebhookURLの設定
- 投稿日:2020-02-11T22:20:01+09:00
Windowsでgulpの環境構築。yarn編
yarnでgulpの環境構築
gulpの環構築の時にサラッと出来るように自分用に投稿。
完璧に初心者なのであしからず※ちなみにyarnもgulpもnodeもインストール済みとして書きます。
環境
・yarn
1.21.1
・gulp
CLI version: 2.2.0
Local version: 4.0.2 `
・node(楽だからnodistで管理したほうがいいかも)
v11.13.0手順
test(任意)フォルダの中に移動します
C:\Users\(ユーザー名) > CD testC:\Users\(ユーザー名)\test >ちなみにtestフォルダの中は下記になります
test─┬─css ├─scss │ └─main.scss └─index.htmlpackage.jsonを生成しないとダメなので下記を実行
C:\Users\(ユーザー名)\test > yarn init実行すると色々聞かれるけどエンター連打。
そうするとtest直下にpackage.jsonが生成される。test─┬─css ├─scss │ └─main.scss ├─package.json └─index.htmlmacはこの時にgulpのローカルインストールをする
C:\Users\(ユーザー名)\test > yarn add gulpパッケージをインストールします。なのでとりあえず下記を実行。
(後で色々変更できるけどとりあえず)C:\Users\(ユーザー名)\test > yarn add --dev gulp C:\Users\(ユーザー名)\test > yarn add --dev gulp-sass C:\Users\(ユーザー名)\test > yarn add --dev gulp-autoprefixer C:\Users\(ユーザー名)\test > yarn add --dev gulp-plumber次にgulpfile.jsの生成。これは自分で作らないとだめなやーつ。
作ったらtestフォルダに放り投げといて下さい。
中身はざっくりこんな感じ。const { watch, series, task, src, dest } = require('gulp'); const sass = require('gulp-sass'); const autoprefixer = require('gulp-autoprefixer'); const plumber = require('gulp-plumber'); const convertToCss = () => src('scss/*.scss') .pipe(plumber()) .pipe(sass()) .pipe(autoprefixer()) .pipe(dest('css/')); const watchscss = () => watch('scss/*.scss', convertToCss); exports.default = watchscss;.pipe(dest('css/'));の部分を
.pipe(dest('css'));にしててそれに気づかず大変でした。最後に下記を実行して終了
C:\Users\(ユーザー名)\test > yarn gulpこれでちゃんとコンパイルが出来ているはず。
何故かこれだけの作業なのに結構時間がかかった。
- 投稿日:2020-02-11T16:10:27+09:00
Nodejs(TypeScript)とcacとinquirer.jsでサクッとCLIを作成する
はじめに
NodejsでCLIツールを作成するときに良さそうなパッケージを見つけて、実際に使ってみたら良かったので紹介していきます。
使ったパッケージ
cac
シンプルでパワフルなコマンドラインインターフェイスを作るためのフレームワーク
https://www.npmjs.com/package/cac
inquirer.js
対話型のインターフェースを組み込むのに便利
https://www.npmjs.com/package/inquirer
インストール
$ npm i cac inquirer $ npm i --save-dev @types/inquirerサンプル
cac
を使ってCLIの骨組みを書いていきます。
下記の例ではcli hello hoge
みたいなコマンドを入力されたときに処理が実行されるようにしています。cli.tsimport index from '../src/index' import cac from 'cac' const cli = cac() cli.command('hello [name]', 'Enter your name').action(() => { index() }) cli.help() cli.parse()
inquirer
を使って対話型のインタフェースを定義していきます。
下記の例では、入力とリストとチェックボックスの対話型インターフェースを定義しています。index.tsimport { prompt, Separator, QuestionCollection } from 'inquirer' export default async (): Promise<void> => { const name = process.argv[3] if (!name) { console.error('Please pass one argument!!') process.exit(1) } const msg = ` Hello!! ${name} !!! ` console.log(msg) // Input const inputQuestions: QuestionCollection = [ { type: 'input', message: "What's your name", name: 'name' } ] await prompt(inputQuestions).then((answers: any) => { console.log(JSON.stringify(answers, null, ' ')) }) // List const listQuestions: QuestionCollection = [ { type: 'list', name: 'color', message: 'What do you like color?', choices: [ 'black', 'red', { name: 'orange', disabled: 'disabled' }, 'green' ] } ] await prompt(listQuestions).then((answers: any) => { console.log(JSON.stringify(answers, null, ' ')) }) // Checkbox const checkboxQuestions: QuestionCollection = [ { type: 'checkbox', message: 'select', name: 'select', choices: [ new Separator(' = Choise A = '), { name: 'hoge' }, { name: 'fuga' }, { name: 'foo' } ], validate: (answer: any): boolean | string => { if (answer.length < 1) { return 'You must choose' } return true } } ] await prompt(checkboxQuestions).then((answers: any) => { console.log(JSON.stringify(answers, null, ' ')) }) }実行する
ビルドするのが面倒なので
ts-node
で実行してきます。$ npx ts-node bin/cli.ts hello test Hello!! test !!! ? What's your name is_ryo { "name": "is_ryo" } ? What do you like color? red { "color": "red" } ? select hoge, fuga, foo { "select": [ "hoge", "fuga", "foo" ] }さいごに
サクッと対話型のCLIを作ることができました。
これでCLIを作るときの雛形はできるので、自作CLIを作っていきましょう!
ではまた!!!
- 投稿日:2020-02-11T12:34:43+09:00
Symbol Testnet node 構築備忘録
これは
https://billing.time4vps.com
で
借りたサーバーでテストネットノードを構築した際の 備忘録である
この構築にあたっては
mikun氏@mikunNEM
の協力無くしては
成し得ませんでした 今一度 感謝の意を表します
セキュリティー編----------------------------------------------
ここでは 例として
usernameを "pasomi"
sshdportを "20023"
として 作業を進めますrootでログイン
新しいuser作成
adduser pasomi(任意の名前)新しいuserにsudo権限付与
gpasswd -a pasomi sudosshポート変更とrootログイン禁止
vim /etc/ssh/sshd_config"i"で編集を開始
接続Poetの変更
"#Port 22"を"Port 20023"(任意の数字)に変更rootログインを禁止
"PermitRootLogin yes"を"PermitRootLogin no"に変更ESC keyで編集を終了
":wq"で保存して終了
※間違った時は":q!"で保存せず終了設定変更を反映させる
systemctl restart sshd※rebootの方がいいかも
これより後は変更したsshポートでないとログイン不可
rootでのログインも不可port20023でpasomiにログイン
dockerインストール編----------------------------------------------------------------------
(参考サイト https://qiita.com/youtangai/items/ff67ceff5497a0e0b1af)dockerがインストールのシェルスクリプトを用意しているので,それを実行します
curl https://get.docker.com | shデフォルトだと,sudoなしではdockerを実行できません.
ユーザをdockerグループに追加すると,sudoなしでdockerコマンドを実行できるので追加します.
sudo usermod -aG docker pasomiその後,ユーザ情報を更新するために再起動します.
sudo rebootターミナルが消える(再起動が掛かる)
ターミナル再起動pasomiでログイン
dockerを起動し,常時起動するようにします
sudo systemctl start docker
sudo systemctl enable dockerdockerが正常にインストールできたか確認します
docker --versionここでは"Docker version 19.03.5, build 633a0ea838"と出れば完了
docker-composeインストール編-----------------------------------------------------
(参考サイトhttps://qiita.com/youtangai/items/ff67ceff5497a0e0b1af)↓でdocker-composeの最新のバージョンを確認しましょう(メモしてください)
https://github.com/docker/compose/releasesここでは"1.25.4"と出る
docker-composeをインストール
sudo curl -L https://github.com/docker/compose/releases/download/1.25.4/docker-compose-`uname -s-
uname -m` -o /usr/local/bin/docker-compose
("1.25.4"は確認したバージョンを入力する)
※☝ちょっとココうまくコピペ出来なかったんで参考サイトの方使ってね?docker-composeコマンドを実行できるように,実行権限を与えます
sudo chmod +x /usr/local/bin/docker-composedocker-composeが正常にインストールできたか確認します
docker-compose --versionここでは"docker-compose version 1.25.4, build 8d51620a"と出る
bootstrapのダウンロード--------------------------------------------------------
Gitをインストール--------------
(参考サイト https://qiita.com/tommy_g/items/771ac45b89b02e8a5d64)Gitをインストール
sudo apt-get install git以下のコマンドを叩き、バージョンが表示されていればOK
dpkg -l git以下のコマンドを叩き、初期設定を行う
git config --global user.name pasomi
git config --global user.email pasomiufw(FairWall)のインストールと設定--------------------------------------------------------
(参考サイト https://qiita.com/_takeuchi_/items/2a1ee9b53c6a863bf844)ufwをインストール
sudo apt-get install ufwSSHで使用しているポート以外を閉じる
sudo ufw allow 20023/tcp(前に設定したsshポート)ポート3000と7900を開ける
sudo ufw allow 3000
sudo ufw allow 7900設定を反映させる
sudo ufw enableFireWall設定の確認
sudo ufw statusbootstrapをインストール
git clone https://github.com/nemfoundation/symbol-testnet-bootstrap.gitbootstrap起動の為にディレクトリに移動
cd symbol-testnet-bootstrap/api-harvest-assembly(又は"cd symbol-testnet-bootstrap/peer-assembly")
IPとフレンドリネームの設定ファイルを編集する
vi api-node/userconfig/resources/config-node.properties.template[localnode]の下にある
"host ="を"host = 176.223.130.232"に変更(自分のIP)"friendlyName = FRIENDLY_NAME"を "xym_pasomi:wehihi_from_dusanjp"に変更
docker-composeを実行する
sudo docker-compose up --build --detachdockerを停止する
sudo docker-compose down更新の方法 例②-----------------------------------------------------------------------------
Bootstrapのアップデートがあった時は、Bootstrapを停止してから、
sudo docker-compose down※ここでdockerのキャッシュを削除するといいかも
sudo docker system prune -aそのディレクトリを全て削除して、
sudo rm -rf symbol-testnet-bootstrap新しいBootstrapをダウンロードして、やり直してみてください?
git clone https://github.com/nemfoundation/symbol-testnet-bootstrap.gitIPとフレンドリネームの設定ファイルを編集する
vi api-node/userconfig/resources/config-node.properties.templatedocker-composeを実行する
sudo docker-compose up --build --detach更新の方法 例②----------------------------------------------------------------------------
更新の確認 https://github.com/nemfoundation/symbol-testnet-bootstrapで確認"api-harvest-assembly"ディレクトリへ移動
cd /api-harvest-assemblyapi-harvest-assemblyを停止
sudo docker-compose down上のディレクトリ"symbol-testnet-bootstrap"へ移動
cd ../bootstrapを更新
git pullディレクトリ"api-harvest-assembly"へ移動
cd api-harvest-assemblyapi-harvest-assemblyを開始
sudo docker-compose up -d
再立ち上げに失敗した時は
一旦 サーバーを再起動
sodo rebootcd symbol-testnet-bootstrap/api-harvest-assembly
docker-compose up -d
これで行けます
- 投稿日:2020-02-11T01:40:44+09:00
Knexあれこれ(雑多メモ)
はじめに(次の見出しまで飛ばしてOK)
最近仕事に対する楽しみ方を意識するようになり、今のつまらない仕事が続くのも嫌だったので、6月で辞めますと退職連絡を済ませてきた。
コーディングしてる最中はプライベートでも仕事でも楽しいので、コードをびっしり書くような会社に転職したいと思ったが、個人での活動実績はない。
とりあえず就活に繋がる作品を何か作ってみようと思い立ちこれ1本で大体何とか済ませちゃうNode.jsの勉強を1週間前に始めた。
が、DB処理があまり好きになれなかった。適当に買った参考書に書いてたDB処理は以下のようなもの
sql.jsconnection.query('SELECT * FROM hoge ', function (error, results, fields) { //取得結果に対する処理 });新卒配属された闇プロジェクトのシステム構成がこれに近い形式で実装されていたことが大体の原因ではあるが。
便利なnpmパッケージ Knex
PHP/Laravelあたりに言語/フレームワークを変更しようかなとこっそり考えつつ、何かいいnpmパッケージはないものかと探してみた。
あった(Knex公式)
記事を書いてくれている方もいた個人的に良いなと思った点
- チェーン形式で処理を書ける
- マイグレーションにも対応してる
軽く記事を流し読みるするだけでも結構便利に思えたのでリファレンス読みつつ色々試してみた。
で、ちょっと一々リファレンスを見に行くのもあれなのでちょっとメモを残そうと思いこの記事を書き始めた。正直公式リファレンスのは読みづらかった
割と参考記事とかぶってる点が多いので、多分knex回りを調べてこの記事を開いてくれた方は↑の参考記事を見ることをお勧めします。マイグレーションのあれこれメモ(本題)
実行前準備
初期構築 マイグレーションをするためのアレコレの準備
$ knex init
マイグレーション実行に当たる必要となる設定
module.exports = { // 開発環境の設定(デフォルトで参照される設定 NODE_ENVを書き換えればデフォルトではなくなる) development: { // データベースの種類 client: 'mysql', // DB接続設定 connection: { host : '127.0.0.1', user : 'root', password : '', database : 'node_app' }, // コネクションプールの設定 pool: { min: 2, max: 10 }, // マイグレーション設定 migrations: { // マイグレーションファイルの配置先(knexfile.jsからの相対) directory:'./db/migrations', // マイグレーションを管理するテーブル名 (マイグレーションの実行と同時にDBに作成される) tableName: 'knex_migrations' } }, // 開発環境とは異なる環境のマイグレーション実行設定定義 (本番環境,検証環境の差別化等) staging: { ... }, production: { ... }, };マイグレーションファイルの作成
<タイムスタンプ>_<ファイル名>.jsというファイルが、
migrations.directory
で設定したパス配下に配置される$ knex migrate:make <ファイル名>
マイグレーションファイルの中身の設定
細かく解説すると助長になるので、コメント参照
20200208161057_items.js// 後述する実行コマンドで呼び出されるメソッド exports.up = function(knex, Promise) { // connection.databaseで設定しているスキーマに引数で渡したテーブルがあるかチェック return knex.schema.hasTable('テーブル名') // hasTableのチェーンメソッド 判定結果を引数existsに渡して無名関数をコールバック .then(function(exists) { if (!exists) { // 接続先のスキーマに指定した名前でテーブルを作成する return knex.schema.createTable('テーブル名', // 作成したテーブルにカラムを作成する function(table) { // テーブルの要素設定 別途記載 table.increments('id').primary(); table.string('name', 100); table.integer('price'); }); }else{ return new Error("The table already exists. 2"); } }); }; // 後述する切り戻しコマンドで呼び出されるメソッド exports.down = function(knex, Promise) { return knex.schema.hasTable('items').then(function(exists) { if (exists) { // 指定したテーブルを削除する return knex.schema.dropTable('items'); } }); };接続先データベース/スキーマに対して実行するメソッド各種 (使いそうな奴だけ)
function(knex, Promise) { // テーブル作成メソッド コールバック内でカラム設定を忘れずに knex.schema.createTable(tableName, callback) // 指定したテーブル名を変更する knex.schema.renameTable(from, to) // 指定したテーブルを削除する knex.schema.dropTable(tableName) // 指定したテーブルが存在しないか確認する 上例のように.then()でチェーンするとスマート knex.schema.hasTable(tableName) // 指定したテーブルが存在すれば、そのテーブルを削除する. has,dropをチェーンしなくて済む knex.schema.dropTableIfExists(tableName) // 指定したテーブルに関する変更処理を実行する knex.schema.table(tableName, callback) };接続先のデータベース/スキーマが持つテーブルに対して実行するメソッド各種
createTableや、table関数のコールバック内で利用する
knex.schema.createTable('posts', function(table) { // 指定したカラムを削除する table.dropColumn(name) // 指定した複数のカラムを削除 table.dropColumns(*columns) // 指定したカラム名を変更 table.renameColumn(from, to) // オートインクリメント形式のカラムを追加 table.increments(name) // 文字列型のカラムを追加 オプション引数で長さも指定できる table.string(name, [length]) // 数値型のカラムを追加 table.integer(name) });主キーとか外部キーとかindexとかの使い方
カラム設定の関数にチェーンする
knex.schema.createTable('posts', function(table) { // 主キーの設定 table.increments(name).primary() // knexインスタンスがMySQLとPostgreSQLの場合のみ使える table.index(columns, [indexName], [indexType]) // 外部キーの設定 table.foreign(カラム名).references('参照テーブル.カラム名') table.string(name) table.foreign(name).references(table.name) });実行手順
未実行のマイグレーションファイルのupメソッドを、タイムスタンプの古い順に全ファイル実行
$ knex migrate:latest
envオプション: 実行対象の環境を指定してマイグレーションを実行する
$ knex migrate:latest --env production直前に実行した全てのマイグレーションファイルのdownメソッドを、タイムスタンプの新しい順に実行する
Latestでバッチ実行したなら、すべてのファイルをタイムスタンプの新しい順に実行する。
Upで個別実行したなら、そのマイグレーションファイルのみを実行する$ knex migrate:rollback
allオプション:過去に実行した全てのマイグレーションファイルのdownメソッドを実行する
$ knex migrate:rollback --allタイムスタンプが最も古い未実行のマイグレーションファイルのUpメソッドを実行する
$ knex migrate:up
マイグレーションファイルを指定してそのUpメソッドを実行する
$ knex migrate:up <ファイル名>.js
タイムスタンプが最も新しい実行済のマイグレーションファイルのdownメソッドを実行する
$ knex migrate:down
マイグレーションファイルを指定してそのdownメソッドを実行する
$ knex migrate:down <ファイル名>.js
マイグレーションファイルを一覧表示する
実行済みのものと未実行のものに分割してリスト表示してくれる
$ knex migrate:list Using environment: development Found 1 Completed Migration file/files. 20200208145923_items.js Found 1 Pending Migration file/files. 20200208161057_items.js
作成日の異なるマイグレーションファイルがある場合のmigrate:latestの挙動
タイムスタンプの古い方から実行される
/project |--migration | |--20200208161057_items.js | |--20200208161542_items.js20200208161057_items.jsexports.up = function(knex, Promise) { console.log('items oldest'); }20200208161542_items.jsexports.up = function(knex, Promise) { console.log('items lastest'); }実行結果$ knex migrate:latest Using environment: development items oldest items latest
作成日の異なるマイグレーションファイルがある場合のmigrate:rollbackの挙動
タイムスタンプの新しい方から実行される
/project |--migration | |--20200208161057_items.js | |--20200208161542_items.js20200208161057_items.jsexports.up = function(knex, Promise) { console.log('items oldest'); }20200208161542_items.jsexports.up = function(knex, Promise) { console.log('items lastest'); }実行結果$ knex migrate:rollback Using environment: development items latest items oldest
オプション引数類は一例で上げてるだけになります。詳細は公式へ
migrate:latestの後にもう1回migrate:latestをした場合のmigrate:rollbackの挙動
上述した通り、migrate:rollback は直前の1回の実行を戻す
2回に分けた場合は2回実行するか、--all
オプション を使うぼやき
結構前からあるパッケージなのにknexの日本語記事少ないってことは、
割とNode.jsを書いてる人からは不人気なのだろうか。
- 投稿日:2020-02-11T00:42:41+09:00
Node12系 AWS LambdaでHTMLをPDFに変換しようとしたらいろいろハマった
Node8系でwkhtmktopdfを使ってHTMLをPDFに変換するLambdaを使っていたのだが、Node8系で動いていた。
Node8系がサポートされなくなるということで、12系にそのままあげたら動かなくなってしまったのでNode12系でHTMLをPDFに変換するLambdaを作り直す必要が出てきた。HTMLをPDFに変換するLambdaについては結構多くの記事が見つかったが、なかなか上手くいかなかった。
やりたかったこと
Lambdaで日本語を含むHTMLをPDFに変換し、S3に保存する
試したが上手くいかなかった方法
- wkhtmlpdf
- 自分が見つけられなかっただけかもしれないが、Node12系でも問題なく動くソースを見つけられなかった
- html-pdf
- phantomjsの128エラーでちっとも動かなかった
- puppeteer
- 動きそうな気配はあったが、node_modulesのサイズが大きすぎてLambdaの最大ソースサイズをオーバーしてしまった
上手く行った方法
使用モジュール
chrome-aws-lambda を使った。
puppeteer-coreもnpm installする必要があるが、puppeteerだと大きすぎるから必要なcoreだけ使ってるっぽい。注意点
- Lambdaのメモリ設定を512MBにする必要があった
- 最初256MBにしていて、browserがlaunchできなかったいうようなエラーが出て、chrome-aws-lambdaもダメかあと思っていたところBUG報告で512MBにしたらできたで、って書いてあった
.fonts
をちゃんとzipファイルに含める
- Lambda環境に日本語フォントはない。自分で.fontsとして読み込ませる必要があるが、日本語が反映されへんな〜と思ったら.fontsをzipファイルに含むのが漏れていたというオチだった
コード
構造
┣ pdfGenerator.js ┣ package.json ┣ package-lock.json ┣ .fonts ┣ ipaexg.ttf ┣ ipaexm.ttfコード
pdfGenerator.js/* Lambda環境でも日本語フォントを使えるようにするには.fontsを読み込ませるためにHOMEを設定する必要ある */ process.env['HOME'] = "/var/task"; process.env['PATH'] = process.env['PATH'] + ':' + process.env['LAMBDA_TASK_ROOT']; const AWS = require("aws-sdk"); const S3 = new AWS.S3({ signatureVersion: "v4" }); const chromium = require("chrome-aws-lambda"); exports.handler = async function(event, context, callback) { try { if (!event.html) { callback("unable to get html"); return; } const fileName = event.filename, tmpFileName = `/tmp/${Math.random().toString(36).slice(2)}.pdf`, bucket = event.bucket, pageSize = event.pageSize || "A4", html = event.html; const executablePath = await chromium.executablePath, browser = await chromium.puppeteer.launch({ args: chromium.args, defaultViewport: chromium.defaultViewport, executablePath, headless: chromium.headless, ignoreHTTPSErrors: true }); const page = await browser.newPage(); await page.setContent(html); const pdf = await page.pdf({ path: tmpFileName, format: pageSize }); browser.close(); S3.putObject({ Bucket: bucket, Key: fileName, Body: pdf, ContentType: "application/pdf" }, (error) => { callback(error); }); } catch(e) { callback(e); } };参考リンク
- 投稿日:2020-02-11T00:40:40+09:00
Vue.js勉強会に参加してみた
はじめに
WantedlyでVue.jsの勉強会を見つけたので、参加してきました。
Vue.jsは前々から勉強しようと思っていたのですが、後回しになっていたので、これを機会に本腰を入れよう!環境構築
今回、事前に環境構築をしてきてとお願いされたのは以下のもの
- Visual Studio Code
- 拡張機能でVetur(Vue.js用の拡張機能)もインストール
- githubアカウント
- Node.js
- versionは10以上
- git
- versionは2.20以上
このうち、(僕のパソコンはWindowsなこともあり)Node.jsとgitのインストールを行いました。
nodistのインストール
WindowsでNode.jsのバージョンを管理するには、nodistを使うらしい。
インターン先ではnodebrewを使っていたので、「あれ?」と思ったが、nodebrewは基本的にmac環境で使っているそうです。以下のサイトの手順通りに進めました。
[Node.js] Node.js の導入(Windows編)1. 公式ページにアクセス
2. インストーラーをダウンロード
実行時のversionは0.9.1
3. インストーラーに従ってインストール
ここでインストール終了時に「PATH not updated, original length 1183 > 1024」というエラーが。
取り敢えず、「OK」を押すと、何事もなかったかのように「Install Finished」と出る。しかしコマンドプロンプトを開いて、
$ nodist -v
と打っても'nodist'は、内部ファイルまたは~というエラーが返ってくる。これはPATHが通ってないときに出てくるやつですね。
まぁ、さっきの時点でそんな気はしましたが、、、4. nodistのPATHを通す
こちらの方の記事を参考にしたら、うまくいきました!
node.js インストール備忘録(windows7)5. nodistのversion確認
$ nodist -v 0.9.1無事インストールできました!
Node.jsのインストール
続いてNode.jsをインストールしていきます。
1. インストール可能なNode.jsのバージョンを確認
$ nodist distめちゃくちゃ出てきてビックリ(笑)。
2. 任意のバージョンをインストール
「偶数バージョンの方がいい」みたいなことを聞いたことがあったので、調べてみると以下のような記事が。
node.jsのバージョンごとの違い今回は安全に使いたいので、偶数バージョンの最新版(12.14.1)をインストール。
$ nodist + v12.14.13. インストールされている Node.js を確認
$ nodist (x64) > 12.14.14. Node.js のバージョンを切り替える
$ nodist v12.14.15. 現在使用可能なNode.jsのバージョンを確認
$ node -v v12.14.16. npmのアップデート
npmはNode.jsのパッケージを管理するもの。
$ npm -v $ npm install npm -g以上でNode.jsのインストールは終了!
Gitのインストール
今までGitを使いたいときはSourseTreeを使っていたのですが、インターン先ではGitをコマンドで打つので、自分のパソコンにも入れたいと思いつつ、後回しにしていた。。。
今回やっとGitをインストール!以下の記事を参考にしました。
Git インストール for Windows特に問題はなく成功
$ git --version git version 2.25.0.windows.1Vueとは
- オープンソース
- WebアプリケーションのUIを構築
- SPAを高速に構築することが可能
- 学習コスト低い
Gitを使ってみる
ここは今回のメインではないので、箇条書きで進めます
- GitHubでリポジトリを作る
- リモートに適当なディレクトリを作る
- README.mdを作成し、
# Hello, GitHub!
と入力して保存git init
をして、gitの初期化git remote add origin git@github.com:xxxx/yyyy.git
git remote -v
でリモートを確認できるgit add .
をして、先ほど編集した差分をstage (commit待ちのファイル群) に乗せるgit status
で、stageに乗ったか確認 (緑色になってたらstaged)git commit -m "first commit"
で、差分をコミットgit push origin master
で、作ったコミットをoriginリモートのmasterブランチ (デフォルトのブランチ) にpushVue.jsについて
Vue.jsはドキュメントがとても優秀、わからなくなったらここを読めばほとんど全て理解できる
- https://jp.vuejs.org/v2/guide/index.html
-そのドキュメントの日本語がよく分からず後回しにした人間がここに1人Vueで書いてみよう
今回はscriptタグで、CDNからVueを読みます。
Todoリストを作成して、練習していきます。sample.html<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Step1 ToDo Application</title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> </html>Vueインスタンスの作成
ではbody要素を足していきます。
まずはVueのインスタンスを作ります。更に、elプロパティでappというidの要素を指定すると、それ以下をVueが管理してくれます。sample.html<body> <div id="app"> <!-- ここをvueが管理 --> </div> <script> const app = new Vue({ el: '#app' // "id=app"を指定 }) </script> </body>データを持つ
動的に変化するデータを扱うには、data プロパティに宣言します。
そして{{}}内に囲むことで、そのデータを表示できます。sample.html<body> <div id="app"> {{ hoge }} </div> <script> const app = new Vue({ el: '#app', data: { hoge: "sample" } }) </script> </body>ここでVueの特徴の一つreactive性が出てきます。
これは、変更されたdataが直ちに再描画されるというものです。フォームデータの束縛(バインディング)
v-model="~"
の形で記述された場合、~
の変数にデータを格納します。sample.html<body> <div id="app"> <label>ToDoの内容<input type="text" v-model="todoText"></label> {{ todoText }} </div> <script> const app = new Vue({ el: '#app', data: { todoText: "sample" } }) </script> </body>こうすると、inputタグのデータがtodoTextという変数と結びつくため、フォーム内に初めから"sample"という文字列が表示されます。
リストの表示
リストを表示するには
v-for
を使います。sample.html<body> <div id="app"> <label>ToDoの内容<input type="text" v-model="todoText"></label> <ul> <li v-for="todo in todoList">{{ todo }}</li> </ul> </div> <script> const app = new Vue({ el: '#app', data: { todoText: "sample", todoList: ['掃除', '洗濯', '料理'] } }) </script> </body>算出プロパティ
テンプレートで表示するのに計算が必要な場合は算出プロパティ
computed
を使用します。sample.html<body> <div id="app"> <label>ToDoの内容<input type="text" v-model="todoText"></label> <p>あと{{ todoCount }}個のtodo</p> <ul> <li v-for="todo in todoList">{{ todo }}</li> </ul> </div> <script> const app = new Vue({ el: '#app', data: { todoText: "sample", todoList: ['掃除', '洗濯', '料理'] }, computed: { todoCount() { return this.todoList.length } } }) </script> </body>メソッド
DOMイベントに対して何かのアクションをするには、
v-on
ディレクティブを使用します。
これにより、呼び出したいメソッドを呼ぶことができます。sample.html<body> <div id="app"> <label>ToDoの内容<input type="text" v-model="todoText"></label> <button v-on:click="register">登録</button> <p>あと{{ todoCount }}個のtodo</p> <ul> <li v-for="todo in todoList">{{ todo }}</li> </ul> </div> <script> const app = new Vue({ el: '#app', data: { todoText: "", todoList: [] }, computed: { todoCount() { return this.todoList.length } }, methods: { register: function() { this.todoList.push(this.todoText); this.todoText = ""; } } }) </script> </body>より本格的な開発のために
コンポーネントシステム
コンポーネントとは、ざっくり言うと「部品」のこと。
ページをコンポーネント化して、各部品として管理することで、再利用性や保守性が高まる。Vueでは.vueファイルとして保存します。
更にVueの特徴は、.vueファイル一枚にtemplate,style,scriptを書けることです。(単一ファイルコンポーネント)
このおかげで、ファイル管理が楽になります。Vuex
状態管理のためのライブラリ(+パターン)。
共通の状態やデータを複数のコンポーネントで管理する場合に活用できる。参考:ざっくり理解、Vuexって何?VuexとAPIの関係を図解してみた
Nuxt.jsについて
Nuxt.jsとは
Nuxtは、モダンな web アプリケーションを作成する Vue.js に基づいたプログレッシブフレームワークです。Vue.js 公式ライブラリ(vue、vue-router や vuex)および強力な開発ツール(webpack、Babel や PostCSS)に基づいています。 Nuxt の目標は、優れた開発者エクスペリエンスを念頭に置き、Web 開発を強力かつ高性能にすることです。
先ほど説明したものや、cssフレームワーク、SSRなどもろもろのベストプラクティスを適用したプロジェクトを一瞬で構築可能。
本格的なWebアプリケーション作成ができる。Nuxt.jsをセットアップする
npxのインストール
npxを使うと、ローカルにインストールしたnpmパッケージを、npxコマンドだけで実行できるようになります。
これにより、面倒なコマンドを打たなくて済みます。
言わば"便利コマンド集"のようなもの。普通はnpmが入れば自動的にインストールされる。
しかしnodist経由だと、npxが自動でインストールされないらしい...そこで個別にインストールします。
$ npm install -g npxプロジェクト作成
npm create-nuxt-app <プロジェクト名>
でNuxt.jsのプロジェクトを作成可能です。
ただし、プロジェクトを作る場所はカレントディレクトリではなく、キャッシュに残っている場所になってしまいます。しかもその場所のパスにスペースが入っていると、
operation not permitted, mkdir '~'のエラーが出てプロジェクトを作れない。。。
そこで、エラーが出る場合は以下のコマンドでキャッシュの場所を変えます。
$ npm config set cache <プロジェクトを作りたいディレクトリのパス> --globalその上で改めて
$ npm create-nuxt-app <プロジェクト名>を実行します。
プロジェクト作成中、UIフレームワークなど、設定を聞かれるので、適宜選択してください。
プロジェクトのディレクトリ構成
- layouts
- 全ページで使用されるテンプレートファイルを規定する。ページの外観を変更するために使用される(例えばサイドバーなど)。
- page の
layout
プロパティで変更可能- pages
- アプリケーションのビュー及びルーティングファイルを入れる。
- Nuxt.js フレームワークはこのディレクトリ内のすべての .vue ファイルを読み込み、Vue Routerによって自動的にルーティングされる
pages/index.vue
→/
pages/hoge/fuga.vue
→/hoge/fuga
- components
- pages から利用するコンポーネントを入れておく
- components から components も使ったりする
- stores
- Vuex ストアのファイルを入れる
- デフォルトではVuexストアは無効。このディレクトリに index.js ファイルを作成するとストアが有効になる。
Nuxt.jsでカレンダーアプリを作ってみる
サンプルとしてカレンダーアプリ(
と言えるかすら微妙なもの)を作ってみました。index.vueの作成
まずはindex.vueです。pagesディレクトリ内に作ります。
コンポーネントとして作ったCalender.vueをscript
内で読み込みます。
これにより、Calender.vueの内容を、<calender />
タグの部分にはめ込むことができます。index.vue<template> <div class="container"> <calendar /> </div> </template> <script> import Calendar from '~/components/Calendar' export default { components: { Calendar, } } </script> <style></style>コンポーネントの作成(Calendar.vueとCalendarDay.vue)
Calendar.vueにカレンダーの全体像、CalendarDay.vueにカレンダーの一日の部分を入れます。
Calendar.vue<template> <div class="calendar"> <calendar-day v-for="day in dayList" :key="day" :day="day" /> </div> </template> <script> import CalendarDay from '~/components/CalendarDay' export default { components: { CalendarDay, }, data() { return { dayList: [] } }, created() { for (let i = 1; i <= 31; i++) { this.dayList.push(i) } } } </script> <style scoped> .calendar { display: flex; flex-direction: row; flex-wrap: wrap; } </style>CalendarDay.vue<template> <div class="calendar-day"> {{ day }} <input type="text" v-model="text"> <button @click="addSchedule({ day, text })">追加</button> <ul> <li v-for="schedule in scheduleList" :key="schedule.id">{{ schedule.text }}</li> </ul> </div> </template> <style scoped> .calendar-day { border: solid 1px black; width: 150px; height: 150px; } </style> <script> import { mapGetters, mapMutations } from 'vuex' export default { data() { return { text: '', } }, props: { day: 0, }, computed: { ...mapGetters({ getScheduleListByDay: 'schedule/getScheduleListByDay', }), scheduleList() { return this.getScheduleListByDay(this.day) } }, methods: { ...mapMutations({ addSchedule: 'schedule/addSchedule' }), } } </script>storeの作成(schedule.js)
storeディレクトリにschedule.jsを作成し、予定データを保存・加工します。
schedule.jsexport const state = () => ({ scheduleList: [], // Array<{ id: Number, day: Number, text: String }> lastScheduleId: 0, }) export const getters = { getScheduleListByDay: (state) => (day) => { return state.scheduleList.filter(schedule => schedule.day === day) }, } export const mutations = { addSchedule (state, { day, text }) { state.scheduleList.push({ id: ++state.lastScheduleId, day, text, }) }, }おわりに
Vueを使うと、コンポーネントとしての管理がしやすいなぁと思いました。
ただ、アロー関数などJSの記法をしっかり覚えないと...