- 投稿日:2021-01-09T23:08:06+09:00
NodejsでWebアプリケーション作成 with Docker
前提
ProgateのNodejsコース完了程度の知識があること。
Docker使える。
VSCodeでDocker入門本記事の対象者
ProgateでNodejs学んだ。次は自分のプロジェクトを作ってみたいって人
本記事でやること
- DockerでNodejs環境を作る
- プロジェクトの作成
- ライブラリのインストール
- ブラウザ上でページを確認
環境
Docker
VSCode
Node 14.15
Gitプロジェクトの作成
まず適当な場所にプロジェクトのフォルダを作成。
本記事ではnodejs-sample-app
という名前で作った。そして、そのフォルダをVSCodeで開く。
以下のファイルを作成
docker-compose.ymlversion: "3" services: node: image: node:14.15 volumes: - .:/project tty: true working_dir: /project command: bashNodeのバージョンは14.15を指定しておく。
コンテナに入ってバージョンを確認。
root@cf2295d42525:/project# node -v v14.15.4そしたらプロジェクトを作る準備が完了。
ここからnpmコマンドを使ってプロジェクトを構築する。
以下のコマンドを打つと、プロジェクトに
package.json
というファイルが作成される。
$ npm init -y
root@cf2295d42525:/project# npm init -y Wrote to /project/package.json: { "name": "project", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC" }package.json は Nodejsプロジェクトの様々な情報をかくところと把握しておけばOK
次に Webアプリケーション において一番最初に呼ばれるjsファイルを作る。
package.json と同じ階層に以下のように作成app.jsconsole.log("Hello nodejs");そうしたら、以下のコマンドで実行されるか確かめる
root@cf2295d42525:/project# node app.js Hello nodejsHello nodejs と表示されたらOK
次に package.json を以下のように変更
package.json{ "name": "project", "version": "1.0.0", "description": "", "main": "app.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "node app.js" }, "keywords": [], "author": "", "license": "ISC" }mainを修正 testの末尾にカンマ追加, scripts.start追加
そうすると、
npm start
でscripts.startで指定したコマンドが呼ばれるようになる。root@cf2295d42525:/project# npm start > project@1.0.0 start /project > node app.js Hello nodejsこれでひと段落。
このタイミングで
git init
すると良い。expressのインストールとルーティング
expressのインストール
$ npm install expresspackage.jsonに以下のように追記される
{ ... "dependencies": { "express": "^4.17.1" } }そして、node_modulesというフォルダと package-lock.jsonというファイルができる。
node_modulesにはインストールしたpackageが入る。
これはプッシュしたくないのでgitignoreを作成してつっこむ。.gitignorenode_modules/installして差分がでてるのでここでcommit。
ルーティングを作成
app.jsconst express = require('express'); const app = express(); app.get('/', (req, res) => { res.send({message: "ok!"}); }); const port = process.env.PORT || 3000 app.listen(port, () => console.log(`server started port ${port}`));
npm start
すると、以下のように表示される。root@cf2295d42525:/project# npm start > project@1.0.0 start /project > node app.js server started port 3000しかし、今のままではブラウザでひらけない
docker-composeにportについて記述する必要がある。
docker-compose.ymlversion: "3" services: node: image: node:14.15 volumes: - .:/project tty: true working_dir: /project ports: - "3000:3000" command: npm startportsを追加し、コンテナを立ち上げた時に npm start 実行するように変更した。
docker-compose を編集したら、コンテナを作り直す必要がある。
一度コンテナを消して以下を実行$ docker-compose up -dちゃんとサーバーとして起動しているかログを確認
nodejs-sample-app(main)$ docker-compose logs Attaching to nodejs-sample-app_node_1 node_1 | node_1 | > project@1.0.0 start /project node_1 | > node app.js node_1 | node_1 | server started port 3000いけてそう。
ブラウザで確認
ejs
ejsを使うためにインストール
$ npm install ejs
viewsフォルダを作成し、その中にejsファイルを作成
views/index.ejs<!DOCTYPE html> <html lang='en'> <head> <meta charset='UTF-8'> <meta name='viewport' content='width=device-width, initial-scale=1.0'> <title>Document</title> </head> <body> <p><%= message %></p> </body> </html>app.jsconst express = require('express'); const app = express(); app.get('/', (req, res) => { res.render("index.ejs", {message: "うおおおおおお"}) }); const port = process.env.PORT || 3000 app.listen(port, () => console.log(`server started port ${port}`));renderでejsを描画し、「message」を埋め込む
- 投稿日:2021-01-09T21:56:54+09:00
ESモジュールでexpressを使うサンプル(babel利用)
目的
フロントエンドはESモジュール形式で記載するのに、バックエンド側はrequire()を使うという課題?を揃えたいという願望です。
(babelにするかtypescriptにするかで悩んでいます)
- 実現したら、おまけにsequelizeも追加するかも
実現手段
expessをES6(import)で利用できるようにするため、babelでトランスパイルする。
⇒package.json に 「type: module」を追加すればESモジュールを使えますが、jsファイルの拡張子(.cjs、.mjs)の切り分けが面倒なのでbabelにします。express-generatorでひな形を生成する。
開発時は「babel-node」で実行(ビルド不要)可能とする。トランスパイルしたjsファイルが必要な場合はbuildを行う。
sequelizeと組み合わせて使用する(sequelizeはnodeモジュール形式で生成される。ES6形式で記載したexpress側で問題なく利用できることを確認する)
前提
- nodeとyarnがインストール済みであること (npmを使う場合は適宜読み替えてください)
利用モジュール
{ "dependencies": { "cookie-parser": "~1.4.4", "debug": "~2.6.9", "express": "~4.16.1", "morgan": "~1.9.1" }, "devDependencies": { "@babel/cli": "^7.12.10", "@babel/core": "^7.12.10", "@babel/node": "^7.12.10", "@babel/preset-env": "^7.12.11" } }手順詳細
1. express-generatorでひな形を作成(viewは生成しない。.gitignoreは生成する)
npx express-generator express-generator-babel --no-view --git2. (作成されたフォルダに移動し)必要なライブラリをインストール
yarn install
3. expressが起動することを確認
yarn startブラウザで「http://localhost:3000」 を表示する
4. babelインストール
yarn add @babel/cli @babel/core @babel/preset-env -D
5. babelの設定ファイル(.babelrc)を作成する
targetにcurrentを入れることで、インストールされているnode.jsが理解できる形でトランスパイルされます。
(最近のnodeであればawaitやasyncなどがヘルパー関数ではなく、そのまま出力されます(pollyfill不要)){ "presets": [ [ "@babel/preset-env", { "targets": { "node": "current" } } ] ] }6. babelでビルドするため、フォルダ構成を変更する。
- jsファイルを「/src」フォルダ配下にすべて移動する
mkdir src mv bin/ routes/ app.js src/※「bin」「routes」フォルダと、app.jsファイルを「src」フォルダに移動している。
- フォルダ階層が変わったためソースを一部修正する
app.js (publicフォルダの位置を修正)
app.use(express.static(path.join(__dirname, 'public'))); ↓ app.use(express.static(path.join(__dirname, '../public')));
- トランスパイル先フォルダを作成する
mkdir dist
7. ビルド用コマンドをpackage.jsonに追加する
package.json の "scripts"に下記コマンドを追加する。
"build": "babel src --out-dir dist --copy-files && babel ./src/bin/www --out-file ./dist/bin/www"※.src/bin/www は拡張子がないjsファイル。フォルダ指定では対象にならないため、個別にトランスパイルをしている。
8. babelでトランスパイルを行う
yarn build9. トランスパイルしたソースで動作確認を行う
- package.json の "scripts"に下記コマンドを追加する。
"serve": "node ./dist/bin/www"
- サーバを起動する
yarn serveブラウザで「localhost:3000」を開き、expressのトップページが開くことを確認する。
10. ESモジュールに変更して動作確認を行う
- require()をimportに変更しても動作することを確認する。
- module.exportsからES6のexportに変更した場合、読み込み元も「import」に修正する必要がある。
- ソース内でrequire()をimportに変更しても、外部にエクスポートする「module.export」を変更しなければ、呼び出し元は変更不要。
/src/routes/index.js
// var express = require('express'); //コメントアウト import express from 'express'; //追加 var router = express.Router(); /* GET home page. */ router.get('/', function(req, res, next) { res.render('index', { title: 'Express' }); }); // module.exports = router; //コメントアウト export default router; //追加/src/app.js
// var express = require('express'); //コメントアウト // var path = require('path'); // var cookieParser = require('cookie-parser'); // var logger = require('morgan'); import express from 'express'; //追加 import path from 'path'; import cookieParser from 'cookie-parser'; import logger from 'morgan'; // var indexRouter = require('./routes/index'); //コメントアウト import indexRouter from './routes/index'; //追加 var usersRouter = require('./routes/users'); var app = express(); app.use(logger('dev')); app.use(express.json()); app.use(express.urlencoded({ extended: false })); app.use(cookieParser()); app.use(express.static(path.join(__dirname, '../public'))); app.use('/', indexRouter); app.use('/users', usersRouter); module.exports = app; //コメントアウトしない。読み込み元(bin/www)を変更せず、require()のままとするため。 //export default app; // exportに書き換えると、読み込み元をimportに書き換える必要がある。11. ESモジュール化後の動作確認
yarn build yarn serve
- ブラウザで「localhost:3000」を開き、expressのトップページが開くことを確認する。
12. 開発用に「babel-node」を導入する(ビルド無しで動作させるため)
- babel-nodeをインストールする
yarn add @babel/node -D
- package.jsonの startを修正する
"start": "node ./bin/www", ↓ "start": "babel-node ./src/bin/www",
- babel-nodeで起動することを確認する(build不要)
yarn startブラウザで「localhost:3000」を開き、expressのトップページが開くことを確認する。
- 投稿日:2021-01-09T21:56:54+09:00
expressをESモジュールに変更する手順(babel利用)
目的
バックエンドをESモジュールで記載できるようにしたい(フロントエンドに合わせる)という目的です。
おまけにsequelizeを追加して、動作することも確認する。
完成後ソース(tagのv1がsequelize追加前まで、v2(最新コミット)が最後まで)
https://github.com/murasuke/express-generator-babel結果
- ESMとしてexportしたモジュールはimportする、module.exportの場合(node)はrequire()を利用するということに気を付ければ、混在していても問題なく動く。
実現手段
expessをES6(import)で利用できるようにするため、babelでトランスパイルする。
⇒package.json に 「type: module」を追加すればESモジュールを使えますが、jsファイルの拡張子(.cjs、.mjs)の切り分けが面倒なのでbabelにします。express-generatorでひな形を生成する。
開発時は「babel-node」で実行(ビルド不要)可能とする。トランスパイルしたjsファイルが必要な場合はbuildを行う。
sequelizeと組み合わせて使用する(sequelizeはnodeモジュール形式で生成される。ES6形式で記載したexpress側で問題なく利用できることを確認する)
前提
- nodeとyarnがインストール済みであること (npmを使う場合は適宜読み替えてください)
利用モジュール
{ "dependencies": { "cookie-parser": "~1.4.4", "debug": "~2.6.9", "express": "~4.16.1", "morgan": "~1.9.1" }, "devDependencies": { "@babel/cli": "^7.12.10", "@babel/core": "^7.12.10", "@babel/node": "^7.12.10", "@babel/preset-env": "^7.12.11" } }手順
①expressのひな形をESモジュールに変更し、babelでコンパイルする
1. express-generatorでひな形を作成(viewは生成しない。.gitignoreは生成する)
npx express-generator express-generator-babel --no-view --git2. (作成されたフォルダに移動し)必要なライブラリをインストール
yarn install
3. expressが起動することを確認
yarn startブラウザで「http://localhost:3000」 を表示する
4. babelインストール
yarn add @babel/cli @babel/core @babel/preset-env -D
5. babelの設定ファイル(.babelrc)を作成する
targetにcurrentを入れることで、インストールされているnode.jsが理解できる形でトランスパイルされます。
(最近のnodeであればawaitやasyncなどがヘルパー関数ではなく、そのまま出力されます(pollyfill不要)){ "presets": [ [ "@babel/preset-env", { "targets": { "node": "current" } } ] ] }6. babelでビルドするため、フォルダ構成を変更する。
- jsファイルを「/src」フォルダ配下にすべて移動する
mkdir src mv bin/ routes/ app.js src/※「bin」「routes」フォルダと、app.jsファイルを「src」フォルダに移動している。
- フォルダ階層が変わったためソースを一部修正する
app.js (publicフォルダの位置を修正)
app.use(express.static(path.join(__dirname, 'public'))); ↓ app.use(express.static(path.join(__dirname, '../public')));
- トランスパイル先フォルダを作成する
mkdir dist
7. ビルド用コマンドをpackage.jsonに追加する
package.json の "scripts"に下記コマンドを追加する。
"build": "babel src --out-dir dist --copy-files && babel ./src/bin/www --out-file ./dist/bin/www"※.src/bin/www は拡張子がないjsファイル。フォルダ指定では対象にならないため、個別にトランスパイルをしている。
8. babelでトランスパイルを行う
yarn build9. トランスパイルしたソースで動作確認を行う
- package.json の "scripts"に下記コマンドを追加する。
"serve": "node ./dist/bin/www"
- サーバを起動する
yarn serveブラウザで「localhost:3000」を開き、expressのトップページが開くことを確認する。
10. ESモジュールに変更して動作確認を行う
- require()をimportに変更しても動作することを確認する。
- module.exportsからES6のexportに変更した場合、読み込み元も「import」に修正する必要がある。
- ソース内でrequire()をimportに変更しても、外部にエクスポートする「module.export」を変更しなければ、呼び出し元は変更不要。
/src/routes/index.js
// var express = require('express'); //コメントアウト import express from 'express'; //追加 var router = express.Router(); /* GET home page. */ router.get('/', function(req, res, next) { res.render('index', { title: 'Express' }); }); // module.exports = router; //コメントアウト export default router; //追加/src/app.js
// var express = require('express'); //コメントアウト // var path = require('path'); // var cookieParser = require('cookie-parser'); // var logger = require('morgan'); import express from 'express'; //追加 import path from 'path'; import cookieParser from 'cookie-parser'; import logger from 'morgan'; // var indexRouter = require('./routes/index'); //コメントアウト import indexRouter from './routes/index'; //追加 var usersRouter = require('./routes/users'); var app = express(); app.use(logger('dev')); app.use(express.json()); app.use(express.urlencoded({ extended: false })); app.use(cookieParser()); app.use(express.static(path.join(__dirname, '../public'))); app.use('/', indexRouter); app.use('/users', usersRouter); module.exports = app; //コメントアウトしない。読み込み元(bin/www)を変更せず、require()のままとするため。 //export default app; // exportに書き換えると、読み込み元をimportに書き換える必要がある。11. ESモジュール化後の動作確認
yarn build yarn serve
- ブラウザで「localhost:3000」を開き、expressのトップページが開くことを確認する。
12. 開発用に「babel-node」を導入する(ビルド無しで動作させるため)
- babel-nodeをインストールする
yarn add @babel/node -D
- package.jsonの startを修正する
"start": "node ./bin/www", ↓ "start": "babel-node ./src/bin/www",
- babel-nodeで起動することを確認する(build不要)
yarn startブラウザで「localhost:3000」を開き、expressのトップページが開くことを確認する。
②sequelize+sqliteを追加してデータを取得する
sequelize-cliを利用して生成したひな形(node module形式)を、express側から利用できることを確認する。
13. sequelize導入(DBはsqliteを利用する。別にサーバを作る必要がないため)
yarn add sequelize sqlite3 yarn add sequelize-cli -D
- 初期化時に自動生成されるフォルダを「/src」配下にするため、先に「.sequelizerc」ファイルを作成する(プロジェクトルート)
touch .sequelizerc
- sequelize関連ファイルを「/src/seqelize」で管理するように設定する(指定しない場合は、プロジェクトルートに作成される)
const path = require('path'); module.exports = { 'config': path.resolve('./src/sequelize/config', 'config.json'), 'models-path': path.resolve('./src/sequelize/models'), 'seeders-path': path.resolve('./src/sequelize/seeders'), 'migrations-path': path.resolve('./src/sequelize/migrations'), };
- マイグレーションのための初期化を行う
yarn sequelize init※コマンドは、sequelize, sequelize-cli どちらでもよい(エイリアス)
プロジェクトルートではなく、/src/sequelizeに作成されます。
- config.jsonをsqlite用に書き換える。
{ "development": { "database": "database_development", "dialect": "sqlite", "storage":"db/proto_app_dev.sqlite" }, "test": { "database": "database_test", "dialect": "sqlite", "storage":"db/proto_app_test.sqlite" }, "production": { "database": "database_production", "dialect": "sqlite", "storage":"db/proto_app.sqlite" } }14. sequelize-cli でテーブル定義のひな形を作成後、マイグレーションを行う
- sequelize model:generateでmodel定義と、マイグレーション用のひな形を生成する。
yarn sequelize model:generate --name User --attributes name:string,birth:date,email:string
- マイグレーションを行い、テーブルを作成する
yarn sequelize db:migrate15. テスト用データを登録(db:seed)する
- ひな形を作成する
yarn sequelize seed:generate --name user
- ひな形を修正(登録データを用意する)
'use strict'; module.exports = { up: async (queryInterface, Sequelize) => { const now = new Date(); const birth = new Date(now); const seeds = []; const subtractYear = ( date, year ) => new Date( date.setYear(date.getFullYear() - year) ); seeds.push({ name:"name1", birth:subtractYear(birth, 1), email:"mail1@example.com", createdAt: now, updatedAt: now }); seeds.push({ name:"name2", birth:subtractYear(birth, 1), email:"mail2@example.com", createdAt: now, updatedAt: now }); seeds.push({ name:"name3", birth:subtractYear(birth, 1), email:"mail3@example.com", createdAt: now, updatedAt: now }); return await queryInterface.bulkInsert("users",seeds, {}); }, down: async (queryInterface, Sequelize) => { await queryInterface.bulkDelete('users', null, {}); } };
- seedを登録する
yarn sequelize db:seed:all※やり直す場合は「yarn sequelize db:seed:undo:all」
16. 作成したmodelをexpress側から利用し、登録したデータが取得できることを確認する
- ./route/users.jsを修正し、sequelizeのmodel(users)を全レコードjson形式で返すように修正する
修正前
var express = require('express'); var router = express.Router(); /* GET users listing. */ router.get('/', function(req, res, next) { res.send('respond with a resource'); }); module.exports = router;修正後
import db from "../sequelize/models/index"; import express from 'express'; const router = express.Router(); /* GET users listing. */ router.get('/', async function(req, res, next) { //res.send('respond with a resource'); const users = await db.User.findAll(); res.json( users ); }); // module.exports = router; export default router;呼び出し元(app.js)も変更する。
// var usersRouter = require('./routes/users'); import usersRouter from './routes/users';17. ビルド後、データが取得できることを確認する
yarn build yarn serve
- localhost:3000/users にアクセスして、DBからデータが取得できることを確認する
[{"id":1,"name":"name1","birth":"2020-01-10T09:51:38.737Z","email":"mail1@example.com","createdAt":"2021-01-10T09:51:38.737Z","updatedAt":"2021-01-10T09:51:38.737Z"} ,{"id":2,"name":"name2","birth":"2019-01-10T09:51:38.737Z","email":"mail2@example.com","createdAt":"2021-01-10T09:51:38.737Z","updatedAt":"2021-01-10T09:51:38.737Z"} ,{"id":3,"name":"name3","birth":"2018-01-10T09:51:38.737Z","email":"mail3@example.com","createdAt":"2021-01-10T09:51:38.737Z","updatedAt":"2021-01-10T09:51:38.737Z"}]
- 投稿日:2021-01-09T14:31:45+09:00
Node.jsを勉強する⑦ - npmモジュールyargsを使った引数のオプションの処理
はじめに
前回はコマンドライン引数の受け取りについてまとめました。
今回はnpmモジュールyargsを使ったオプションの変換を記事にします。yargsを利用することで、ターミナルでコマンドを実行する際に、引数のオプションを入れた場合、それを引数として変換できます。教材
Udemy
The Complete Node.js Developer Course (3rd Edition)
https://www.udemy.com/course/the-complete-nodejs-developer-course-2/解決したいこと
processを用いることで、コマンドライン引数の受け取りはできましたが、引数のオプションを入力しても上手く変換されません。
まずは、こちらから見ていきましょう。app.jsというファイルを作成し、コマンドライン引数がconsoleに表示されるようにコードを書きます。app.jsconsole.log(process.argv[2])それでは、こちらのファイルを引数addBookとオプション title="Kokoro"を入れて実行してみます。
ターミナルnode app.js addBook --title="Kokoro"結果は以下のようになり、オプションである"Kokoro"をうまく読み込んでくれません。(--title="Kokoro"全体が2つめの引数として認識されている)
ターミナルaddBookこちらをnpmのyargsを使って解決します。
yargsのインストール
ターミナルにてインストールのコマンドを実行します。npm公式のyargsのページはこちら
ターミナル//npmを開始していない場合はこちらも実行 npm init npm i yargs
次に、requireを用いて、yargsをapp.js内で使えるようにします。コマンドライン引数をyargs.argvを用いて表示してみます。
app.jsconst yargs = require('yargs') console.log(yargs.argv);同じ引数を入れて、ファイルを実行すると、以下のように出力されます。
ターミナルnode app.js addBook --title="Kokoro" { _: [ 'addBook' ], title: 'Kokoro', '$0': 'app.js' }引数 addBookに対して、titleをプロパティとして認識し、Kokoroを値として出力できています。
ちなみに、'$0'は実行されたファイル名を指します。app.jsが実行されていることがわかります。コマンドをカスタマイズする
次に、yargsのコマンドをカスタマイズしてみます。
app.jsconst yargs = require('yargs') // 以下のコマンドを作作成します。 yargs.command({ //コマンド名 command: 'addBook', //以下で、コメントを残しておきます。 describe: 'Add a new Book', //以下の処理を実行します handler: function(){ console.log("Add a new book!"); } }) //yargsを実行する yargs.parse()コマンドが作成されているかターミナルから確認してみます。
ターミナルnode app.js --help Commands: app.js addBook Add a new Book Options: --help Show help [boolean] --version Show version number [boolean]コマンドに、 addBookと設定したコメントが追加されています。
実際に、コマンドを実行してみましょう。
ターミナルnode app.js addBook Add a new book!処理には、"Add a new book!"をコンソールに出力する処理を書きましたが、無事に表示されました。
コマンドに引数のオプションを追加する
作成したコマンドには、builderを用いて、オプションを追加できます。
app.jsconst yargs = require('yargs') yargs.command({ command: 'addBook', describe: 'Add a new Book', //オプション引数を追加 builder: { title:{ //処理の内容をメモ describe: "Add a book title", //必須の引数にするか指定 demandOption: true, //データ型を指定 type: "string" } }, //オプションを表示するように変更する handler: function(argv){ console.log("Adding " + argv.title); }, }) yargs.parse();ターミナルでオプションのtitleを入れてファイルを実行します。
ターミナルnode app.js addBook --title="Kokoro" Adding Kokoroオプションが上手く変換されて、コンソールに出力されました。
- 投稿日:2021-01-09T12:41:52+09:00
メンバーをBANする方法 Discord.js(GBAN前編)
サーバーから人をBANする方法
荒らす人、イライラする人にはBANができます。
その動作をBOTにさせる方法を教えます!動作環境
バージョン サービス v.12以上 Glitch document
公式ドキュメント(英語):Link
動き方
!ban メンションorID
↓
理由を聞く(BANをする理由)
↓
BAN完了!コード
const discord = require("discord.js"); const client = new discord.Client(); const prefix = "!";//ここは好きに変えてもいいです client.on("message", async message => { if (!message.content.match(/^!/)) return; //!が最初にない場合は処理をしない var command = message.content; command = command.replace("!", ""); if (command == "ban") { if (message.mentions.members.size == 1) { //メンションがあるかを確認 const member = await message.mentions.members.first();//メンションの内容 const id = member.user.id; //ユーザーID const mee = await message.channel.send({ //あとで編集などができるようにawait(非同期処理)をつける embed: { color: 16757683, description: "60秒以内に理由を入力してください。" } }); const filter = msg => msg.author.id === message.author.id; const collected = await message.channel.awaitMessages(filter, { max: 1, time: 60000 }); const response = collected.first(); if (!response) return mee.edit({ embed: { description: "タイムアウト…" } }); mee.edit({ embed: { description: "BANしています…" } }); message.guild.members.ban(id, { reason: response.content }); mee.edit({ embed: { description: `<@${id}>をBANしました。` } }); } else { //IDの場合 let me = message.content; me = me.replace("!ban ", ""); let id = me const mee = await message.channel.send({ embed: { color: 16757683, description: "60秒以内に理由を入力してください。" } }); const filter = msg => msg.author.id === message.author.id; //検索内容を設定 const collected = await message.channel.awaitMessages(filter, { max: 1, time: 60000 }); const response = collected.first(); if (!response) return mee.edit({ embed: { description: "タイムアウト…" } }); mee.edit({ embed: { description: "BANしています…" } }); message.guild.members.ban(id, { reason: response.content });//BANをする mee.edit({ embed: { description: `<@${id}>をBANしました。` } }); } } })動かない場合
①使うBOTに管理者権限、BANの権限、チャンネルへのアクセス権がない
②tokenが間違っている
③BOTが招待されていない
④コードが間違っている
など…使う上での注意
※サーバーにいないひとをBANする場合、IDでしかBANができません。一応反応はします。(エラーを出すこともできるけど→別の記事で)サーバー内にいる人ならメンションでOKです。
質問など
Discordの場合:ライグー/racoon#1010
コメントでもOKです
- 投稿日:2021-01-09T12:29:45+09:00
(小ネタ)TypeScriptで型定義ファイルが無いモジュールの読み込み方法
はじめに
ml5を利用しようとしたところ、型定義が無く、エラーが発生したため、型定義が無い時のモジュールの読み込み方法について調べました。
*なお、ml5の型定義は現在draft版を作成中。
https://gist.github.com/dikarel/38a12ce263199a41ad67c15eac7f4b45型定義が無い時のエラー
ml5を以下のようにモジュールをインポートするとエラーとなる。
import * as ml5 from "ml5";具体的には以下のようなコンパイルエラーが発生する。
Could not find a declaration file for module 'ml5'. Try npm install @types/ml5 if it exists or add a new declaration (.d.ts) file containing declare module 'ml5';型定義が無い時の読み込み方法
型定義ファイル(
d.ts
)を自作すれば良いが、面倒な時はrequire
でモジュールを読み込みます。
暗黙的にany
型になるので、型定義ファイルd.ts
が見つからないエラーは消えます。const ml5 = require('ml5')ただし
TSLint
の設定によっては[tslint] require statement not part of an import statement (no-var-requires)
という警告がでます。
// tslint:disable-next-line:no-var-requires
とコメントでrequire('ml5')
についてだけ警告を無効にします。// tslint:disable-next-line:no-var-requires const ml5 = require('ml5')この状態では
ml5
がany
型になり、型チェックも賢い補完も行われません。
自分の使う API だけ型付けして置くと、開発がスムーズです。App.tsxtype ImageClassifierOptions = { alpha: number; topk: number; version: number; }; interface IMl5 { imageClassifier( model: "MobileNet" | "Darknet" | "Darknet-tiny" | string, callback?: (error: any, result: any) => void ): undefined | Promise<any>; imageClassifier( model: "MobileNet" | "Darknet" | "Darknet-tiny" | string, options?: ImageClassifierOptions, callback?: (error: any, result: any) => void ): undefined | Promise<any>; imageClassifier( model: "MobileNet" | "Darknet" | "Darknet-tiny" | string, video?: MediaElement | HTMLVideoElement, options?: ImageClassifierOptions, callback?: (error: any, result: any) => void ): undefined | Promise<any>; } const ml5 = require('ml5') as IMl5;終わりに
以上。
- 投稿日:2021-01-09T11:42:38+09:00
npmに自作モジュールを公開する方法
はじめに
先日Node.jsの勉強中にnpmについて改めて学ぶ機会がありました。その際npmにサンプルのモジュールを公開したので、具体的なやり方をシェアします。
npmとは
Node Package Managerが正式な名称です。その名の通りNode.jsのパッケージを管理するためのツールです。ホームページは下記リンク先からアクセスできます。
npmはNode.jsをインストールする際にインストールされます。インストール済みの場合、下記コマンドでバージョンが表示されます。
npm --versionnpmに自作モジュールを公開する方法
公開までの流れ
流れは下記の通りです。
- npmのアカウントを作成する。
- 公開したいモジュールを作成する。
- npmへログインする。
- npmへ公開する。
それでは1つずつ見ていきます。
npmのアカウントを作成する
まずはnpmのアカウントを作成します。下記リンク先からSign Upできます。
公開したいモジュールを作成する
npm initでpackage.jsonを作成します。package nameを聞かれるので、npmレポジトリ上に存在していない名前を入力します。あらかじめnpmのサイトで利用されていない名前であることを確認しておきましょう。
npm initpackage.jsonができたら、private属性をpackage.jsonに追記して公開設定にします。
"private": false次に、README.mdファイルを準備します。ここにはどういった動きをするモジュールなのか、プロジェクトの概要を記述しておきます。
npmへログインする
ターミナルを起動し、プロジェクトのルートで下記コマンドを入力します。ユーザーネーム、パスワード、メールアドレスを聞かれるので入力します。
npm loginnpmへ公開
ログインができたら、下記コマンドで公開できます。
npm publish —access public※—dry runオプションをつけることで、お試しで実行することができます(実際には公開されません)。
npm publish —access public —dry run最後に
簡単ですがサンプルのモジュールをGitHub上にpushしたので、package.json等の参考までに見てください。
https://github.com/n199603/npm-study
以上、npmに自作モジュールを公開する方法でした。見ていただきありがとうございました。
- 投稿日:2021-01-09T11:00:01+09:00
NimのコードをNode.js用のJavaScriptコードにトランスコンパイルする
概要
- NimのコードをJSバックエンドでコンパイルしてNode.jsスクリプトとして実行してみます
- NimのコードからNode.js用のライブラリを生成して、Node.jsスクリプトからライブラリを読み込んで関数を呼び出してみます
NimはJavaScriptを生成できる
Nimは公式でNimのコードからJavaScriptのコードにトランスコンパイル可能です。
例えば、以下のようなNimコードに対して
index.nimproc plus*(x, y: cint): cint {.exportc.} = return x + y以下のコマンドでコンパイルします。すると、
index.nim
からindex.js
が生成されます。$ nim js index.nim $ ls index* index.js index.nimこのようにJavaScriptコードを生成できます。
しかしここで生成されるJavaScriptはフロントエンド用で、HTMLから読み込む想定のものです。
Node.jsからは扱うことはできません。NimはNode.jsのコードも生成できる
しかし、コンパイル時にオプションを渡すことにより、Node.js用のJavaScriptコードを生成できます。
Nim Backend Integration - Nim前述のコードを手直ししてNode.js用コンパイルを実施し、Node.jsで実行してみます。
index.nimproc plus*(x, y: cint): cint {.exportc.} = return x + y echo plus(1, 2)$ nim js -d:nodejs index.nim $ node index.js 3node.jsで実行できました。
NimのコードからNode.js用ライブラリを生成してみる
Node.js用の単体のスクリプトとして実行できることがわかりました。
次はNode.js用ライブラリを生成してNode.jsスクリプトから読み込めることを確認します。以下のNimコードを用意します。
以下のNimコードでは、plus
関数を定義して、Node.jsからplus
関数を呼び出せるようにするものです。lib.nimimport jsffi var module {.importc.}: JsObject proc plus*(x, y: cint): cint = return x + y module.exports.plus = plus次に、上記ライブラリを読み込んで使用する
index.js
を定義します。index.jsconst lib = require("./lib"); console.log(lib.plus(1, 2));これらのファイルを同じディレクトリに配置し、以下のコマンドを実行します。
$ nim js -d:nodejs lib.nim $ ls lib* lib.js lib.nim $ node index.js 3無事、Node.jsスクリプトから、Nimで生成したNode.js用ライブラリを読み込んで、関数を呼び出すことができました。
まとめ
以下の内容について記載しました。
- NimのコードをJSバックエンドでコンパイルしてNode.jsスクリプトとして実行できる
- コンパイルするときはjsバックエンドで
-d:nodejs
を付ける- NimのコードからNode.js用ライブラリを生成してNode.jsスクリプトからライブラリを読み込み、関数を実行できる
module {.importc.}: JsObject
でモジュールを読み込んで関数をセットする以上です
- 投稿日:2021-01-09T00:36:06+09:00
herokuデプロイ後sequelizeでPostgreSQLに接続できないときの解決法
sequelizeを使ってPostgreSQLと接続したい。
ローカル環境では接続に成功していたが、herokuにデプロイした後は失敗する。
失敗
const Sequelize = require('sequelize'); // herokuまたはローカル環境のPostgreSQLに接続する const sequelize = new Sequelize(process.env.DATABASE_URL || 'postgres://postgres:postgres@localhost/hogehoge');成功
const Sequelize = require('sequelize'); const sequelize = new Sequelize( process.env.DATABASE_URL || 'postgres://postgres:postgres@localhost/hogehoge', {dialectOptions: { ssl: true }} );ログを見ると
ssl off
(うろ覚え)とあったので、このようにオプションを追加してみると接続に成功した。
- 投稿日:2021-01-09T00:02:14+09:00
【Node.js】現在日時を取得する方法3選
目標
Node.jsで現在日時をYYYYMMDDHHmmssの14桁のフォーマットで出力します。
nodeコマンドで下記のような出力が得られるプログラムですね。$ node index.js 202101082341前提
Node.js 14.15.4
date-utils 1.2.21
moment 2.29.1Javascriptで頑張る
index.jsconst date = new Date(); const currentTime = formattedDateTime(date); console.log(currentTime) function formattedDateTime(date) { const y = date.getFullYear(); const m = ('0' + (date.getMonth() + 1)).slice(-2); const d = ('0' + date.getDate()).slice(-2); const h = ('0' + date.getHours()).slice(-2); const mi = ('0' + date.getMinutes()).slice(-2); const s = ('0' + date.getSeconds()).slice(-2); return y + m + d + h + mi + s; }date-utiliesを利用
index.jsrequire('date-utils'); const date = new Date(); const currentTime = date.toFormat('YYYYMMDDHH24MISS'); console.log(currentTime);Moment.jsを利用
index.jsconst moment = require('moment'); const currentTime = moment(); console.log(currentTime.format("YYYYMMDDHHmmss"));結論
モジュールって便利!!
- 投稿日:2021-01-09T00:02:14+09:00
【Node.js】現在日時を取得する方法4選
目標
Node.jsで現在日時をYYYYMMDDHHmmssの14桁のフォーマットで出力します。
nodeコマンドで下記のような出力が得られるプログラムですね。$ node index.js 202101082341前提
Node.js 14.15.4
date-utils 1.2.21
moment 2.29.1更新情報
【2020/01/09 toLocaleStringメソッドを利用 追加】
@il9437 様、ありがとうございます!Javascriptで頑張る
index.jsconst date = new Date(); const currentTime = formattedDateTime(date); console.log(currentTime) function formattedDateTime(date) { const y = date.getFullYear(); const m = ('0' + (date.getMonth() + 1)).slice(-2); const d = ('0' + date.getDate()).slice(-2); const h = ('0' + date.getHours()).slice(-2); const mi = ('0' + date.getMinutes()).slice(-2); const s = ('0' + date.getSeconds()).slice(-2); return y + m + d + h + mi + s; }date-utiliesを利用
index.jsrequire('date-utils'); const date = new Date(); const currentTime = date.toFormat('YYYYMMDDHH24MISS'); console.log(currentTime);Moment.jsを利用
index.jsconst moment = require('moment'); const currentTime = moment(); console.log(currentTime.format("YYYYMMDDHHmmss"));toLocaleStringメソッドを利用 (@il9437 様からのご教示)
記事を出した時点では上記のやり方で実装する必要があるとの認識でしたが、
@il9437 様にtoLocaleStringメソッドでスウェーデン語を指定してから加工する効率的な方法を教えて頂いたので記事内でも紹介しますindex.jsconst date = new Date().toLocaleString('sv').replace(/\D/g, ''); console.log(date);