はじめに
こんにちは!qiita初投稿です。
自分は組み込み系を2年くらいやっているプログラマーです。
仕事では主にvisual c++ や c#.netを使ってます。
元々web系に興味があったので、組み込み系で行ったデスクトップアプリ制作の経験が活かせるelectronを勉強しています。
ある程度勉強して、node-lameというライブラリを使ってwavファイルをmp3にエンコードするちょっとしたアプリを作ってみたので解説してみます。
node-lameとは
lameというオープンソースのエンコーダーをnodejs環境で使えるようにしたライブラリのようです。
wavやmp2をmp3にエンコードしたり、デコードしたりと音声ファイルの変換ができるみたいです。
(node-lame公式画像)
wavなどの音声ファイルはヘッダー部分、データの部分とフォーマットが決まっていて、プログラムで読み込むときはヘッダーがどこまでか、データ部はどんな形式でサイズはどうなのかを考えて読み込むことになります。
データを正確に読み込むのはかなり大変でそれを変換するとなると一つなにかがずれるだけでエラーが起きたりしてかなり大変です。
このライブラリを使うだけで安全に読み込んでくれるのでかなり便利ですね。
基本的な使い方
エンコードのサンプルコードをちょこっと解説します。
1.まずrequireでnode-lameを読み込む
const Lame = require("node-lame").Lame;
2.出力先のパスとファイル名、ビットレートなどを設定してインスタンスを作成する
output:のあとにパスとファイル名を設定します。ここに適当な変数をセットしておくと、guiでユーザーが設定したパスとかを使えますね。
const encoder = new Lame({
output: "./audio-files/demo.mp3",
bitrate: 192,
}).setFile("./audio-files/demo.wav");
3.encode()またはdecode()で変換する
then()で異常系を書いておくと、成功したら「エンコードが終わりました」的なメッセージを出して、失敗したらエラーメッセージを出したりできますね。
encoder
.encode()
.then(() => {
// Encoding finished
})
.catch((error) => {
// Something went wrong
});
作ったもの
electronといえば、atom,vscodeなどですね。
組み込み系のプログラマーとしてはラズベリーパイのosの焼き込みに仕えるetcherがelectronを使ったソフトとして思い浮かびます。
etcherのUIはすごくシンプルで好きなので、etcherを参考にシンプルなUIを作ってみました。
githubリポジトリ
完全に見た目通りです。「SELECT WAV FILES」でwavファイルをダイアログで選択します。
それから 「ENCODE TO MP3!」 をクリックしたら選択したwavファイルがmp3に変換されて、出力先のパスに保存されます。
ソース
大まかな動作の流れはmainWindow.htmlからボタンの入力をmain.jsが受け取り、ダイアログを開いたり、変換をする。
変換が上手くいったらメッセージを表示するです。
main.js
const electron = require("electron");
const url = require('url');
const Lame = require("node-lame").Lame;
const {app, BrowserWindow, ipcMain, dialog, Menu} = electron;
const path = require('path');
let { cnvfilename,filename} = '';
let mainWindow;
app.on('ready', () => {
mainWindow = new BrowserWindow({
width: 650,
height: 500,
webPreferences: {
nodeIntegration: true,
contextIsolation: false
}
});
// Load html into window
mainWindow.loadURL(url.format({
pathname: path.join(__dirname, 'mainWindow.html'),
protocol:'file:',
slashes: true
}));
// Quit app when closed
mainWindow.on('closed', function(){
app.quit();
});
mainWindow.removeMenu();
});
// Catch Convert
ipcMain.on('Convert',function(e){
// Replace wav to mp3 (WIP)
filename = filename.replace('wav', 'mp3');
// Set output location
const output = "./output/" + filename;
// Set target file by path
const encoder = new Lame({
output: output,
bitrate: 128,
}).setFile(cnvfilename);
// Encode by node-lame
encoder.encode()
.then(() => {
// Encoding finished
console.log("success");
e.reply('convert-reply', 'complete!')
})
.catch((error) => {
// Something went wrong
console.log(error);
});
});
// File-open dialog
ipcMain.handle('file-open', async (event) => {
const filepaths = dialog.showOpenDialogSync(mainWindow, {
buttonLabel: 'open',
filters: [
{ name: 'Audiofiles', extensions: ['audiofiles', 'wav'] },
],
properties:[
'openFile',
'createDirectory',
]
});
// when closes dialog without opening a file
if( filepaths === undefined ){
return({status: undefined});
}
// get files contents
try {
const filepath = filepaths[0];
cnvfilename = filepath;
filename = path.basename(filepath);
return({
status: true,
path: path,
name: filename
});
}
catch(error) {
return({status:false, message:error.message});
}
});
mainWindow.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>AudioConv</title>
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link rel="stylesheet" href="./css/main.css">
</head>
<body>
<div class="container">
<form>
<div class="row pt-160">
<div class="col s6 center-align">
<i class="medium material-icons icon-white">add_box</i>
<pre class="m-12" id="input-file"> </pre>
<button id="filesSelect" type="button" class="waves-effect waves-light btn">Select Wav files</button>
</div>
<div class="col s6 center-align">
<i class="medium material-icons icon-white">cached</i>
<pre class="m-12" id="after-convert"> </pre>
<button id="convert" type="button" class="waves-effect waves-light btn">Encode to MP3!</button>
</div>
</div>
</form>
</div>
<script>
const electron = require('electron');
const { ipcRenderer } = electron;
// Get html elements
const form = document.querySelector('form');
const BtnFilesSelect = document.getElementById('filesSelect');
const BtnConvert = document.getElementById('convert');
// Adding Eventlistner to each button
BtnFilesSelect.addEventListener('click', filesSelect);
BtnConvert.addEventListener('click', convert);
// File open dialog event
function filesSelect(e){
ipcRenderer.invoke('file-open')
.then((result) => {
if(result.status == undefined){
return(false);
}
if(!result.status){
alert('Could not open the file\n${result.message}');
return(false);
}
document.getElementById('input-file').innerHTML = result.name;
})
}
// Convert button
function convert(e){
ipcRenderer.send('Convert');
}
// Show complete message when converting is finished
ipcRenderer.on('convert-reply', (e, message) => {
document.getElementById('after-convert').innerHTML = message;
})
</script>
</body>
</html>
今後やりたいこと
とりあえずまずは変換できるファイルを増やしたいですね。
それからまだipcRendererやipcMainの仕様をしっかり把握していないのでその辺を掘り下げていきたいですね。
↧
node-lameを使ってelectronでwav→mp3に変換するデスクトップアプリを作ってみた
↧
npmで管理しているライブラリのバージョンアップ手順まとめ
概要
npmで管理しているライブラリのバージョンアップ方法をまとめていきます。
また、今回は何かサンプルのプロジェクトを利用し、結果を見ていくとわかりやすいと思うので、https://github.com/creativetimofficial/vue-notus こちらを利用し下記の手順を試しながら結果を記載していきます。
ローカル環境のnpmバージョンを確認
最新のversionになっていることを確認します。
最新になっていなければversionをlatestまで上げてからバージョンアップを行うのが良いです。
❯ npm --version
7.6.3
現在のライブラリのversionを確認
npm outdatedコマンドで現在のライブラリのバージョン、マイナーバージョンがどのくらい上がるのかを確認します。
npm outdated説明
Current:現在インストールされているバージョン
Wanted:存在するバージョンのうち、 package.json に記載された semver 条件を満たす最新のバージョン
Latest:そのパッケージの最新バージョン
❯ npm outdated
Package Current Wanted Latest Location Depended by
@babel/core 7.13.10 7.13.10 7.13.14 node_modules/@babel/core vue-notus
@babel/eslint-parser 7.13.10 7.13.10 7.13.14 node_modules/@babel/eslint-parser vue-notus
@popperjs/core 2.9.1 2.9.1 2.9.2 node_modules/@popperjs/core vue-notus
@tailwindcss/forms 0.2.1 0.2.1 0.3.2 node_modules/@tailwindcss/forms vue-notus
@vue/cli-plugin-babel 5.0.0-alpha.7 5.0.0-alpha.7 4.5.12 node_modules/@vue/cli-plugin-babel vue-notus
@vue/cli-plugin-eslint 5.0.0-alpha.7 5.0.0-alpha.7 4.5.12 node_modules/@vue/cli-plugin-eslint vue-notus
@vue/cli-service 5.0.0-alpha.7 5.0.0-alpha.7 4.5.12 node_modules/@vue/cli-service vue-notus
@vue/compiler-sfc 3.0.7 3.0.7 3.0.11 node_modules/@vue/compiler-sfc vue-notus
chart.js 2.9.4 2.9.4 3.0.2 node_modules/chart.js vue-notus
core-js 3.9.1 3.9.1 3.10.0 node_modules/core-js vue-notus
eslint 7.22.0 7.22.0 7.23.0 node_modules/eslint vue-notus
eslint-plugin-vue 7.7.0 7.7.0 7.8.0 node_modules/eslint-plugin-vue vue-notus
gulp-append-prepend 1.0.8 1.0.8 1.0.9 node_modules/gulp-append-prepend vue-notus
postcss 8.2.8 8.2.8 8.2.9 node_modules/postcss vue-notus
tailwindcss 2.0.4 2.0.4 2.1.1 node_modules/tailwindcss vue-notus
vue 3.0.7 3.0.7 2.6.12 node_modules/vue vue-notus
vue-router 4.0.5 4.0.5 3.5.1 node_modules/vue-router vue-notus
バージョンのアップデートを行う(今回は、マイナーバージョンのみアップデートを実施します。)
npm-check-updatesというライブラリをグローバルにインストールしncuコマンドで、メジャーバージョンは固定、マイナーバージョンのみ最新にします。
なぜ、npm updateコマンドを利用しないのかというと、npm updateコマンドでは、package.jsonの書き換えは行ってくれないためです。
npm-check-updatesのインストール方法
npm i -g npm-check-updates
npm-check-updatesを利用し、マイナーバージョンのみアップデートを実施
❯ ncu -u --target minor
Upgrading /Users/yoshitaka.koitabashi/Desktop/vue-notus/package.json
[====================] 21/21 100%
@popperjs/core 2.9.1 → 2.9.2
@tailwindcss/forms 0.2.1 → 0.3.2
@vue/compiler-sfc 3.0.7 → 3.0.11
core-js 3.9.1 → 3.10.0
gulp-append-prepend 1.0.8 → 1.0.9
tailwindcss 2.0.4 → 2.1.1
vue 3.0.7 → 3.0.11
vue-router 4.0.5 → 4.0.6
@babel/core 7.13.10 → 7.13.14
@babel/eslint-parser 7.13.10 → 7.13.14
@vue/cli-plugin-babel 5.0.0-alpha.7 → 5.0.0-alpha.8
@vue/cli-plugin-eslint 5.0.0-alpha.7 → 5.0.0-alpha.8
@vue/cli-service 5.0.0-alpha.7 → 5.0.0-alpha.8
eslint 7.22.0 → 7.23.0
eslint-plugin-vue 7.7.0 → 7.8.0
postcss 8.2.8 → 8.2.9
Run npm install to install new versions.
package.jsonが更新されたので、その状態でnpm install コマンドを実行
❯ npm install
up to date, audited 1580 packages in 3s
117 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
もし、npm installでerrorを吐く場合
依存関係が解決できずエラーになってしまった場合は、npm audit fix --forceコマンドで自動的に修正してくれます。
> npm audit fix --force
アップデート後のライブラリのバージョンを確認
npm lsコマンドでライブラリのバージョンが上がったことを確認します。
❯ npm ls
vue-notus@1.1.0 /Users/yoshitaka.koitabashi/Desktop/vue-notus
├── @babel/core@7.13.14
├── @babel/eslint-parser@7.13.14
├── @fortawesome/fontawesome-free@5.15.3
├── @popperjs/core@2.9.2
├── @tailwindcss/forms@0.3.2
├── @vue/cli-plugin-babel@5.0.0-alpha.8
├── @vue/cli-plugin-eslint@5.0.0-alpha.8
├── @vue/cli-service@5.0.0-alpha.8
├── @vue/compiler-sfc@3.0.11
├── autoprefixer@10.2.5
├── chart.js@2.9.4
├── core-js@3.10.0
├── eslint-plugin-vue@7.8.0
├── eslint@7.23.0
├── gulp-append-prepend@1.0.9
├── gulp@4.0.2
├── postcss@8.2.9
├── tailwindcss@2.1.1
├── vue-router@4.0.6
├── vue-template-compiler@2.6.12
└── vue@3.0.11
ライブラリの監査を見れるので結果を確認
npm auditコマンドでライブラリの監査が行えるのでその結果を確認します。
❯ npm audit
found 0 vulnerabilities
依存関係の監査結果で脆弱性がSeverity: highのものがあった場合の対応
npm audit fixコマンドを実施して依存関係の脆弱性対応を自動で行うことができます。
> npm audit fix --force
↧
↧
dockerコンテナ内でts-node-devのホットリロードを有効にする
結論
dockerコンテナ内でts-node-devのホットリロードを有効にするためには --poll オプションを付ける必要がある。
$ ts-node-dev --poll ./src/bin/www.ts
(起動用のファイルbin/www.tsへのパスはディレクトリ構成に応じて書き換えてください。拡張子.tsは省略可)
もう少し詳しく
dockerのNode.jsコンテナ内で、アプリケーションの雛形をexpress-generatorで作りTypeScriptに書き換えた。
開発時にコードを書き換えるたびTSからJSにコンパイルし再起動するのは面倒。
ts-node-devをつかうとコンパイルせずにTSのまま直接起動し、コードを変更したときには再起動してくれる。
ts-node-devをインストールする
$ yarn add -D ts-node-dev
スクリプトを追加する
package.json
"scripts": {
"dev": "ts-node-dev ./src/bin/www.ts" // .tsは省略可
}
ts-node-devで起動する
$ yarn dev
起動したが、コードを変更しても再起動されない。
スクリプトに--pollオプションを追記する
package.json
"scripts": {
"dev": "ts-node-dev --poll ./src/bin/www.ts"
}
再びyarn devで起動後、コードを変更してみると再起動され、変更内容が反映されていた。
↧
Node.js管理ツールの更新頻度とスター数を比較してみた
概要
Node.jsのバージョン管理ツールについて調べたところ、nvm、nodebrewなど色々存在しており、
なにを使えば正解なのかわからなかったので、Gitリポジトリの最終コミット日付とコミット数とスター数で比較してみました。
※2020/04/07時点
結論
1.nvm
現在、最もコミット数が多く、今なお開発が続いていることから、nvmがおすすめです。
スター数も47.6kと、他のNode.js管理ツールと比較してダントツで獲得数が多いです。
2.n
スター数は、nvmに及ばないものの、こちらも現在開発が続いております。
nvmはみんな使ってるから、別のツールを使ってみたいという方は、nをおすすめします。
nに関しては、参考記事が見つからなかったので実際にインストールして試してみました。
n
Node.js管理ツールまとめ
※以下に列挙した以外にもあるかもしれません。
※最終コミットの最新順でソートしています。
Node.js管理
コミット数
最終コミット
スター数
nvm
1980
2021年3月30日
48k
n
681
2021年3月12日
14.4k
nodenv
943
2020年7月22日
1.5k
nave
228
2020年5月30日
1.5K
nodebrew
219
2019年1月7日
961
nodist
441
2019年3月30日
1.3k
ndenv
13
2018年12月27日
313
nvm
コミット数:1980
最終コミット:2021年3月30日
スター数:48k
n
コミット数:681
最終コミット:2021年3月12日
スター数:14.4k
nodenv
コミット数:943
最終コミット:2020年7月22日
スター数:1.5k
nave
コミット数:228
最終コミット:2020年5月30日
スター数:1.5k
https://github.com/isaacs/nave
nodebrew
コミット数:219
最終コミット:2019年1月7日
スター数:961
nodist
コミット数:411
最終コミット:2019年3月30日
スター数:1.3k
ndenv
コミット数:13
最終コミット:2018年12月27日
スター数:313
↧
PuppeteerでサイトをクロールしてURLリストを作るツール
はじめまして。Webサイトのリニューアルとか新規構築とかやってる世にいうWebディレクター?PM?的な役割をよくやるおじさんです。
おじさんはよく数百から数千ページのWebサイトの新規構築・リニューアルPJを担当したりします。提案やら見積もりの断面から参画することが多く、だいたいサイト規模を図るところから入るんですが。担当者によっては適当にサイト規模の見積もりをして、後からこんなでかいサイトだと思わなかったなんて話になります。
古のツールとしてWebsite Exploreなんてものがあり、未だにこれ使ってページ数算出している人もよく見かけます。
今どきキラキラしたheadless chromeとか色々あるんだからもっとスマートにできないの?と思っていたところ、まとまった自分の時間が取れたので便利そうなのを作ってみました。そしてgithubで公開してみました。
前提として
おじさんは前時代的なWebサイト構築の時代を生きてきて、本格的にコードを書かなくなって約10年。アラフォーでなんか色々間違っていると思うんですが何事も経験なので、こうしてQiita記事も初めて書いてみました。
では、何を作ったのか書きますね。と思ったんですがめんどくさいのでREADMEをほぼそのまま載せますね。
これは何?
Web サイトリニューアルの際等に現行サイトに sitemap.xml が無く、サイト規模が全くわからない場合があります。そんな時に使うツール。
任意の URL から a タグ href 属性を辿り、存在する URL(a タグリンクが繋がっている URL) をリスト化します。
puppeteer を使って a タグを巡り URL をリスト化、エクセルファイルとして出力
title,description,charset 等基本的なページ情報もついでに取得してエクセルファイル内に出力
クロールした際の HTML コードもついでにテキストファイルとして出力
puppeteer 越しに headless chrome の描画結果 a タグを走査するので、js 等で出力されている a タグリンクも巡ることが可能
※対象 URL にはそれなりのアクセス負荷がかかるので、サイト管理者の許可なく本ツールを使用しないでください
実行方法
下記で node パッケージインストール
npm i
conf.yaml を設定したうえで下記の様に実行
node salvage.js
conf.yaml に記載の startUrl を起点として a タグリンクを辿り、url リストを作成する。URL リストはエクセルファイルとして出力されます。
conf.yaml 設定内容
startUrl
クロールの起点となる URL の指定
通常はサイトのトップページ等を指定する
複数指定可能
allowDomain
a タグを辿る際に許可するドメイン
基本的には startUrl に指定した URL のドメインを指定する
複数指定可能
basicAuthentication
クロール対象サイトに BASIC 認証がかかっている際にコメントアウトを解除し使用
loadBlockFileExtention
クロールをする際にロードをブロックするファイル
クロール速度を高速化するために画像等の読み込みをブロックすることを推奨
emulateDevice
UA 判定等でスマホ UA を使いたい場合等はコメントアウトして使用
(https://github.com/puppeteer/puppeteer/blob/main/src/common/DeviceDescriptors.ts のデバイスを指定可能)
コメントアウトした状態では puppeteer デフォルトの UA でアクセスする(chrome)
結果出力
result ディレクトリ内に結果が出力されます
出力例
result
└── 20210407151539483
├── htmlcode
│ ├── https:__example.com_.txt
│ ├── https:__example.com_business.html.txt
│ ├── https:__example.com_en_.txt
│ ├── https:__example.com_en_business.html.txt
│ ├── :
│ └── https:__example.com_about.html.txt
└── result.xlsx
result.xlsx の出力内容
url
URL
status
クロールした際の HTTP ステータスコード
conf.yaml の loadBlockFileExtention に指定された拡張子の URL は"SKIP"として出力
title
title タグ内文言
description
meta[name="description"]の content 値
keywords
meta[name="keywords"]の content 値
canonical
link[rel="canonical"]の href 値
viewport
viewport 指定
charset
document.charset の値
おわりに
それなりにサーバ負荷かかると思うので、100ページ位のサイトでしか試せてない
誰か実戦投入として大きめのサイトで試してみてほしい(もちろんサイト管理者に許可とったうえで)
ソースコードはネット上の色んなとこからコピペしたりしているので、全然きれいに書けてない。
誰か今どきなキラキラしたコードに書き換えてほしい
あとスクショ撮ったり各ページで読み込んでるアセットファイルとかをまるっとダウンロードするツールとか作りたいなー
↧
↧
npm と yarn と pnpm 比較(2021年4月版)
3者の公式
概要
3者ともJavascriptのパッケージマネージャー。
npm はNode.jsをインストールすれば一緒にインストールされる。
yarn: npmと互換性があり、npmで使用していたプロジェクト設定ファイル(package.json)がそのまま使える。
pnpm: 同じくnpmと互換性があり、ディスクスペースの使用量と速度が大幅に改善されている。
先に npmとyarnとpnpmの違い2021 からわかりやすい結論。
筆者のおすすめ
初心者、もしくは複数人開発であればnpm をおすすめします。
標準ツールのため、Nodeと一緒に複数人でバージョンを揃えやすい
nodeを入れれば追加でのインストールが不要
標準ツールのため、信頼性があり、ドキュメントも多い
現在はインストールがそこまで遅くはない
開発でパッケージマネージャーを触ることは最初期や機能追加以外は少ない
個人開発であればpnpmかYarn(v1) をおすすめします。
パッケージのインストール、アンインストールが早く、初期の試行錯誤がしやすい
pnpmではnode_modulesのサイズが小さくなり、容量を圧迫しない。
3者の特徴
より翻訳および引用しての箇条書き。
npm
Node Package Manager。2009年にNode.jsがリリースされた翌年にリリースされた。
package-lock.jsonファイルを自動的に生成する。バージョンコントロールシステムにコミットすると便利。他の開発者がローカルマシンに依存関係を簡単にインストールできる。
ローカルまたはグローバルな依存関係を簡単に管理。
複数のバージョンの依存関係を扱うのに十分な機能。
pypiやrubygems、packagistよりも多くのパッケージを持つ公式レジストリを持っている。npm社はGitHubが買収し、Microsoftの孫会社。
補足: package-lock.json
依存パッケージが依存するパッケージ(ネストした依存状態)のバージョン情報が変わる場合がある。
package.jsonだけでは、node_modulesを完璧に再現できるとは限らない(勝手に違うバージョンのライブラリがインストールされてしまう可能性)
package-lock.jsonはバージョン情報をすべて正確に記録する
package-lock.json に書き込まれたバージョンのパッケージがインストールされる
yarn
2016年にリリース。
npmと比べてインストールが速い、セキュリティが高い。セキュリティが高いというのは、インストール時にパッケージが不正に変更されていないかなどをチェックサムを用いて検証することができ、安全なパッケージのインストールが可能であるということ。
例えば、同じリポジトリの下で複数のパッケージを管理していて、それらがすべて個別のpackage.jsonファイルを持っている場合、リポジトリ内のすべてのパッケージの依存関係を一度にインストールすることができ、すべてのパッケージを簡単に更新することができる。npmの場合は、各パッケージフォルダ内でnpm installコマンドを手動で実行する必要がある。
オフラインキャッシュの仕組みを利用している。つまり、パッケージを初めてインストールすると、Yarnはそのパッケージを~/.yarn-cacheの下にあるキャッシュフォルダに追加する。これによりnpmと比較してYarnのパフォーマンスを大幅に向上させている。
yarn.lockというロックファイルを利用しているので、プロジェクトはすべてのチームメイトに対して正しく動作する。決定論的インストールアルゴリズムとも呼ばれている。
アプリケーションを開発する際のさまざまな場面で便利なライセンスチェッカーが組み込まれている。
npmとは異なり、Yarnはパラレルダウンロードと呼ばれるアプローチを採用している。これにより、Yarnはより多くのリソースを利用してビルドプロセスを高速化することができる。
Yarnは、HTTPリクエストに失敗した場合、自動的に再試行することができる。
pnpm
リリースはyarnとあまり変わらない。
すべてのパッケージを1つの場所にインストールし、シンボリックリンクを使って参照する。複数のプロジェクトに同じモジュールの同じバージョンをインストールする場合二重インストールしない。
content-addressable storage systemと呼ばれる全く新しい概念を導入し、ファイル間の違いを検出できるようにしている。これにより、2つの異なるバージョンのパッケージに、変更されていないファイルを複製することがなくなった。
これらのためインストールの高速化とディスク使用容量の効率化が望める。
最新版の5.8.0では、Yarn-bashのような新しい設定であるshell-emulatorが導入されており、これはクロスプラットフォームのシェル環境である。
厳格なアクセスコントロールメカニズムを持っており、パッケージはpackage.jsonファイルで定義された依存関係にのみアクセスすることができる。
ただし、npmとyarnでは対応していてもpnpmには標準対応していない場合がある。
3者のベンチマーク
引用: https://github.com/pnpm/benchmarks-of-javascript-package-managers
The app's package.json here
action
cache
lockfile
node_modules
npm
pnpm
Yarn
Yarn PnP
install
51s
14.4s
39.1s
29.1s
install
✔
✔
✔
5.4s
1.3s
707ms
n/a
install
✔
✔
10.9s
3.9s
11s
1.8s
install
✔
33.4s
6.5s
26.5s
17.2s
install
✔
28.3s
11.8s
23.3s
14.2s
install
✔
✔
4.6s
1.7s
22.1s
n/a
install
✔
✔
6.5s
1.3s
713ms
n/a
install
✔
6.1s
5.4s
41.1s
n/a
update
n/a
n/a
n/a
5.1s
10.7s
35.4s
28.3s
まとめ
安定性で npm。機能性、パフォーマンスで yarn あるいは pnpm。
以上参考になればさいわいです。
↧
DockerでNode.js+PostgreSQLの環境を構築する
はじめに
Docker上でNode.js(Express)とPostgreSQLの環境を構築しようとしたのですが、正しく動作する簡潔な記事が見当たらなかったので、本記事を投稿します。
データベースの情報を取得するWebアプリケーションを作成し、実際にデータを追加してみて正しく動作することの確認を行っていきます。
環境概要
Webサーバー (Node.js)
image : node:15-slim
データベース (PostgreSQL)
image : postgres:13
プロジェクト
ディレクトリ構成
project/
├─app/ # Node.jsアプリケーション
│ ├─node_modules/
│ ├─Dockerfile
│ ├─index.js
│ ├─package.json
| └─yarn.lock
├─initdb/ # PostgreSQL初期化ファイル
│ └─setup.sql
└─docker-compose.yaml
docker-compose
下記のように記載します。
PostgreSQLのデータはdb_dataボリュームで永続化しています。
docker-compose.yaml
version: "3"
services:
node:
container_name: node_express
build: ./app
volumes:
- ./app:/app
tty: true
ports:
- 3000:3000
postgres:
container_name: postgres
image: postgres:13
ports:
- 5432:5432
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: password
POSTGRES_DB: postgres_db
volumes:
- db_data:/var/lib/posrgresql/data
- ./initdb:/docker-entrypoint-initdb.d
volumes:
db_data: {}
app:Node.jsアプリケーション
Expressを使用して、PostgreSQLのデータを取得するWebアプリケーションを作成します。
index.js
const express = require('express');
const app = express();
// PostgreSQLの設定
const { Pool } = require('pg')
const pool = new Pool({
user: 'postgres',
host: 'postgres',
database: 'postgres_db',
password: 'password',
port: 5432,
})
// ルーティングの設定
app.get('/', async(req, res) => {
const { rows } = await pool.query('select * from users')
res.send(rows)
});
const port = 3000;
app.listen(port, () => {
console.log(`server started on port ${port}`);
});
pacakge.jsonは下記のように手書きするか、npm initなどで作成します。
package.json
{
"name": "app",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node index.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.17.1",
"pg": "^8.5.1"
}
}
Dockerfileを下記のように作成し、ビルド時に必要なパッケージをインストールして起動するようにします。
Dockerfile
FROM node:15-slim
RUN yarn install
WORKDIR /app
CMD ["yarn", "start"]
initdb:PostgreSQL初期化ファイル
postgresイメージでは、初期化時にdocker-entrypoint-initdb.d内のsqlファイルが実行されるため、ここで初期化を行います。
Node.jsアプリケーション内でも記載していますが、usersというテーブルをこのファイル内で作成します。
setup.sql
set client_encoding = 'UTF8';
create table users(
id serial primary key,
name varchar not null,
age integer not null
)
動作確認
コンテナの立ち上げ
docker-composeコマンドでコンテナを立ち上げます。
docker-compose up
http://localhost:3000 にブラウザでアクセスすると、空のデータが取得できていると思います。
データの追加
postgresコンテナに入ってデータを追加してみましょう。
下記コマンドで実行中のpostgresコンテナに入れます。
docker exec -i -t postgres bash
ターミナルに入れたら、psqlコマンドでPostgreSQLに接続します。
psql -U postgres -d postgres_db
この状態でSQLコマンドを入れれるようになるので、下記コマンドを実行します。
insert into users (name, age) values ('MY NAME', 20);
再度http://localhost:3000 にブラウザでアクセスすると、先ほど追加されたデータが帰ってきます。
おわりに
Docker上でNode.jsとPostgreSQLの環境を構築し、実際に動作確認を行いました。
↧
重い腰を上げて、NPMの取りこぼしを回収する
zennからの転載です。
概要
npm をなんとなく使って来ましたが、実は色々と機能が豊富なので、この期に取りこぼしを回収するべく少し調べてみました。取りこぼしそうな部分をまとめたいと思います。
npmとは
Node.jsのパッケージ管理ツール。自身もJSで記述されており、Node.jsのリリースに含まれています。
2020年にGithubが買収されています。
日本人で一番コミットが多いのがwatildeさんの様です。
lockファイルの優先順位
npm-shrinkwrap.json
package-lock.json
yarn.lock
npmコマンド
公式を見ると意外にたくさんコマンドがあります。
パッケージの管理系
npm audit
実行すると、脆弱性が報告されているパッケージ・バージョンをレポートしてくれる。脆弱性が発見された場合はnpm audit fixで自動修正できる場合がある。自動修正されない場合は手動で修正する必要がある。
npm ci
CI環境などで使用する npm i。pcakage-lock.jsonがあって、node_modulesがない時に早いらしい。
試しに私のプロジェクトで実行したところ(ざっくりです)、
npm i ⇒ 7.8
npm ci ⇒ 7.0
あまり変わらない印象。ただCIを高速化したいのであれば、yarnやらpnpmを使うのも手だが、安全の為にnpmにだけ依存する選択もありうる。
npm dedupe
複数のパッケージが必要とするパッケージをそれぞれの配下でインストールするのでなく、必要とする全てのパッケージが参照できる位置までディレクトリ構造を遡って配置する。
node_modules/A/node_modules/C
node_modules/B/node_modules/C
=>node_moudles/C
現在は npm iを実行すると自然とdedepeしてくれる様子。試しにnpm ls --depth=3を実行すると、dedeupedの文字が散見されるはず。
npm find-dupes は npm dedupe --dry-run と同じ
npm prune
package.jsonに記載されていないパッケージをnode_modulesから削除する。
npm prune --produtionを実行すると、devDependancyに記載されているパッケージもnode_modulesから削除される為、ビルドする時に便利です。
ブラウザでパッケージの関連ページを開く便利系
打ってみて何が開くか確かめてください。
npm repo
npm home
npm docs
npm bugs
パッケージの実行系
npm exec
基本npxと同じ動作。npx内部で npm exec をcallしている様に見える。
違いは引数の渡し方。npx と違い -- を使って渡す。
npm explore
別プロセスで指定したパッケージ配下を開く。
# イメージ
$ npm i axios
$ npm explore axios
bash$ pwd
# => /path/to/node_modules/axios
exit;
## パラメータを指定するとただちに終了
npm explore axios -- git pull origin master
インストール状況の確認系
npm ls, (npm ll, npm laは出力が微妙に違う)
デフォでは1階層しか見えないので、 npm ls --all とか npm ls --depth=3とかすると深く見れる。v8で大幅な変更を予定している。
npm explain との違いはなんだろう?
npm outdated
更新のあるライブラリを一覧する。
ex)
bash
$ npm outdated
Package Current Wanted Latest Location Depended by
@babel/core 7.13.10 7.13.14 7.13.14 node_modules/@babel/core my-project
@babel/preset-env 7.13.10 7.13.12 7.13.12 node_modules/@babel/preset-env my-project
...
Current, Latestはわかると思いますが、Wantedはpackage.jsonの設定で許容される最新のバージョンです。
赤い出力はcurrent < watedなので、すぐにアップデートすることが推奨されるパッケージです。
パッケージの探索系
npm search
パッケージを文字列一致で検索する。 ex) npm search react
正気表現も使える。 ex) npm search /react-.*/
npm versions パッケージ名
バージョン一覧がみられる
new view パッケージ名
npmパッケージの詳細を確認する
NPMの設定系
npm root
インストールされるnode_modulesの位置を参照する。 npm prefix -gでグローバルの参照先を見る。
npm prefix (-g)はプロジェクトのパスを出力し、
npm bin (-g)は実行ファイルのパスを出力する。
package.jsonの管理系
npm install, npm uninstall, npm update
省略
npm set-script
npmスクリプトを追加する。
ex) npm set-script hoge 'npm run other command'
その他
npm hook
npmレジストリの変更をweb hookで通知を受けることができます。受け取るのにはサーバを立てる必要があ理ます。
実装の参考: https://github.com/npm/npm-hook-slack
npm link
ローカルで開発中の別レポをnode_modulesにインストールしたかのようにリンクさせる。
リンク元で、 npm link を実行するとグローバルにリンクが作成され、使用するプロジェクトで npm link パッケージ名すると、node_modulesの中にシンボリックリンクが生成される。
npm shrinkwrap
npm-shrinkwrap.jsonを生成する。npm-shirinkwrap.jsonは npm iの時に package-lock.json
より優先的に読み込まれます。
通常は package-lock.json を使用する為、あまり使用しないと思います。
NPMパッケージの開発者向け
npm publish
npmパッケージを公開する
など
package.json
main
最初に読まれるファイル。 axiosの mainは index.jsなので、 require('axios')すると node_modules/axios/index.jsが読み込まれる。
browser
クライアントサイド(ブラウザ)で使用することが想定されるパッケージの場合、mainではなく、browserにセットする。
bin
CLIツールの場合はbinに実行ファイルを指定する。コマンド名をつけることも可能。指定した名前でnode_modules/.binに保存される
{
"bin": {
"myapp": "./cli.js"
}
}
GUIツール
q-nick/npm-gui
720kb/ndm
どちらもパッケージの追加や、outdatedなパッケージの更新ができる模様ですが、npm scriptを実行したりと言う様な機能は無い模様。
参考
公式サイト
全部知ってる? npmを使いこなすために絶対知っておきたい10のこと
便利なnpmコマンド | スペースマーケットブログ
package.jsonの中身を理解する - Qiita
↧
Node.jsからOracleへ接続してSQLを実行する方法
虎の穴ラボのH.Hです。
以前作ったNode.jsで動くPuppeteerでWebサイトのテストをしていた際に、画面の動作と合わせてデータベースへの登録が正しく行われているかを確認する必要が出てきたため接続方法を調べたのでこちらにまとめました。
Puppeteerの利用方法はこちらをご覧ください。
WEBサイトへのアクセスと文言のチェックなどを行う仕組みが書かれています。
Puppeteerを使ってWebサイトの自動テストツールを作ってみた
条件
環境:MacBookPro
対象DB:Oracle
Node.js:バージョンv15.8.0
手順
1.Node.jsが動作するディレクトリを作成
動かすユーザーのホームディレクトリに以下のようにディレクトリを作成
puppeteerで使用するのでディレクトリを「puppeteer」としていますが、名前は任意なので用途にあった名前で問題ありません。
$ mkdir ~/workspace/auto_test/puppeteer
2.Node.jsのインストール
$ cd ~/workspace/auto_test/puppeteer
$ nodebrew install-binary latest
$ npm init
$ npm install --save puppeteer
(2021/2/4時点で最新バージョンはv15.8.0)
3.Oracle Instant Clientのインストール
公開されている手順はこちらに記載されています。
今回はManual Installationとして記載されている手順を実行します。
3.1.ダウンロードするClientを選択する
下記のサイトからOSに合うものをダウンロードします。
Instant Clientのダウンロード
今回はMacOSのものを選択します。ダウンロードは「Instant Client for Mac OS X (Intel x86) (32-bit and 64-bit)」のリンクの先の「Instant Client Package - Basic」で問題ありません。
(ダウンロードにはOracleプロファイルのアカウントが必要です)
3.2.dmgファイルをダウンロードする
上記のサイトからOracle Instant Clientのdmgファイルをダウンロードする
3.3.ダウンロードしたファイルをダブルクリックで開く
2021/2/8現在macOS向けは19.8が最新になります。
(OS毎にバージョンがバラバラなので注意が必要です)
3.4.インストール用のコマンドを実行する
下記のコマンドを実行する
$ /Volumes/instantclient-basic-macos.x64-19.8.0.0.0dbru/install_ic.sh
3.5.instantclientへのパスを通す
以下のコマンドで先ほど作成したディレクトリへのパスを通します。
以下のコマンドを実行してbash_profileに以下の内容を追記します。
(Macで動作を確かめる前にLinuxでも環境が構築できるかを確かめていたので、その際の設定と同じにするためにbash_profileに設定を記述しています)
$ vi ~/.bash_profile
export PATH=(ユーザーのホームディレクトリ)/Downloads/instantclient_19_8:$PATH
export LD_LIBRARY_PATH=(ユーザーのホームディレクトリ)/Downloads/instantclient_19_8:$LD_LIBRARY_PATH
4.oracledbのインストール
node.jsからoracleへ接続するためのモジュールをインストールします。
場所は(ユーザーのホームディレクトリ)/workspace/auto_test/puppeteerです。
コマンドは以下の通りです。
$ npm install oracledb
5.接続用の設定ファイルを準備する
(ユーザーのホームディレクトリ)/workspace/auto_test/puppeteer配下に設定用のファイルを作成します。
名前は任意で実行時のコードでパスを指定するので、場合によっては配下にディレクトリを作成しても問題ありません。
今回は配下にsettingというディレクトリを作成して、その中にdbconfig.jsという名前で作成します。
module.exports = {
user : "ユーザー名",
password : "パスワード",
connectString : "アドレス:ポート番号/スキーマ名",
externalAuth : process.env.NODE_ORACLEDB_EXTERNALAUTH ? true : false
};
6.Node.jsの実行ファイル
ここからNode.js上で実行され実際にSQLを実行する部分になります。
今回はSELECT文の実行を行う内容になります。
SQL文をsqlという変数で定義し、動的なパラメータはparameterで定義しています。
--例
SELECT * FROM table1 WHERE record_no=:record_no
:record_noの部分に動的に値をいれることができます。
parameterは配列です。
実行ファイルの名称は任意で設定可能です。ここではaction.jsとします。
const oracledb=require('oracledb');
(async () => {
const dbConfig = require('./setting/dbconfig.js');
try {
sql='SELECT * FROM table1 where record_no=:record_no';
parameter=[1];
connection = await oracledb.getConnection(dbConfig);
options = {outFormat: oracledb.OUT_FORMAT_OBJECT};
result = await connection.execute(sql,parameter, options);
//複数行も取れるので、ここからは取得したデータの加工などを行う
}catch(error){
console.log("ERROR"+error);
}finally{
await connection.close();
}
})();
7.実行
実行は以下のコマンドで可能です。
$ node action.js
8.まとめ
Node.jsからOracleに接続する手順について今回まとめました。注意点はoracledbを動かすためのOracle Instant ClientがOS毎に異なる点です。3の部分 で各OS用のファイルをダウンロードして、公式のGitHubのページの手順を行えばインストールすることが可能です。
(Linux環境の場合はzipファイルをダウンロードし、解凍してパスを通すことで完了しました)
Node.jsからOracleに接続する手順を日本語でまとめたページがあまりなかったので、参考にしていただければ嬉しいです。
↧
↧
Node.jsとは??
今回は、Node.jsについて学習していきます。
Node.jsとは??
簡単に言うとサーバーサイドバージョンのJavaScriptです。
最近JavaScriptでフロントが書かれているため、サーバーサイドもJavaScriptで書いたら効率いいよねってことで使われています。
Node.jsで何ができるのか??
①Node.jsじたいは動かない
え?動かんの?って思った方もいらっしゃるかなと思います。JavaScriptのプラットフォームです。
あくまで、Node.jsはメインであるJavaScriptが動くよう補佐官のようなものです。
②Webアプリ
Node.jsは軽量のため、リアルタイムのウェブアプリケーションに最適です。
また処理速度も早いため、複数人がログインする場合などに使われたりします。
③ゲームアプリ
ゲーム通信に適した通信プロトコルを使用できるようになるライブラリを使用した方がより良いアプリを作ることができます。
④スマートフォンアプリ
リアルタイム通信が可能なため、チャット機能などの実装に使われています。
⑤ウェブAPI
Expressという機能を使うことで、WEBAPIを作ることができます。
*Expressとは、ウェブアプリケーションやモバイルアプリケーション向けのNode.jsのフレームワークです。
↧
yarn install で出会った「error An unexpected error occurred: "ENFILE: file table overflow」を解決したよ
事象
yarn installしていたら、以下のエラーに出会った。
error An unexpected error occurred: "ENFILE: file table overflow ...
環境
Mac OS 11.2.3 (Big sur)
node v14.16.1
対処方法
nodeがどうとかyarnがどうとかでなく、Macの制限が原因みたい。
で、以下のコマンド実行
$ echo kern.maxfiles=65536 | sudo tee -a /etc/sysctl.conf
Password:
kern.maxfiles=65536
$ echo kern.maxfilesperproc=65536 | sudo tee -a /etc/sysctl.conf
kern.maxfilesperproc=65536
$ sudo sysctl -w kern.maxfiles=65536
kern.maxfiles: 12288 -> 65536
$ sudo sysctl -w kern.maxfilesperproc=65536
kern.maxfilesperproc: 10240 -> 65536
$ ulimit -n 65536
その後、無事にyarn install完了!!!
よかった!!
参考サイト
Error: ENFILE: file table overflow on MacOS Sierra
↧
マジで危険が危ないnode.jsのconfig
概要
普段、Node.jsでExpressを使用したAPIを開発をしているのだが、config機能の取り扱いでこれはやべえって思った内容があったので備忘ついでに残すことにした。
事象
ある操作をすると、本来は変更が加わってはいけないはずのconfigの中身が変更されてしまう。
変更されたconfigの中身はExpressを再起動しない限り元には戻らない。
発現方法
呼び出したconfigの中身を入れ替えてやればいい。
import config from 'config'
const pollutionConfig = () => {
config.aaa = "pollution"
}
export default pollutionConfig;
config/sample.js
module.exports = {
"aaa":[
111,
222,
333,
{
"sample1": 12345,
"sample2": 67890
}
],
"bbb":[
111,
222,
333,
{
"sample1": 12345,
"sample2": 67890
}
]
}
configの中身は値渡しで渡ってくるわけではなく内部的に値をクローンしてくれるわけでもないようなので、この結果は当然のことらしい。
それでも基本的なこととして、configの内容が書き変わるとかないでしょ。
ならばどうするか
ディープコピーしようぜ。
import config from 'config'
const safetyConfig = () => {
const c = JSON.perse(JSON.stringify(config))
c.aaa = "OK"
}
export default safetyConfig;
これなら大元のグローバル領域が変更されることはない。
ディープコピーの方法はいくつかあるが、JSONデータは配列と連想配列が入り乱れることも多いため、一旦stringifyした上でperseしなおすのが一番手っ取り早いと思う。
場合によっては、これは共通処理化してしまってもいいかもしれない。
パフォーマンスに関しては知らん。
↧
npm install -g xxx(グローバルインストール)でエラーが出てしまった時の対処法
概要
npm のグローバルインストール実行時に、エラーでインストールが出来なかった時の対処法の備忘録。
具体的には、npm install -g @angular/cli を実行時にエラーで正常終了しなかった時、権限の問題を解消して正常にインストールをできる様にした話。
前提
Node.js をインストール済み
筆者の環境
macOS 10.15.7 Catalina
Node.js v14.16.1
npm v6.14.12
事象
以下を実行して、npm グローバルインストールで「Angular CLI」というものを入れようとした時の話。
# -g の後ろは何でも良いが、今回は実例としてこのパッケージをインストール
npm install -g @angular/cli
すると、以下のエラーが発生
npm WARN deprecated request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142
npm WARN deprecated har-validator@5.1.5: this library is no longer supported
npm WARN checkPermissions Missing write access to /usr/local/lib/node_modules
npm ERR! code EACCES
npm ERR! syscall access
npm ERR! path /usr/local/lib/node_modules
npm ERR! errno -13
npm ERR! Error: EACCES: permission denied, access '/usr/local/lib/node_modules'
npm ERR! [Error: EACCES: permission denied, access '/usr/local/lib/node_modules'] {
npm ERR! errno: -13,
npm ERR! code: 'EACCES',
npm ERR! syscall: 'access',
npm ERR! path: '/usr/local/lib/node_modules'
npm ERR! }
npm ERR!
npm ERR! The operation was rejected by your operating system.
npm ERR! It is likely you do not have the permissions to access this file as the current user
npm ERR!
npm ERR! If you believe this might be a permissions issue, please double-check the
npm ERR! permissions of the file and its containing directories, or try running
npm ERR! the command again as root/Administrator.
npm ERR! A complete log of this run can be found in:
npm ERR! /Users/{ユーザ名}/.npm/_logs/2021-04-08T17_35_24_683Z-debug.log
→ インストールの過程でアクセスする一部のディレクトリのアクセスを拒否された模様。
Missing write access to /usr/local/lib/node_modules
原因
特定のディレクトリにパーミッション(権限)がないから。
解決策
解決方法は2つある
❶ sudo を頭に付けてインストールを実行する
sudo npm install -g @angular/cli
❷ 該当のディレクトリのオーナーを今のユーザに変更する
# /usr/local/ 以下の lib/node_modules, bin, share のオーナーを現在のユーザに変更
sudo chown -R $(whoami) $(npm config get prefix)/{lib/node_modules,bin,share}
どちらでも良いが、グローバルのパッケージを触る時に毎回「sudo」つけるのが抵抗あるなら❷、そんなの気にしない or よくわからないなら今は❶で良いと思われる。
結果
再度インストールを実行してみた。
npm WARN deprecated request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142
npm WARN deprecated har-validator@5.1.5: this library is no longer supported
/usr/local/bin/ng -> /usr/local/lib/node_modules/@angular/cli/bin/ng
> @angular/cli@11.2.8 postinstall /usr/local/lib/node_modules/@angular/cli
> node ./bin/postinstall/script.js
+ @angular/cli@11.2.8
updated 1 package in 4.667s
ちょっと警告は出たけど、インストール成功。
補足
「解決策❷」で対応する場合、
最初は純粋に、/usr/local/lib/node_modules にだけ、以下のコマンドで権限を与えてみたが、、、
sudo chown -R $USER /usr/local/lib/node_modules
でも、その後インストールを再実行したら、以下の様に、今度は他のディレクトリでもアクセス拒否が起きた。
npm ERR! code EACCES
npm ERR! syscall symlink
npm ERR! path ../lib/node_modules/@angular/cli/bin/ng
npm ERR! dest /usr/local/bin/ng
npm ERR! errno -13
npm ERR! Error: EACCES: permission denied, symlink '../lib/node_modules/@angular/cli/bin/ng' -> '/usr/local/bin/ng'
npm ERR! [OperationalError: EACCES: permission denied, symlink '../lib/node_modules/@angular/cli/bin/ng' -> '/usr/local/bin/ng'] {
npm ERR! cause: [Error: EACCES: permission denied, symlink '../lib/node_modules/@angular/cli/bin/ng' -> '/usr/local/bin/ng'] {
npm ERR! errno: -13,
npm ERR! code: 'EACCES',
npm ERR! syscall: 'symlink',
npm ERR! path: '../lib/node_modules/@angular/cli/bin/ng',
npm ERR! dest: '/usr/local/bin/ng'
npm ERR! },
npm ERR! errno: -13,
npm ERR! code: 'EACCES',
npm ERR! syscall: 'symlink',
npm ERR! path: '../lib/node_modules/@angular/cli/bin/ng',
npm ERR! dest: '/usr/local/bin/ng'
npm ERR! }
なので、/usr/local/ ディレクトリ配下の他のディレクトリにも権限与えないとエラーが解消しないと気付き、上記の解決策に至ったとさ。。。
↧
↧
【Node】npmstartしたら、ENOENT: no such file or directory, open '/home/ubuntu/package.json'と怒られた件【React】
症状
RailsAPIモードにReactを入れた構成をcloud9上でnpmstartで動かそうとしたとき、下記エラーコードで怒られてしまいました。
どうやら、package.jsonがないよと言われているようです。
エラーメッセージ
(master) npm start
npm ERR! code ENOENT
npm ERR! syscall open
npm ERR! path /home/ubuntu/package.json
npm ERR! errno -2
npm ERR! enoent ENOENT: no such file or directory, open '/home/ubuntu/package.json'
npm ERR! enoent This is related to npm not being able to find a file.
npm ERR! enoent
npm ERR! A complete log of this run can be found in:
npm ERR! /home/ubuntu/.npm/_logs/2021-04-09T02_35_13_814Z-debug.log
ファイルを確認すると確かに/home/ubuntu/package.jsonには、該当のファイルがありませんでした。
その下位にある/home/ubuntu/プロジェクト名/frontendにはpackage.jsonがありました。
解決策
package.jsonがあるディレクトリのfrontendまで移動して、そこでnpmstartすることで正常にnpmstartすることができました。
ディレクトリを移動して、npmstart
#package.jsonがあるディレクトリまで移動
cd frontend
npm start
ちなみに、「npm start」Nodeプロジェクトを実行という意味で、package.json の scripts.start に指定された内容を実行するとのこと。
今回のエラーは実行に必要なpackage.jsonファイルが見つからなかったため、怒っていたようです。
初歩的ではありましたが、npmstartはnodeをインストールしたディレクトリでなければいけないことを改めて認識することができましt。
参考
プロジェクトを実行!npm startの使い方【初心者向け】
https://techacademy.jp/magazine/16393
↧
node.jsでTwitterに投稿をしてみる。
node.jsでTwitterに投稿をしてみる
node.jsでTwitter APIを使ってTwitterに投稿を行うまでの流れです。
ある一点でハマってしまったので、その点についても記述します。
流れ
keyとtokenの取得
ソースコード
投稿
前提条件
node.jsは既に導入済みとします。
筆者はhomebrew→nodebrew→node.jsの手順でインストールしました。
またTwitterのAPIを使うにはTwitterの開発者アカウントが必要ですが、そちらも登録済みとします。登録方法は詳しくまとめている方が沢山いるので、そちらを参照して下さい。
環境
PC
Macbook air 2013
OS
Big sur v11.2.3
Homebrew
v3.0.10
nodebrew
v8.9.4
エディタ
vs code
1. keyとtokenの取得
Twitterデベロッパーサイトにアクセスします。
右上にあるDeveloper Potralをクリックします。
Dashboardが表示されたら、左側のoverviewを選択して、Add Appをクリックします。
この画面はプロジェクト作成済などの状態で人によって変わりますので参考程度にしてください。
また、選択肢にプロジェクトとスタンドアロンが表示されている方は、公式のこちらを参考にしてください。
アプリの名前を決めます。他のユーザが既に使用している名前は使用できません。
今回はdemo2021-testという名前にしました。
名前が通ると、keyが生成されます。
このkeyは一度しか表示されませんが、現時点のkeyは今回の用途では使用できない可能性があるので保存はしなくても結構です。
keyは再生成できるので安心してください。
そしてそのまま、画面下にあるsettingをクリックしてください。
次にApp permissionsの変更を行います。
ここが冒頭での筆者がハマった点になります。
デフォルトではこの設定がreadになっているので、Twitterに書き込みが行えません。
なので、permissionsをread+writeに変更します。
先ほどkeyを保存しなくて良いとした理由は、keyのpermissionがreadになっており、変更後に再生成したkeyでないとtwitterへの書き込みができない可能性があるからです。
次にkeyとtokenを生成します。
settingsからkey and tokensに切り替え、Authentication TokensのGenerateをクリックすると、tokenが生成されます。
Consumer Keysでは、既に一度keyを作っているのでRegenerateからkeyを再生成します。
もし値を忘れた場合は、Regenerateからどちらも再生成が可能です。
2. ソースコード
ここからはターミナルでの作業です。
まずは、Twitterのモジュールをインストールします。
npm install twitter
次にプログラムを書いていきます。
ソースコードは、公式のドキュメントがあるのでそれに生成した自分のkeyとtokenを記述するだけです。
ファイル名は、twitter_node.jsにしました。
var Twitter = require('twitter');
var client = new Twitter({
consumer_key: '自身のAPI key',
consumer_secret: '自身のAPI secret key',
access_token_key: '自身のAccess token',
access_token_secret: '自身のAccess token secret'
});
client.post('statuses/update', {status: 'node.js test hello!'}, function(error, tweet, response) {
if(error) throw error;
console.log(tweet); // Tweet body.
console.log(response); // Raw response object.
});
{status: 'node.js test hello!'}の部分が、実際にツイートされます。
3. 投稿
あとは、プログラムを実行するだけです。
node twitter_node.js
Twitterにログインするとツイートがされています。
エラーを吐かれた場合
keyのpermissionsが変更前のreadとして反映されている可能性が高いです。
再生成したものを使用するようにしてください。
またkeyとtokenの配置も気をつけてください。
まとめ
node.jsからAPIを通してツイートできるようになりました。
Twitter APIに触れたのは初めてだったので色々と面白かったです。
今後はbot化を目指したいです。
参考文献
導入にあたり参考にした記事
Permissionsの解決に至った記事
↧
【Node】npmstartすると、Something is already running on port 8080. Probably:と言われてしまう件【React】
症状
cloud9でnpmstartを一度実行した状態で誤ってターミナルを閉じてしまい、再度開きなおしてnpmstartをすると下記のような表示されるようになってしまいました。
翻訳すると、「何かがすでにポート8080で実行されています。おそらく:(中略)代わりに、別のポートでアプリを実行しますか?」
yを押すと、npmstartは動作するようにはなりますが、実行するたびに表示されるのはめんどくさいので解消します。
$ react-scripts build
Creating an optimized production build...
Compiled successfully.
File sizes after gzip:
? Something is already running on port 8080. Probably:
/home/ubuntu/.nvm/versions/node/v12.16.1/bin/node /home/ubuntu/environment/プロジェクト名/frontend/node_modules/react-scripts/scripts/start.js (pid 15133)
in /home/ubuntu/environment/プロジェクト名/frontend
Would you like to run the app on another port instead? › (Y/n)
解決策
killコマンドでプロセスを停止させることで、同様のメッセージはひょうじされないようになりました。
#ポート番号は任意のものに変えて使用してください
npx kill-port 8080
参考
Node.js Port 3000 already in use but it actually isn't?
https://stackoverflow.com/questions/39322089/node-js-port-3000-already-in-use-but-it-actually-isnt
↧
(自分メモ)最新のNode.js(LTS)をLinuxに導入する方法
1. NVMの導入
以下を参照して最新のNVM(Node Version Manager)を導入する。
https://github.com/nvm-sh/nvm#installing-and-updating
# cat /etc/redhat-release
CentOS Linux release 7.9.2009 (Core)
# curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash
# source ~/.bashrc
# nvm --version
0.38.0
# which nvm
/usr/bin/which: no nvm in (/root/.nvm/versions/node/v14.16.1/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin)
# command -v nvm
nvm
2. Node.jsの導入
# nvm ls-remote|grep Latest
v4.9.1 (Latest LTS: Argon)
v6.17.1 (Latest LTS: Boron)
v8.17.0 (Latest LTS: Carbon)
v10.24.1 (Latest LTS: Dubnium)
v12.22.1 (Latest LTS: Erbium)
v14.16.1 (Latest LTS: Fermium)
# nvm ls
N/A
default -> stable (-> N/A)
iojs -> N/A (default)
node -> stable (-> N/A) (default)
unstable -> N/A (default)
lts/* -> lts/fermium (-> N/A)
lts/argon -> v4.9.1 (-> N/A)
lts/boron -> v6.17.1 (-> N/A)
lts/carbon -> v8.17.0 (-> N/A)
lts/dubnium -> v10.24.1 (-> N/A)
lts/erbium -> v12.22.1 (-> N/A)
lts/fermium -> v14.16.1 (-> N/A)
# nvm install --lts --latest-npm (最新がv14.16.1なので、それを導入するのと同じ)
# nvm install v14.16.1
# nvm install v12.22.1
3. 切り替えテスト
v12.22.1を利用
# nvm use v12.22.1
Now using node v12.22.1 (npm v6.14.12)
# nvm current
v12.22.1
# node -v
v12.22.1
# nvm ls
-> v12.22.1
v14.16.1
default -> stable (-> v14.16.1)
iojs -> N/A (default)
unstable -> N/A (default)
node -> stable (-> v14.16.1) (default)
stable -> 14.16 (-> v14.16.1) (default)
lts/* -> lts/fermium (-> v14.16.1)
lts/argon -> v4.9.1 (-> N/A)
lts/boron -> v6.17.1 (-> N/A)
lts/carbon -> v8.17.0 (-> N/A)
lts/dubnium -> v10.24.1 (-> N/A)
lts/erbium -> v12.22.1
lts/fermium -> v14.16.1
deactivate
# nvm deactivate
/root/.nvm/*/bin removed from ${PATH}
# nvm current
none
# node -v
-bash: node: コマンドが見つかりません
# nvm ls
v12.22.1
v14.16.1
default -> stable (-> v14.16.1)
iojs -> N/A (default)
unstable -> N/A (default)
node -> stable (-> v14.16.1) (default)
stable -> 14.16 (-> v14.16.1) (default)
lts/* -> lts/fermium (-> v14.16.1)
lts/argon -> v4.9.1 (-> N/A)
lts/boron -> v6.17.1 (-> N/A)
lts/carbon -> v8.17.0 (-> N/A)
lts/dubnium -> v10.24.1 (-> N/A)
lts/erbium -> v12.22.1
lts/fermium -> v14.16.1
v14.16.1を利用
# nvm use v14.16.1
Now using node v14.16.1 (npm v7.9.0)
# nvm current
v14.16.1
# node -v
v14.16.1
# nvm ls
v12.22.1
-> v14.16.1
default -> stable (-> v14.16.1)
iojs -> N/A (default)
unstable -> N/A (default)
node -> stable (-> v14.16.1) (default)
stable -> 14.16 (-> v14.16.1) (default)
lts/* -> lts/fermium (-> v14.16.1)
lts/argon -> v4.9.1 (-> N/A)
lts/boron -> v6.17.1 (-> N/A)
lts/carbon -> v8.17.0 (-> N/A)
lts/dubnium -> v10.24.1 (-> N/A)
lts/erbium -> v12.22.1
lts/fermium -> v14.16.1
↧
↧
[Symbol Watcher]ノードの委任ハーベスターの変動をメールかSlackで通知する機能を追加しました
はじめに
Symbolノーダーのみなさんこんにちわ
この間ハーベストの通知機能を作成したのですが、思いの外使っていただき、現在80アカウント程度の方が使ってくれています!
ありがとうございます!
前回はハーベストを行う全ての人にむけたツールだったのですが、今回はノードを建てた人(ノーダー)さん用のツールを作ってみました。
かくいう私もGCP上でSymbolノードを立てたのですが現在10人(内2人は自分)となかなか苦しい状況が続いておりますw
毎日unlockedaccountを確認して、増えてない事を確認していましたが、
そろそろ見るのが面倒になってきたのでツールを作成しました
良かったお使いください
ツールはこちら -> SymbolWatcher
使い方
ノードと通知先を入力
使い方はすでにハーベストの通知機能を使ってくれている方であれば簡単です
自分のノードのIPアドレスかドメインを入力してください、
1メールアドレス or 1SlackURLに対して3つまでノードを登録することができます
通知先のメールアドレスかSlackURLに認証メッセージがとどきます
メール認証
Slack認証
認証完了画面
これで通知が届くようになりました
通知
メール通知
Slack通知
通知内容は委任者数、増えたアカウント、減ったアカウントです
通知をとめたい場合はリンクをクリックしてください
最後に
私のノードは
GCP上に CPU 8コア RAM 32GB SSD 750GBとなかなかの高スペックで作成してあります!
バージョンも常に最新でHttps対応もしています!
ちなみに月3万位このサーバーを維持するのにかかります(笑
このままだと赤字なので委任者を大募集しています!!w
ドメイン: raharu-symbol-node-01.com
アカウント情報: https://raharu-symbol-node-01.com:3001/node/unlockedaccount
接続peer: https://raharu-symbol-node-01.com:3001/node/peers
リストに表示されないよ!とかありましたらご連絡ください
https://qiita.com/raharu0425/items/1f11654dee1f129337c2
ノーダーさんとSymbolの普及の一助になれば幸いですm(_ _)m
↧
husky v5 で消耗している人には simple-git-hooks がお薦め
Git の Hook を扱う husky というライブラリがあり、大変お世話になっていた。が、 v5 が登場してから、設定変更を余儀なくされた。
v4 とは大きく異なる設計思想のため、私達は今まで書いていた設定ファイルを変え、 .husky ディレクトリを作成し、 husky のコマンドドキュメントを読んで、確認した。
正直 husky v5 のこの変更には失望した。もちろん正当な理由が合ったのだとは思うが、このようなツールの設定変更に時間を取られたくないと思った。このようなツールにはドキュメントが存在しないくらいの方がちょうどいいと思った。なんでこんな大きなドキュメントがあるのか不思議に思った。
なんか同僚の PC で pre-commit フックが動いてないっぽい。そんでコードがフォーマットされてなくてイライラする。 OSS にプルリクくれる人にも申し訳ない。
しかも husky の変更は個人的に改悪だと思った。 .husky ディレクトリを作成したり、 husky install で何が行われるのか? .husky の中にある謎のファイル _ は何なのか?
しかも、 Husky は 勝手に .git/config を変更するから、他のツールと併用すると面倒なことになりそう。
自分はただ単に git commit の前に Prettier を実行したいだけなのに、なぜこんなことになってしまったんだ。
そこで見つけたのが simple-git-hooks
超かんたん。基本これで終わり。
yarn add simple-git-hooks
package.json
"scripts": {
"prepare": "simple-git-hooks"
},
"simple-git-hooks": {
"pre-commit": "npx lint-staged"
}
あーもうこれで生きてくわ。これで良い。これだけで良い。
ちなみに husky から移行する時は、下記コマンドを実行して husky が 勝手に 変更した Git の設定をもとに戻そう。
yarn remove husky
rm -rf .husky
git config core.hooksPath .git/hooks/
↧
Base64 変換
Base64 変換についてまとめてみました。
Python3 の例
encode01.py
#! /usr/bin/python
#
import base64
#
data_in = 'こんにちは'
bytes_in = data_in.encode()
#
encoded = base64.b64encode(bytes_in)
print(encoded)
decode01.py
#! /usr/bin/python
#
import base64
#
data = b'44GT44KT44Gr44Gh44Gv'
decoded = base64.b64decode(data)
str_out = decoded.decode()
print(str_out)
#
Node.js の例
encode01.js
#! /usr/bin/node
// ---------------------------------------------------------------
// encode01.js
//
// Apr/10/2021
//
// ---------------------------------------------------------------
'use strict'
// ---------------------------------------------------------------
console.error ("*** 開始 ***")
const data_in = 'こんにちは'
const buffer = new Buffer.from(data_in)
const string = buffer.toString('base64')
console.log(string)
console.error ("*** 終了 ***")
// ---------------------------------------------------------------
decode01.js
#! /usr/bin/node
// ---------------------------------------------------------------
// decode01.js
//
// Apr/10/2021
//
// ---------------------------------------------------------------
'use strict'
// ---------------------------------------------------------------
console.error ("*** 開始 ***")
const data_in = '44GT44KT44Gr44Gh44Gv'
const string = Buffer.from(data_in,'base64')
console.log(string.toString())
console.error ("*** 終了 ***")
// ---------------------------------------------------------------
Go の例
encode01.go
package main
import (
b64 "encoding/base64"
"fmt"
"os"
)
func main() {
fmt.Fprintf (os.Stderr,"*** 開始 ***\n")
data := "こんにちは"
sEnc := b64.StdEncoding.EncodeToString([]byte(data))
fmt.Println(sEnc)
fmt.Fprintf (os.Stderr,"*** 終了 ***\n")
}
decode01.go
package main
import (
b64 "encoding/base64"
"fmt"
"os"
)
func main() {
fmt.Fprintf (os.Stderr,"*** 開始 ***\n")
data_in := "44GT44KT44Gr44Gh44Gv"
uDec, _ := b64.URLEncoding.DecodeString(data_in)
fmt.Println(string(uDec))
fmt.Fprintf (os.Stderr,"*** 終了 ***\n")
}
コマンドでの変換
エンコード
入力データ
a01.txt
こんにちは
実行結果
$ base64 a01.txt
44GT44KT44Gr44Gh44Gv
デコード
入力データ
b01.txt
44GT44KT44Gr44Gh44Gv
実行結果
$ base64 -d b01.txt
こんにちは
↧