- 投稿日:2019-08-20T22:13:28+09:00
Vue.js初心者お勉強-その1-
前回までのおさらい
firebase で テンプレ環境は展開できた。この後は、firebaseでさくっとvue.jsで作成したフロントエンドアプリを公開したいが、その前に少しくらいvue.jsをカスタマイズできるようになっておくべきと思ったので、vue.jsを勉強。なお、vue.jsを勉強した後のfirebase + vue.jsでググると山ほど記事が出てくるので、写経すればそんなに難しくない、と予想します。
触ってみる
こちらの記事が簡単そうだったので、やってみます。
vue-cliのインストール
vue-cliは雛形からプロジェクトを作成してくれる公式ツールです。よくある対話型で答えていけばうまい事やってくれるやつ。npm initとか、firebase initとかみたいな。
npm install -g vue-clivue-cliによるvueプロジェクト作成
以下のコマンドでプロジェクトを作成します。
vue init [テンプレート名] [プロジェクト名]テンプレート名は写経してwebpackを指定。他にもいろいろあって、メリットもさまざまなのでしょうか…?
PS C:\first_vuejs> vue init webpack first_vuejs ? Project name first_vuejs ? Project description A Vue.js project ? Author teraco ? Vue build standalone ? Install vue-router? Yes ? Use ESLint to lint your code? Yes ? Pick an ESLint preset Airbnb ? Set up unit tests Yes ? Pick a test runner karma ? Setup e2e tests with Nightwatch? Yes ? Should we run `npm install` for you after the project has been created? (recommended) npmなどと入力するとガリガリとプロジェクトを作成していき
※ 最近のvueでは、vue create [プロジェクト名]でプロジェクトを作成するのが流行りの様子。
To get started: cd first_vuejs npm run devと指示されるので実行。
> webpack-dev-server --inline --progress --config build/webpack.dev.conf.js 13% building modules 30/33 modules 3 active ...t_vuejs\src\components\HelloWorld.vue{ parser: "babylon" } is deprecated; we now treat it as { parser: "babel" }. 95% emitting DONE Compiled successfully in 16857ms 22:54:14 I Your application is running here: http://localhost:8080めでたくHello worldに成功したようです。
さて、中身を見てみるとindex.htmlが不思議…。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <title>first_vuejs</title> </head> <body> <div id="app"></div> <!-- built files will be auto injected --> </body> </html>index.htmlからjsなどへのリンクが張っていないが、Webpackを使って統合されるらしいです。
Vue.js初心者向け:インラインテンプレートから単一ファイルコンポーネントの使い方まで - Qiitaそれではチュートリアル通りに中身をいじっていきます。
タイトル変更 & vueプロジェクトの構成
app.vue<template> <div id="app"> <img src="./assets/logo.png"> <h1>Todo Management.</h1> <hr /> <router-view/> </div> </template>index.htmlから呼ばれるapp.vueを編集し、H1を追加します。これで全てのページに反映されます。…とこの後のステップを言葉で書くのがつらいので、図にしてみました。
ちょいと拡大してみてほしいのですが、
- app.vueから個別ページ用の表示をスイッチする"view"機能を呼び出し。これをvueでは"ルーター"と呼ぶ。
- "ルーター"の実体はsrc/router/index.js。こいつで、どのパスにアクセスしたら、どのページを表示するかを決定する。ここでは "/" にアクセスしたら、HelloWorld.vueを表示、/hogeにアクセスしたらhoge.vueを表示としている。
- あとは、HelloWorld.vueとかhoge.vueを書けば、個別ページが書き変わる。
ここまでがvue-cliで始めるVue.jsチュートリアル (1) - Qiitaの内容です。
以下、vue-cliで始めるVue.jsチュートリアル (2) - Qiitaの内容。これも写経なのだが、画像で説明。
前述のHelloWorld.vueが個別ページの表示を決定するファイルだった。これを編集してチュートリアルを続ける。このxxxx.vueはの間にページの実体を書いていく形式なので、チュートリアル(1)で作成したの中身を削除し、チュートリアル(2)を進める。
リストの表示(ループ)
前述した通り、間にHTML(ぽいもの)を書けばページが表示できるがそれだと拡張性がないので、v-forを使って表示する。
v-forは公式ページでリストレンダリング — Vue.jsとして説明されているディレクティブである。ディレクティブとはテンプレート構文 — Vue.jsで説明されている通り、Vue.jsの世界でv-から始まる特別な属性、と理解すればよいみたい。
Todoの追加
これもVue.jsに用意されているディレクティブを利用してやってみる。
中のv-on:clickされたらaddTodo()メソッドを実行し、addTodoメソッドの内容は下部の赤枠に書いてある。内容はnewTodoに値を追加する事。Todoの削除
Todoの削除とやっている事はあまり変わらず。v-onディレクティブを利用して、メソッドを呼び出して動作させる。
v-onの文字がなくなって@になっているのは、vue.jsの省略記法である。詳しくは以下ページを参照。
Todoの編集 / 完了済みTodoへのclass付与
前者はv-ifディレクティブ、v-elseディレクティブを使って実装。後者はv-bindディレクティブを使って実装。画像省略。
GitHub Pagesでの配信
チュートリアルの通りにやったらできました。GitHub Pages初めて使ったけど、こりゃ簡単でいいですね。
以上です。
今後の勉強予定メモ
- Vue.js単体
- Vue.js 初心者向けタッチ&トライ @de:code 2019 - 資料一覧 - connpass
- Vue 3.x系、TypeScriptを利用するチュートリアル。Elementを使って管理画面作成もあり。
- チュートリアルについて | 基礎から学ぶ Vue.js
- 書籍の補足資料だからきっと簡単なはず
- Vue.js の主要な機能をざっくりとつかってみたときのメモ - Qiita
- ぱっと見、難しそうだった
- Vue.js + Firebase
- その他
- 投稿日:2019-08-20T18:18:10+09:00
RabbitMQを使ってみる by JavaScript
初めまして、Guuuuuchanと申します。
初めての投稿です。はじめに
最近、業務でRabbitMQを使いました。
初めて実装した時はドキュメントを読んでもどういうものかよくわからず、まずは動かして理解しようかと思いました。備忘録的なところが多いので、多少説明が足りなくて申し訳ないかもしれないです。
その時はコメントで補足などもらえたら助かります。また、僕の場合はJavaScript(Node.js)での実装になるので、JavaでRabbitMQ使いたい方はこちらの方が書いた素晴らしい記事が参考になるかと思います。
AMQPとは?
この辺はWikiとか公式を読んでもらった方が正確です。
AMQPは「Advanced Message Queuing Protocol」の略です。
プラットフォームに依存しないメッセージングミドルウェアです。メッセージをキューに入れて、非同期で取り出すといった単純なものです。
公式サイトには「To become the standard protocol for interoperability between all messaging middleware(すべてのメッセージングミドルウェア間の相互運用性の標準プロトコルになるため)」と書かれています。
- 特徴
- オープンスタンダードなアプリケーション層のためのプロトコル
- メッセージ指向
- キューイング
- ルーティング
- セキュア
- 堅牢性
RabbitMQってなに?
RabbitMQはAMQPを実装したオープンソースのミドルウェアです。
似たようなミドルウェアとしてActiveMAやIBM MQ Lightなどがあります。Erlang上で動いており、クラスタリングとフェイルオーバーを実現するためにOpen Telecom Platformフレームワーク上で構築されています。耐久性やスケーリングを考慮して設計されているようです。
クライアントアプリは以下の言語で動きます。
- Python
- Java
- Ruby
- PHP
- C#
- JavaScript
- Go
- Elixir
- Objective-C
- Swift
- Spring AMQP
なぜRabbitMQを使う必要があるのか?
結論から言うと
1. スケーリングできる
1. 耐障害性がある
1. メンテナンスがしやすい例えば大量のデータをバッチ実行したい場合、途中で失敗した場合最初からやり直す必要があります。
RabbitMQを使えば、バッチの引数に与えるデータをRabbitMQのキューに入れておくことで、バッチが途中で終了した場合でも失敗した箇所から実行できます。
そして、データが大量にある場合、キューを取り出すジョブを増やすことでスケールすることが可能です。
また、データをキューに入れておくことで、データを入れる側と取り出す側で任意のタイミングで処理を実行することができるので、どちらがメンテナンス状態になってもさほど大きな問題にはなりません。準備
僕の環境では以下のツールが入っているので、もし動かしたい場合は先に以下のツールを先に入れておいてください。
- Docker
- Node.js
- yarn
まずはRabbitMQサーバを立てよう!
DockerでコンテナにRabbitMQサーバを立てます。
まず、適当なディレクトリを作ります。
mkdir sample-rabbitmq-server cd sample-rabbitmq-serverdocker-compose.ymlを作成し、コンテナの内容を記載します。
touch docker-compose.yml
docker-composeの内容は以下のように記載します。
version: '3' services: my-queue: container_name: rabbitmq image: rabbitmq:3.7.17-management ports: - '5672:5672' - '15672:15672' volumes: - rabbitmq-data:/var/lib/rabbitmq volumes: rabbitmq-data: docker-compose up -dブラウザを開き、http://localhost:15672にアクセスしてみましょう。
guest/guestでログインできます。
ログイン後はこんな画面になるはず
とりあえず、サーバのインストールは以上です。
また、rabbitmqのバージョンを投稿時の最新で記載していますが、こちらのページで最新バージョンを知ることができます。
RabbitMQ Changelog — RabbitMQRabbitMQのクライアントを使ってメッセージを送ってみよう
今回の投稿ではJavaScript(Node.js)で実装してみます。
まず、プロジェクトを作ります。yarn initでNodeのプロジェクトを作ります。successが出てくればOKです。
mkdir rabbitmq-client cd rabbitmq-client yarn init // 連打でOK こんなメッセージが出てくるはず yarn init v1.16.0 question name (rabbitmq-client): question version (1.0.0): question description: question entry point (index.js): question repository url: question author: question license (MIT): question private: success Saved package.json ✨ Done in 4.98s.次に、RabbitMQのクライアントを入れましょう!
yarn add amqplibメッセージを送るプログラムを作ります。
vim send.js const amqp = require('amqplib/callback_api'); amqp.connect('amqp://localhost', (error0, connection) => { if (error0) throw error0; connection.createChannel((error1, channel) => { if (error1) throw error1; const queue = 'hello'; const msg = 'Hello world'; channel.assertQueue(queue, { durable: false }); channel.sendToQueue(queue, Buffer.from(msg)); console.log(" Sent message :", msg); }); setTimeout(() => { connection.close(); process.exit(0) }, 500); });保存したら、実行してメッセージを送ります。
node send.js実行後、コンソールにメッセージが出るはずです。
$ node send.js Sent message : Hello world
メッセージが本当に送れているかWebUIで確認してみましょう。
次はメッセージを受信してみよう
メッセージを受信するプログラムを作ります。
vim receive.jsvar amqp = require('amqplib/callback_api'); amqp.connect('amqp://localhost', function(error0, connection) { if (error0) { throw error0; } connection.createChannel(function(error1, channel) { if (error1) { throw error1; } var queue = 'hello'; channel.assertQueue(queue, { durable: false }); console.log(" [*] Waiting for messages in %s. To exit press CTRL+C", queue); channel.consume(queue, function(msg) { console.log(" [x] Received %s", msg.content.toString()); }, { noAck: true }); }); });実行してみます。
$ node receive.js
こんなメッセージが出ればOKです。
[*] Waiting for messages in hello. To exit press CTRL+C [x] Received Hello worldCtrl + Cを押すまで、待機状態になります。
別のコンソールで、send.jsを実行すると非同期でreceive.jsに受信されます。その他
receive.jsを動かさない状態で、send.jsを何度か実行するとどんどんQueueにメッセージが溜まっていきます。
その時、receive.jsを起動すると、一気にキューを受け取ります。
また、複数のコンソールでreceive.jsを起動すると、ランダム?でどれかのreceive.jsに受信されます。キューからメッセージを受け取る時は一度しか取れないですからです。これは設定で変更することができます。
最後に
最近のフロントエンドでは、非同期処理が当たり前のように使われるようになってきました。
もしかしたら今後、RabbitMQを使うシーンがまたあるかもしれないです。また、別の投稿でRabbitMQの使い方を紹介しようと思っています。
参考文献
業務で使う場合はやはり公式ドキュメントが一番よいと思います。
Messaging that just works — RabbitMQRabbitMQのチュートリアルがあるのでこちらを参考にしてください
Getting started with RabbitMQ — RabbitMQ
- 投稿日:2019-08-20T18:16:49+09:00
Node JSのコールバックパターン
継続渡しスタイル(continuation-passing style : CPS)
JavaScriptにおいてコールバック関数とは、ある関数を呼び出す時に、引数として指定する関数で、FuncAの処理が完了した時にFuncAの結果を通知するために起動される関数のことを指します。
同期的継続渡しスタイル
test.jsfunction add(a, b, callback) { callback(a + b) } console.log('before') add(1, 2, result => console.log('Result : ' + result)) console.log('after')結果
example.sh$ node test.js before Result : 3 after
非同期CPS
test.jsfunction addAsync(a, b, callback) { setTimeout(() => callback(a + b), 100) } console.log('before') add(1, 2, result => console.log('Result : ' + result)) console.log('after')結果
example.sh$ node test.js before after Result : 3
継続渡しではないコールバック
test.jsconst result = [1, 5, 7].map(element => element - 1) console.log(result) // [0, 4, 6]ちなみに以下のことはダイレクトスタイル(Direct Style:DS)と呼びます。
example.jsfunction add(a, b) { return a + b } console.log(add(1,2)) // 3同期処理か非同期処理か
どっちでもいいですが、まず避けなければならないのは「一貫性がないAPI」です。
同期と非同期の混在
もっとも危険なのは、ある条件には同期処理、ある条件には非同期処理を行う関数です。
以下のコードは一貫性がないコードの例です。test.jsconst fs = require('fs') const cache = {} function inconsistentRead(filename, callback) { if(cache[filename]) { callback(cache[filename]) // cacheにデータがある場合、同期的に実行される。 } else { // cacheにデータがない場合、ひい同期関数fs.readFile()を呼び出す。 fs.readFile(filename, 'utf8', (err, data) => { cache[filename] = data callback(data) } } }混在がもたらす問題
test.jsconst fs = require('fs') const cache = {} function inconsistentRead(filename, callback) { if(cache[filename]) { callback(cache[filename]) // cacheにデータがある場合、同期的に実行される。 } else { // cacheにデータがない場合、ひい同期関数fs.readFile()を呼び出す。 fs.readFile(filename, 'utf8', (err, data) => { cache[filename] = data callback(data) }) } } function createFileReader(filename) { const listeners = [] inconsistentRead(filename, value => { listeners.forEach(listener => listener(value)) }) return { onDataReady: listener => listeners.push(listener) } } const reader1 = createFileReader('data.txt') reader1.onDataReady(data => { console.log('First call data: ' + data) // しばらくしてから同じファイルを呼び出す const reader2 = createFileReader('data.txt') reader2.onDataReady(data => { console.log('Second call data: ' + data) }) })結果
example.sh$ node test.js First call data: some data
解決策1同期APIの利用
同期関数を使えば解決できます。
test.jsconst fs = require('fs') const cache = {} function consistentReadSync(filename) { if (cache[filename]) { return cache[filename] } else { cache[filename] = fs.readFileSync(filename, 'utf8') // 同期関数使用 return cache[filename] } }しかし、以下の留意点があります。
・ある機能に関して常に同期バージョウンが用意されているとは限らない
・他のリクエストは処理待ちとなるため、全体的にパフォーマンスが落ちる。解決策2遅延実行
同期的なコールバックが「将来」起動されるようにスケジュールする。
test.jsconst fs = require('fs') const cache = {} function consistentReadAsync(filename) { if (cache[filename]) { process.nextTick(() => callback(cache[filename])) } else { fs.readFile(filename, 'utf8', (err, data) => { cache[filename] = data callback(data) } } }Node.jsのコールバック
エラーの伝播
test.jsconst fs = require('fs') function readJSON(filename, callback) { fs.readFile(filename, 'utf8', (err, data) => { let parsed if (err) { return callback(err) } try { parsed = JSON.parse(data) } catch (err) { return callback(err) } callback(null, parsed) }) }キャッチされない例外
test.jsconst fs = require('fs') function readJSONThrows(filename, callback) { fs.readFile(filename, 'utf8', (err, data) => { let parsed if (err) { return callback(err) } callback(null, JSON.parse(data)) }) } try { readJSONThrows('nonjson.txt', err => { if (err) { console.log(err) } else { JSON.stringify(json) } }) } catch(err) { console.log('こうしてもキャッチはできません。') }上記の場合、キャッチされません。なぜなら、readJSONThrowsを呼び出すスタックとコールバックを呼び出すスタックがことなるからです。
これは下記のようにコードを作ったらキャッチされます。test.jsreadJSONThrows('nonjson.txt', err => { if (err) { console.log(err) } else { JSON.stringify(json) } }) process.on('uncaughtException', (err) => { console.error('ここでキャッチ') process.exit(1) // エラーコード1で終了。これがないと実行を継続する。 })参考文献
Node.jsデザインパターン 第2版 - Mario Casciaro (著), Luciano Mammino (著), 武舎 広幸 (翻訳), 阿部 和也 (翻訳)
- 投稿日:2019-08-20T18:04:01+09:00
Webpack でビルドが稀に落ちる現象の回避
こういうやつ。
V8 がメモリ不足か何かで落ちる現象みたいです。
Ineffective mark-compacts near heap limit Allocation failed - Javascript heap out of memoryこれを回避するには
--max_old_space_size={MB}
を Node.js の引数として設定してあげればいいらしい。npm scripts で Webpcak を使ってる場合はこんな感じ。
例{ "dev": "cross-env NODE_OPTIONS=--max_old_space_size=2048 webpack" "dev2": "node --max_old_space_size=2048 node_modules/webpack/bin/webpack.js" }参考:
- webpack-dev-server and JavaScript heap out of memory · Issue #1433 · webpack/webpack-dev-server
- yarn serve - JavaScript heap out of memory crash · Issue #1453 · vuejs/vue-cli
- Angular 7/8 FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory · Issue #13734 · angular/angular-cli
- Best way to set --max-old-space-size when running npm? · Issue #12238 · npm/npm
ただ記載されているのが
--max-old-space-size
だったり--max_old_space_size
だったりして、どっちが正しいのか分からないしV8も意図的に落とせないので効果が確認しづらい。Node.js の--help
を見ても両方とも載ってないので、効いてるのかどうか分からない…。ちょっと古いけど、詳細な設定はこちらの記事を参考にするとよさそう。
2016年版 Node.jsで幸せになれる10の習慣 - Qiita
- 投稿日:2019-08-20T17:13:42+09:00
ESLint v6.2.0
前 v6.1.0 | 次 (2019/08/31 JST)
ESLint 6.2.0 has been released: https://t.co/L7srPm1jkE
— ESLint (@geteslint) August 18, 2019
This release adds support for parsing ES2020 features (bigint, dynamic import) using the default parser! Please give it a try and let us know if you see any issues.ESLint
6.2.0
がリリースされました。お盆休み中に ESTree 仕様が更新されたので、BigInt と Dynamic Imports 構文をサポートしました。
既知の問題:
babel-eslint
を利用している場合、変数の利用判定が変になる。これはbabel-eslint
の対応待ちです (過去 ESLint 5.0.0 で実施された Breaking Changes に関わる問題であるため)。- npmで更新したとき、JSXの解析がうまくいかなくなる場合がある。npm の不具合によるものです。一度
node_modules
とpackage-lock.json
を削除して再インストールしてみてください。それでも解決しない場合、package.json
のdevDependencies
に"acorn": "^7.0.0"
を追加し、node_modules
とpackage-lock.json
を削除して再インストールしてみてください。質問やバグ報告等ありましたら、お気軽にこちらまでお寄せください。
? 本体への機能追加
BigInt と Dynamic Imports をサポートしました。
これらを利用するには、
env.es2020
設定と、(デフォルトのパーサーでは)parserOptions.ecmaVersion
設定を指定します。.eslintrc.json{ "parserOptions": { "ecmaVersion": 2020 }, "env": { "es2020": true } }
parserOptions.ecmaVersion
設定により、新しい構文 (import("source")
や100n
) が有効になります。env.es2020
設定により、新しいグローバル変数 (BigInt
,BigInt64Array
,BigUint64Array
) が有効になります。設定ファイルに
noInlineConfig
プロパティが追加されました。.eslintrc.json{ "noInlineConfig": true }この設定は
--no-inline-config
CLI オプションとほぼ同等です。今まで CLI でしか指定できなかったものが設定ファイルでも指定できるようになりました。? 新しいルール
function-call-argument-newline
関数呼び出しの各実引数の間に改行を入れるかどうかを矯正するスタイル ルールが追加されました。
例/* eslint function-call-argument-newline: [error, consistent] */ //✘ BAD foo(a, b, c); //✔ GOOD foo(a, b, c); foo( a, b, c );? オプションが追加されたルール
特になし。
✒️
eslint --fix
をサポートしたルール特になし。
⚠️ 非推奨になったルール
特になし。
- 投稿日:2019-08-20T14:18:18+09:00
Macでnodenvで管理しているnpmで入れたモジュールにパスを通す
この記事を書いたきっかけ:
Node.jsをnodebrewで管理していたのをやめ、nodenvでインストールし直したが、npmでグローバルインストールしたモジュールにアクセスできなくて困ったから
参考: nodebrew管理からnodenv管理への移行ははこちらを参考に行いました
注意:上記記事ではanyenvではなく、
git
経由でnodenvがクローンされています。anyenv経由でnodenvをインストールする方法も調べると出てきます。前提
- Node.jsをanyenvのnodenvで管理している
- nodenvのバージョン:
1.1.2-1-g18489d7
- Node.jsのバージョン:
9.11.1
- npmのバージョン:
5.6.0
実際の手順
作業の順番に沿って説明します。
npmがnodenvで管理されたNode.jsのものであることを確認する
nodenvでのNode.jsのインストールは完了していると考えます。
Node.jsをインストールした際に自動的にnpmもインストールされています。npmがnodenvで管理されたNode.jsのものであることを確認します↓
$ which npm /Users/{your_user_name}/.anyenv/envs/nodenv/shims/npm
/usr/local/bin
などが表示された場合、nodebrewなどを利用してインストールされていると思われます。npmのパスが通らない場合
.bash_profile
に以下の記述を追加します
zshを使用している場合は書き込み先を.zshrc
にするなど、適宜読み替えてください。
- 直接編集する
bash_profileexport PATH="$HOME/.anyenv/envs/nodenv/bin:$PATH"
- echoする
$ echo 'export PATH="$HOME/.nodenv/bin:$PATH"' >> ~/.bash_profile
- 更新する
$ source ~/.bash_profileでは、このnodenv配下のnpmでモジュールをグローバルインストールします。
どのNode.jsのnpmか確認する
npmでグローバルインストールする場合は、nodenvでグローバルに設定したNode.jsのnpmを使うほうがいいと思います。nodenvで複数の環境を管理している場合は特に注意です。
- nodenvでNode.jsのバージョン管理をしているか確認する
$ nodenv versions 8.11.1 * 9.11.1 (set by /Users/{your_user_name}/.anyenv/envs/nodenv/version)ローカルバージョンを参照している場合、参照先のファイルが
$ nodenv local {バージョン番号}
実行時に作成されたファイル.node_version
になります。$ nodenv versions * 8.11.1 (set by /{where_your_locally_set_node_is}/.node-version) 9.11.1グローバルバージョンが設定されていない場合
- Node.jsにグローバルバージョンを設定する
$ nodenv global {バージョン番号}npmでモジュールをグローバルインストールする
今回は例として
aws-cdk
というモジュールをインストールしようとしていますが、適宜読み替えてください。
- npmで
aws-cdk
をグローバルインストールする$ npm install -g aws-cdk /Users/{your_user_name}/.anyenv/envs/nodenv/versions/9.11.1/bin/cdk -> /Users/{your_user_name}/.anyenv/envs/nodenv/versions/9.11.1/lib/node_modules/aws-cdk/bin/cdk + aws-cdk@1.4.0 updated 1 package in 10sインストールできたっぽいです。
モジュールのコマンドを確認する
$ cdk -bash: cdk: command not found # そんなコマンドねえよと怒られます $ which cdk # 反応なしはい、通っていません。
先ほどnpmインストールした時に
/Users/{your_user_name}/.anyenv/envs/nodenv/versions/9.11.1/bin/cdk -> /Users/{your_user_name}/.anyenv/envs/nodenv/versions/9.11.1/lib/node_modules/aws-cdk/bin/cdkとありましたので、このディレクトリに向かってパスを通しました。
- 直接編集する
.bash_profileexport PATH="$HOME/.anyenv/envs/nodenv/versions/*/bin:$PATH"
- echoする
$ echo 'export PATH="$HOME/.anyenv/envs/nodenv/versions/*/bin:$PATH"' >> ~/.bash_profile
- 更新する
$ source ~/.bash_profile今度こそパスが通っているか確認します。
コマンドが通っているか確認します。
$ cdk Usage: cdk -a <cdk-app> COMMAND # (略) $ which cdk /Users/{your_user_name}/.anyenv/envs/nodenv/shims/cdk通りました!