nest new my-api
vi docker-compose.yml
version: "3.8"
services:
db:
container_name: translate-api-db
image: mysql:8.0
restart: always
ports:
- 13306:3306
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: translate_api_db
MYSQL_USER: translate_api_db
MYSQL_PASSWORD: db_password
volumes:
- ./db/data:/var/lib/mysql
docker で mysqlの起動
docker compose up
cd my-api
npm install @prisma/client
npm install --save-dev prisma
npx prisma init
ディレクトリ直下に 2つのファイル prisma/schema.prisma と .env が生成されます
データベースがMySQLの場合は以下のように修正します
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
}
.env 例えば以下のように設定します
DATABASE_URL="mysql://adi_db:adi_db_pass@localhost:3307/adi_db?schema=public"
コンテナ名を指定する場合は
DATABASE_URL="mysql://adi_db:adi_db_pass@docker-nest-db-1/adi_db?schema=public"
schema.prisma に テーブル情報を追記します
model User {
id Int @id @default(autoincrement())
email String @db.Text
name String @db.Text
createdAt DateTime @default(now()) @db.Timestamp(0)
updatedAt DateTime @default(now()) @updatedAt @db.Timestamp(0)
source Source[] @relation("source_fk_1")
}
model Source {
id Int @id @default(autoincrement())
userId Int
user User @relation(name: "source_fk_1", fields: [userId], references: [id])
text String @db.Text
translation Translation[] @relation("translation_fk_1")
}
model Translation {
id Int @id @default(autoincrement())
sourceId Int
source Source @relation(name: "translation_fk_1", fields: [sourceId], references: [id])
locale String @db.VarChar(8)
text String @db.Text
}
マイグレーション時に仮のテーブルを作成するので権限を付与します。
d exec -it <コンテナ名> bash
mysql -uroot -p mysql
create user translate_api_db@localhost identified by 'db_password';
grant create, alter, drop, references on *.* to translate_api_db;
実行後は exit でコンテナから抜けます。
次のコマンドでマイグレーションを実行します
npx prisma migrate dev
マイグレーションファイル名を入力されるので、次のように 行った操作を簡単に入力します。(実行日時は自動的にセットされます)
add_tables
実行すると
本番サーバーではロールバックすることがない(修正する場合は、修正するバイブレーションを追加すると言う方式)ため
# Prisma Studioの起動
npx prisma studio
# データベースをリセットしDBへ反映
npx prisma migrate reset
# マイグレーションのステータスチェック
npx prisma migrate status
# マイグレーションの実行・DBへ反映
npx prisma migrate deploy
# 型情報の生成
npx prisma generate
ファイル名 /prisma/seed.ts を作成します。
vi prisma/seed.ts
prisma/seed.ts を 以下の内容で保存します
import { PrismaClient, Prisma } from '@prisma/client';
const prisma = new PrismaClient();
const insertData: Prisma.TodoCreateInput[] = [
{
title: 'タイトル01',
description: '説明01',
status: 'AAA01',
createdAt: new Date(),
updatedAt: new Date(),
},
{
title: 'タイトル02',
description: '説明02',
status: 'AAA02',
createdAt: new Date(),
updatedAt: new Date(),
},
];
const transfer = async () => {
const coffeeShops = insertData.map((c) => {
return prisma.todo.create({ data: c });
});
return await prisma.$transaction(coffeeShops);
};
const main = async () => {
await transfer();
};
main()
.then(() => {
console.log('seed finished.');
})
.catch((e) => {
console.error(e);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});
package.json 次のコードを追記します
"prisma": {
"seed": "ts-node ./prisma/seed.ts"
},
npx prisma db seed
または 直接ファイルを実行してもokです
npx ts-node prisma/seed.ts
ターミナルから以下を実行します。
brew install anyenv
echo 'eval "$(anyenv init -)"' >> ~/.bash_profile
echo $SHELL -l
一旦ターミナルを終了して、再度起動。
メッセージが出るので次のコマンドを実行
anyenv install --init
anyenv install nodenv
exec $SHELL -l
これでインストールは完了です。
yarn自動インストールの設定
mkdir -p "$(nodenv root)/plugins"
git clone https://github.com/pine/nodenv-yarn-install.git "$(nodenv root)/plugins/nodenv-yarn-install"
これを行うだけでnode.jsインストール時に同時に自動的にyarnもインストールしてくれます
yarn を手動でインストールする 場合はこちらのコマンド実行
npm install --global yarn
nodenv install -l
nodenv install 18.14.0
M1 Macには バージョン16以上しかインストールすることができませんのでご注意ください
nodenv global 18.14.0
フォルダ「my-project」以下は v16.19.0 を使用するようにセットします
cd my-project
nodenv install 16.19.0
nodenv local 16.19.0
これで、フォルダ「my-project」以下は必ず 16.19.0 になります。
node -v
正しくバージョンが表示されればOKです。
nodenv versions
touch $(nodenv root)/default-packages
cd ${NODENV_ROOT}
git pull
cd ${NODENV_ROOT}/plugins/node-build/
git pull
~/.bash_profile に記述しておきます
# Node.js Global pathをセット
node_global_path=$(npm root -g)
echo ${node_global_path}
export NODE_PATH=${node_global_path}
curl https://get.volta.sh | bash
(インストール後にターミナルを終了して、再起動します)
バージョン 14.17.0 をインストールする例
volta install node@14.17.0
バージョン 18系の 最新をインストールする例
volta install node@18
volta list all
(インストール後にターミナルを終了して、再起動します)
node -v
rm -rf ~/.volta
export VOLTA_HOME="$HOME/.volta"
export PATH="$VOLTA_HOME/bin:$PATH"
サーバーを立てたいディレクトリに移動した後
npx http-server
これだけで okです。
サーバーを立てたいディレクトリに移動した後
npm install http-server
./node_modules/http-server/bin/http-server
これだけで okです。
例えばポート番号を変更するには以下のように指定します
./node_modules/http-server/bin/http-server --port 50001
Command | Description | Defaults |
---|---|---|
-p or --port
|
Port to use. Use -p 0 to look for an open port, starting at 8080. It will also read from process.env.PORT . |
8080 |
-a |
Address to use | 0.0.0.0 |
-d |
Show directory listings | true |
-i |
Display autoIndex | true |
-g or --gzip
|
When enabled it will serve ./public/some-file.js.gz in place of ./public/some-file.js when a gzipped version of the file exists and the request accepts gzip encoding. If brotli is also enabled, it will try to serve brotli first. |
false |
-b or --brotli
|
When enabled it will serve ./public/some-file.js.br in place of ./public/some-file.js when a brotli compressed version of the file exists and the request accepts br encoding. If gzip is also enabled, it will try to serve brotli first. |
false |
-e or --ext
|
Default file extension if none supplied | html |
-s or --silent
|
Suppress log messages from output | |
--cors |
Enable CORS via the Access-Control-Allow-Origin header |
|
-o [path] |
Open browser window after starting the server. Optionally provide a URL path to open. e.g.: -o /other/dir/ | |
-c |
Set cache time (in seconds) for cache-control max-age header, e.g. -c10 for 10 seconds. To disable caching, use -c-1 . |
3600 |
-U or --utc
|
Use UTC time format in log messages. | |
--log-ip |
Enable logging of the client's IP address | false |
-P or --proxy
|
Proxies all requests which can't be resolved locally to the given url. e.g.: -P http://someurl.com | |
--proxy-options |
Pass proxy options using nested dotted objects. e.g.: --proxy-options.secure false | |
--username |
Username for basic authentication | |
--password |
Password for basic authentication | |
-S , --tls or --ssl
|
Enable secure request serving with TLS/SSL (HTTPS) | false |
-C or --cert
|
Path to ssl cert file | cert.pem |
-K or --key
|
Path to ssl key file | key.pem |
-r or --robots
|
Automatically provide a /robots.txt (The content of which defaults to User-agent: *\nDisallow: / ) |
false |
--no-dotfiles |
Do not show dotfiles | |
--mimetypes |
Path to a .types file for custom mimetype definition | |
-h or --help
|
Print this list and exit. | |
-v or --version
|
Print the version and exit. |
npm install @aws-sdk/client-s3
npm install @aws-sdk/s3-request-presigner
geturl.js
import { GetObjectCommand, S3Client } from '@aws-sdk/client-s3';
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
// ************************
const accessKeyId = 'XXXXX';
const secretAccessKey = 'XXXXX';
const region = 'XXXXXXXXXX';
const bucket = 'my-bucket';
const key = 'my-file.png';
// ************************
const client = new S3Client({
region: region,
credentials: {
accessKeyId: accessKeyId,
secretAccessKey: secretAccessKey,
},
});
const url = await getPresignedUrl(client, bucket, key, 60*60*8);
console.log( `the url is ${url}` );
async function getPresignedUrl(client, bucket, key, expiresIn) {
const objectParams = {
Bucket: bucket,
Key: key,
};
const url = await getSignedUrl(client, new GetObjectCommand(objectParams), { expiresIn });
return url
};
package.json
"type": "module"
node geturl.js
一言でモックと言っても、実は以下のように分類されます.
dummy
, fake
, spy
, stub
, mock
Jestでは 大きく分けて、次の2つ jest.mock
, jest.spyOn
を使います。
.prettierrc.js
module.exports = {
arrowParens: 'always',
bracketSameLine: false,
bracketSpacing: true,
htmlWhitespaceSensitivity: 'css',
insertPragma: false,
jsxSingleQuote: true,
printWidth: 120,
proseWrap: 'preserve',
quoteProps: 'as-needed',
requirePragma: false,
semi: false,
singleQuote: true,
tabWidth: 2,
trailingComma: 'none',
useTabs: false
}
arrowParens : alwaysの時 Arrow関数の引数が1つでも括弧がつく。avoid の時付かない
・ヘッダ、ペイロード(データ本体)、署名をドットでつないで Base64 エンコードしたもの。
・中身は Base64エンコードしただけなので、ペイロードの中身は誰でも見ることができる。
・電子署名を使用して、ペイロードが改ざんされていないか?、正規の発行元以外から勝手に発行されたものかどうか?などを検証することができる。
・よく「JWT脆弱性」というワードが出てくるがJWT自体に脆弱性はない。
(正しくは「JWTを使用した認証システムに脆弱性が存在することがある」)
https://github.com/auth0/node-jsonwebtoken
alg Parameter Value | Digital Signature or MAC Algorithm |
---|---|
HS256 | HMAC using SHA-256 hash algorithm |
HS384 | HMAC using SHA-384 hash algorithm |
HS512 | HMAC using SHA-512 hash algorithm |
RS256 | RSASSA-PKCS1-v1_5 using SHA-256 hash algorithm |
RS384 | RSASSA-PKCS1-v1_5 using SHA-384 hash algorithm |
RS512 | RSASSA-PKCS1-v1_5 using SHA-512 hash algorithm |
PS256 | RSASSA-PSS using SHA-256 hash algorithm (only node ^6.12.0 OR >=8.0.0) |
PS384 | RSASSA-PSS using SHA-384 hash algorithm (only node ^6.12.0 OR >=8.0.0) |
PS512 | RSASSA-PSS using SHA-512 hash algorithm (only node ^6.12.0 OR >=8.0.0) |
ES256 | ECDSA using P-256 curve and SHA-256 hash algorithm |
ES384 | ECDSA using P-384 curve and SHA-384 hash algorithm |
ES512 | ECDSA using P-521 curve and SHA-512 hash algorithm |
none | No digital signature or MAC value included |
引用: https://github.com/auth0/node-jsonwebtoken
https://jwt.io/ にトークンを入力するとヘッダに
{
"alg": "RS256",
"kid": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"typ": "JWT"
}
と表示されます。("alg": "RS256" なので RS256)
HS256
HS256( _ hmac _ with SHA-256)は、 対称アルゴリズム で、2者間で共有される唯一の(秘密)キーを持ちます。署名の生成と検証の両方に同じキーが使用されるため、キーが危険にさらされないように注意する必要があります。
RS256
RS256( SHA-256 を持つRSA署名)は 非対称アルゴリズム で、公開鍵と秘密鍵のペアを使用します。アイデンティティプロバイダには署名の生成に使用される秘密(秘密)鍵があります。 JWTの利用者は、署名を検証するための公開鍵を入手します。秘密鍵ではなく公開鍵を保護する必要がないため、ほとんどのアイデンティティプロバイダは、(通常メタデータURLを通じて)消費者が簡単に入手して使用できるようにしています。
HS256は危険です。RS256を使いましょう。
Google Firebase Auth , Amazon AWS Cognito の accessToken は RS256 です。
サーバーサイドではクライアントから受け取ったjwtの以下の点を検証します
・jwtのペイロード(データ本体)に「改ざんがあるかどうか?」の検証
・想定している発行元以外から「勝手に発行されたjwtかどうか?」の検証
・jwtの有効期限が「有効期限内であるかどうか?(jwtが有効か?)」の検証
Google Firebase の Authentication で受け取ったトークンを検証します。
検証に使用する公開鍵はGoogleのサーバから取得します。
npm install jsonwebtoken axios
const axios = require("axios").default;
const jwt = require("jsonwebtoken");
/**
*
* @param {string} accessToken
*/
const verifyJWT = async (accessToken) => {
const kid = getKidFromJwtHeader(accessToken);
const publicKey = await getPublicKeyFromFirebase('https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com', kid);
jwt.verify(accessToken, publicKey, function (err, decoded) {
if (err) {
console.log('● verifyでエラーが発生');
console.log(err);
}
else if (decoded) {
console.log('● verify OK');
console.log(decoded);
}
else {
console.log('● JWTのデコードができませんでした');
}
});
}
/**
* jwtからヘッダの中のkidを取得
* @param {string} token
* @returns {string} key
*/
const getKidFromJwtHeader = (token) => {
const jwtHeader = getJwtHeader(token)
const obj = JSON.parse(jwtHeader)
return obj.kid
}
/**
* jwtからヘッダを取得
* @param {string} token
* @returns {string} key
*/
const getJwtHeader = (token) => {
const tokenHeader = token.split('.')[0]
const jwtHeader = Buffer.from(tokenHeader, 'base64').toString()
return jwtHeader
}
/**
* Firebaseのjwt検証用公開鍵を取得する
* @param {string} url
* @param {string} kid
* @returns {string} key
*/
const getPublicKeyFromFirebase = async (url, kid) => {
const res = await axios.get(url)
const publicKeys = res.data
const key = publicKeys[kid]
return key
}
verifyJWT("<検証したいトークン>");
○「HTTP OnlyでSecureなCookieに保存する」
×「LocalStorageに保存する」 ( local storageはあらゆるJavaScriptコードから自由にアクセスできてしまいます )
・共通鍵のアルゴリズムは選択しない
・鍵の長さは256bit以上とする
・検証をせずにデコードだけすると、改ざんまたは勝手に発行されたトークンを見ている可能性がある
(なので alg=none を使用するのはありえない)
・認証NGとなるjwtでも、データの中身は誰でも見れるので機密情報はjwtには含めない
vanilla js で jest で テストファイルの中にimpor export を使用すると次のようなエラーが表示されることがあります
Jest encountered an unexpected token
Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.
これを node.js 変換によって回避する方法はこちらです
export NODE_OPTIONS=--experimental-vm-modules
"type": "module" を追加します。
{
"devDependencies": {
"jest": "^28.1.2"
},
"type": "module"
}
module.exports = {
testMatch: ['<rootDir>/**/*.test.js'],
};
↓
export default {
testMatch: ['<rootDir>/**/*.test.js'],
};
以上です。
npm test
または
npx jest
してみましょう
WSL2をインストールしたら、コマンドプロンプトではなく Windowsターミナルから Ubuntu を選択して、unixを起動します。
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
echo 'eval "$(/home/kato/.linuxbrew/bin/brew shellenv)"' >> /home/kato/.bash_profile
eval "$(/home/kato/.linuxbrew/bin/brew shellenv)"
brew install anyenv
anyenv init
echo 'eval "$(anyenv init -)"' >> ~/.bash_profile
exec $SHELL -l
anyenv install --init
anyenv install nodenv
exec $SHELL -l
nodenv --version
node.jsインストール時に同時に自動的にyarnもインストールしてくれるように設定する
mkdir -p "$(nodenv root)/plugins"
git clone https://github.com/pine/nodenv-yarn-install.git "$(nodenv root)/plugins/nodenv-yarn-install"
nodenv install 16.13.2
nodenv global 16.13.2
node -v
server.js
'use strict';
const express = require('express');
const serveIndex = require('serve-index');
const fs = require('fs');
const port = 3000;
const app = express();
const server = require('https').createServer({
key: fs.readFileSync('./privatekey.pem'),
cert: fs.readFileSync('./cert.pem'),
}, app)
app.use(express.static('.'));
app.use(serveIndex('.', {icons: true}));
server.listen(port, () => console.log(`Server Started https://127.0.0.1:${port}`))
nodeモジュールのインストール
npm init -y
npm i -S express serve-index
cert.pem , privatekey.pem の作成
openssl req -x509 -newkey rsa:2048 -keyout privatekey.pem -out cert.pem -nodes -days 365
サーバー起動
node server.js
以下の手順でGoogle Chromeからアクセスできるようにします
node
module.paths
( Ctrl+C 2回押して抜けます。)
SET NODE_PATH=C:\laragon\bin\nodejs\node-v14\node_modules
node
module.paths
reactアプリの初期化(TypeScript)
npx create-react-app test-app --template typescript
reactアプリの初期化(JavaScript + TailwindCSS)
npx create-next-app my-first-next-with-tailwind -e with-tailwindcss
npm install -g firebase-tools
バージョン8を指定して入れる場合は以下のようにインストールします
(バージョン9からファイルサイズが小さくなったため 9がオススメですが。)
npm install -g firebase-tools@8
firebase --version
8.20.0
firebase-tools のバージョン違いによりエラーが出ることがあるので一旦ログアウトを行ってから再度ログインします
firebase logout
firebase login
firebase projects:list
firebase init
例えば以下のように質問に答えます
? Which Firebase features do you want to set up for this directory?
→ (ホスティングを行う場合) ◯ Hosting: Configure files for Firebase Hosting and (optionally) set up GitHub Action deploys
→ (Firestoreを使う場合) ◯ Firestore: Configure security rules and indexes files for Firestore
? What do you want to use as your public directory?
→ build
? Configure as a single-page app (rewrite all urls to /index.html)? (y/N)
→ y
? Set up automatic builds and deploys with GitHub? (y/N) n
→ n
npm run build
firebase deploy
Hosting URL: https://my-app-xxxxx.web.app
firebase hosting:disable
URLにアクセスしてNOT FOUNDになっていることを確認します。
"build": {
"mac": {
"icon": "./icon.png"
},
"win": {
"icon": "./icon.png"
},
}
package.json に以下の設定を追加します。 (アイコン画像は path/to/icon.icns に設置)
{
...
"config": {
"forge": {
...
"electronPackagerConfig": {
"icon": "path/to/icon.icns"
},
...
}
}
}
package.json に以下の設定を追加します。 (アイコン画像は path/to/icon.icns に設置)
{
...
"config": {
"forge": {
...
"packagerConfig": {
"icon": "path/to/icon.icns"
},
...
}
}
}
npm run package で再度ビルドを行います
なおアイコン画像の形式はMacの場合icns形式である必要があります。
こちらのウェブサイトからPing画像からicnsへ変換することができます
const { shell } = require('electron')
shell.openExternal('http://localhost/')
const { shell } = require('electron')
shell.openPath('/Users/hogehoge/テスト フォルダ/001');
vue create electron-vue-hello
cd cd electron-vue-hello
npm run serve
http://localhost:8080/ にアクセスして起動することを確認します
control + c でプロセスをkillして次のコマンドからインストールします
vue add electron-builder
package.json 次のコマンドが追加されたことを確認します
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"electron:build": "vue-cli-service electron:build",
"electron:serve": "vue-cli-service electron:serve",
"postinstall": "electron-builder install-app-deps",
"postuninstall": "electron-builder install-app-deps"
},
npm run electron:serve
npm run electron:build
ここまで来れました準備は全て完了です次はプログラムを記述していきましょう。
npm run electron:build
例
"main": "src/index.js",
index.js の createWindow にイベントを記述していきます
例
const createWindow = () => {
// Create the browser window.
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
});
// and load the index.html of the app.
mainWindow.loadFile(path.join(__dirname, 'index.html'));
// Open the DevTools.
mainWindow.webContents.openDevTools();
};
// ● 続けてイベントを記述 ↓
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow);
// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
app.on('activate', () => {
// On OS X it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});
npm install electron --save-dev
npx create-electron-app my-hello-app
cd my-hello-app
npm start
アプリが起動します
touch src/renderer.js
renderer.js
const { ipcRenderer } = require('electron')
// DOM Ready
document.addEventListener("DOMContentLoaded", function () {
/**
* my-btn を押すとメインプロセスへデータを渡す
*/
const btn = document.getElementById('my-btn')
btn.addEventListener('click', () => {
ipcRenderer.send('MessageMain', { message: 'レンダラーからメインプロセスへメッセージです。' });
console.log( '● レンダラーからメッセージを送信しました' );
});
});
index.html で renderer.js を読み込みます。
index.html
<script src="renderer.js"></script>
index.js でメッセージを受けれるようにしておきます。
index.js
/**
* レンダラープロセスからデータの受信 (MessageMain)
*
*/
ipcMain.on('MessageMain', (event, arg) => {
console.log( '● arg' );
console.log( arg );
})
const mainWindow = new BrowserWindow({
width: 800,
height: 600
});
↓
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
},
});
npm run make
out フォルダにアプリができます。 (ファイルサイズが大きいのは諦めましょう)
npx electron-forge make --arch=ia32
こちらを clone してビルドしてみましょう。 https://github.com/electron-react-boilerplate/electron-react-boilerplate
https://blog.craftz.dog/how-to-make-your-electron-app-launch-1000ms-faster-bcc2997fa1f7
npm install electron-builder --save-dev
node_modules/.bin/electron-builder --mac --x64
npx electron-builder --win --x64
npx electron-builder --win --ia32
npm install --save dotenv
「プロジェクトのトップディレクトリ」に .env ファイルを作成します
.env
HOGE=テスト文字列
index.js
//.envに記述したデータを読み込み
require('dotenv').config();
// 環境変数の表示
console.log('● process.env');
console.log( process.env );
ビルドしたときもビルドしたトップディレクトリに .env を設置する必要があります。
const { shell } = require('electron')
shell.openExternal('https://www.google.com/')
app.on('ready', createWindow);
↓
const gotTheLock = app.requestSingleInstanceLock();
if (!gotTheLock) {
.... 何かしらの行いたい処理
setTimeout( function(app) {
app.exit();
}, 1500, app );
} else {
app.whenReady().then(() => {
.... 何かしらの行いたい処理
});
}
yarn add lodash
yarn add --dev @types/lodash
または
npm install lodash
npm install --D @types/lodash
次のようなコレクション系データがあったとします。
var stageItems = [
{ id: 5, name: "山田" },
{ id: 6, name: "斎藤" },
{ id: 7, name: "朝倉" },
{ id: 8, name: "神山" },
{ id: 9, name: "山田" },
];
// id = 6 なアイテムを選択します
const item = _.find(stageItems, { id:6 });
// name:'山田' なアイテムを全て返します
const item = _.filter(stageItems, { name:'山田' });
なお、コレクションだけでなくこのようなオブジェクトのオブジェクトでも検索可能です
var stageItems = {
5: { id: 5, name: "山田" },
6: { id: 6, name: "斎藤" },
7: { id: 7, name: "朝倉" },
8: { id: 8, name: "神山" },
9: { id: 9, name: "山田" },
};
const obj1 = {
id: "hoge",
name: "ほげ",
phone: "123-4567"
};
const newObj = _.omit(obj1, ["id", "phone"]); // {name: "ほげ"}
// id = 6 が 何番目の要素なのかを検索 ( 0 が先頭 )
const added_i = this.stageItems.findIndex(({id}) => id === 6);
alert( added_i ); // 2番目の要素なので 1
const sortedItems = sortBy(items, "name");
// 逆順にする場合は .reverse() を実行します
const sortedItems = sortBy(items, "name").reverse();
// =>
// [
// { name: 'coffee', amount: 500 },
// { name: 'juice', amount: 500 },
// { name: 'lunch-a', amount: 1000 },
// { name: 'lunch-b', amount: 1200 },
// { name: 'smile', amount: 0 },
// { name: 'suger' }
// ]
引用: https://hbsnow.dev/blog/js-sort/
itemDelete: function ( argId ) {
alert("このidを削除します" + argId);
this.stageItems = _.remove(this.stageItems, function (o) { return o.id !== argId; });
},
drop : 先頭 n個 削除
dropRight : 末尾 n個 削除
const data2 = _.dropRight(data, 3) // 先頭 3つを削除
const data2 = _.dropRight(data, 2) // 末尾 2つを削除
const originalAttachFilesIDs = _.map(originalAttachFiles, 'fileID')
const simpleItems = _.map(stageItems , (data) => {
return { name: data.name }
})
pluckメソッドは version 4 から .map() に統合されたようです。
// in 3.10.1
_.pluck(objects, 'a'); // → [1, 2]
_.map(objects, 'a'); // → [1, 2]
// in 4.0.0
_.map(objects, 'a'); // → [1, 2]
・JavaScriptではオブジェクトのコピーは参照コピーとなります。
・JavaScriptでは スプレッド構文やObject.assignを使ったコピーは1階層目は値がコピーされますが、
2階層以降にオブジェクトがあった場合 参照コピー となります。
const clonedItem = _.cloneDeep(item);
const taguser1 = {
id: 1,
name: "hoge",
tags:[
{
id:1,
name: "Windows"
} ,
{
id:2,
name: "mac"
}
]
};
const taguser2 = { ...taguser1 }; // 参照のコピー(オブジェクトをコピーした場合は参照がコピーされる)
const taguser3 = Object.assign({}, taguser1);
taguser1.id = 99999;
taguser1.tags[0].name = "ウィンドウズ"
console.log( '● taguser1' );
console.log( taguser1 );
console.log( '● taguser2' );
console.log( taguser2 );
console.log( '● taguser3' );
console.log( taguser3 );
結果
● taguser1
{ id: 99999,
name: 'hoge',
tags: [ { id: 1, name: 'ウィンドウズ' }, { id: 2, name: 'mac' } ] }
● taguser2
{ id: 1,
name: 'hoge',
tags: [ { id: 1, name: 'ウィンドウズ' }, { id: 2, name: 'mac' } ] }
● taguser3
{ id: 1,
name: 'hoge',
tags: [ { id: 1, name: 'ウィンドウズ' }, { id: 2, name: 'mac' } ] }
参考 : https://qiita.com/waterada/items/62b32930d3c3668ff3d2
https://www.labnol.org/code/import-lodash-211117
import capitalize from 'lodash.capitalize';
const capitalizeFirstName = (name) => {
const result = capitalize(name);
console.log(response);
};
import memoize from 'lodoash/memoize';
const expensiveFunction = (input) => {
return input * input;
};
const memoizedFunction = memoize(expensiveFunction);
console.log(memoizedFunction(5)); // Calculates the square of 5
console.log(memoizedFunction(5)); // Returns the cached value
↓
const multiply = (a, b) => {
return a * b;
};
const resolver = (...args) => {
return JSON.stringify(args);
};
const memoizedMultiply = _.memoize(multiply, resolver);
console.log(memoizedMultiply(1, 2)); // Calculates the product of 1 and 2 and caches the result
console.log(memoizedMultiply(1, 3)); // Calculates the product of 1 and 3 and caches the result
console.log(memoizedMultiply(1, 2)); // Returns the cached value
https://github.com/you-dont-need/You-Dont-Need-Lodash-Underscore
https://youmightnotneed.com/lodash/
// Native JavaScript
var users = [
{ 'id': 1 , 'user': 'barney', 'age': 36, 'active': true },
{ 'id': 2 , 'user': 'fred', 'age': 40, 'active': false },
{ 'id': 3 , 'user': 'pebbles', 'age': 1, 'active': true }
]
const id = 3;
const user = users.find(function (o) { return o.id === id; })
// Underscore/Lodash
var array1 = [{name: "Alice"}, {name: "Bob"}, {name: "Jeremy"}]
var names = _.pluck(array1, "name")
console.log(names)
// output: ["Alice", "Bob", "Jeremy"]
// Native
var array1 = [{name: "Alice"}, {name: "Bob"}, {name: "Jeremy"}]
var names = array1.map(function(x){
return x.name
})
console.log(names)
// output: ["Alice", "Bob", "Jeremy"]
アロー関数でこのように記述できます
const names = array1.map(x => x.name);
// Underscore/Lodash
var array = [1, 2, 1, 4, 1, 3]
var result = _.uniq(array)
console.log(result)
// output: [1, 2, 4, 3]
// Native
var array = [1, 2, 1, 4, 1, 3];
var result = [...new Set(array)];
console.log(result)
// output: [1, 2, 4, 3]
// Underscore/Lodash
console.log(_.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]))
// output: [1, 2]
// Native
var arrays = [[1, 2, 3], [101, 2, 1, 10], [2, 1]];
console.log(arrays.reduce(function(a, b) {
return a.filter(function(value) {
return b.includes(value);
});
}));
// output: [1, 2]
// ES6
let arrays = [[1, 2, 3], [101, 2, 1, 10], [2, 1]];
console.log(arrays.reduce((a, b) => a.filter(c => b.includes(c))));
// output: [1, 2]
// Lodash
var object = { a: 1, b: 'settings', c: { d: 'test' } };
var hasA = _.has(object, 'a');
var hasCWhichHasD = _.has(object, 'c.d')
console.log(hasA);
// output: true
console.log(hasCWhichHasD);
// output: true
// Native
const has = function (obj, key) {
var keyParts = key.split('.');
return !!obj && (
keyParts.length > 1
? has(obj[key.split('.')[0]], keyParts.slice(1).join('.'))
: hasOwnProperty.call(obj, key)
);
};
var object = { a: 1, b: 'settings' };
var result = has(object, 'a');
// output: true
npx create-next-app
実行するとサイト名を
What is your project named? …
と聞かれますので入力します。( 例: test-app)
アプリ名を指定して新規作成する場合は
npx create-next-app --example parameterized-routing test-app
のようにすると
example指定: parameterized-routing
アプリ名: test-app
で新規作成します。
npm run dev
npm run build
npm run start
新規ファイルを作成
vi pages/page01.js
import Head from 'next/head'
import styles from '../styles/Home.module.css'
export default function Home() {
return (
<div>
<h1>Hello page01</h1>
</div>
)
}
これが URL
http://localhost:3000/page01
にあたります。
<Link href="/page02">
<button>page02</button>
</Link>
package.json
{
"scripts": {
...
"build_static": "next build && next export -o dist",
},
( "build_static"の行を追加します )
ビルドの実行
npm run build_static
/dist/ フォルダに書出が行われます。
JSON ファイルにコメントを記述することはできませんが以下のように無効なパラメーターとして登録しておくことでコメントを対応させることができます。
_comment にコメントを記述する
{
"_comment": "comment text goes here...",
"glossary": {
"title": "example glossary",
"GlossDiv": {
"title": "S",
"GlossList": {
}
}
}
}
npm i puppeteer
vi test_puppeteer.js
以下の内容で保存します。
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({ args: ['--no-sandbox', '--disable-setuid-sandbox'] });
const page = await browser.newPage();
await page.goto('https://google.co.jp/');
await page.screenshot({path: __dirname + '/test_puppeteer.png'});
await browser.close();
})();
実行します
node test_puppeteer.js
libX11-xcb.so.1: cannot open shared object file: No such file or directory
と言うようなエラーが表示される場合があります
chromiumをインストールします(Centos stream)
dnf install -y chromium
libXScrnSaverをインストールします(Centos stream)
dnf install -y chromium
その他参考 : https://github.com/puppeteer/puppeteer/issues/5361
puppeteer と puppeteer-coreの違いは?
puppeteerをインストールした場合はGoogle Chromeのバイナリを追加でダウンロードします。
puppeteer-coreは使用しているマシンに既にインストール済みのGoogle Chromeを使用します。(Google Chromeのダウンロードは行いません)
npm i puppeteer-core
vi test02.js
const puppeteer = require('puppeteer-core');
(async () => {
const browser = await puppeteer.launch({
executablePath: '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
});
const page = await browser.newPage();
await page.goto('https://google.co.jp/');
await page.screenshot({path: 'test02.png'});
await browser.close();
})();
node test02.js
const browser = await puppeteer.launch();
↓
const browser = await puppeteer.launch({ args: ['--no-sandbox', '--disable-setuid-sandbox'] });
としておきましょう。
npm install -g vsce
npm install -g yo
yo doctor
vsce --version
1.95.1
バージョン番号が返ってくればOKです。
Azure Dev Ops にログインして「Profile」→「Personal access tokens」から Personal Access Tokens を作成します。
設定はこちらを参考にします。
作成したトークンをコピーしておきます。
vsce login <ユーザー名>
(コピーしておいたトークンを使ってログインします)
作成した拡張をgithubにpushします。(詳細は割愛します)
"icon": "icon.png",
"repository": {
"type": "git",
"url": "https://github.com/xxxxx/YOUR-GIT-PROJECT-NAME"
},
"bugs": {
"url": "https://github.com/xxxxx/YOUR-GIT-PROJECT-NAME/issues"
},
vsce publish
vsce publish -p <token>
コマンドのヒストリにトークン文字列が残るので注意しましょう
npm ls で deduped がたくさん出るようなら yarn への乗り換えを検討しましょう。
● yarn を使用する
brew install yarn
● yarn のバージョンを確認する
yarn -v
1.19.1
● npmの代わりに yarn を使用する
npm install image-js
↓
yarn add image-js
Webpack4 + Babel を使用して IE11 での動作を確認する。
ローカルにインストールします( サイズはさほど大きくなく、46MB 程度なので複数のローカル環境に入れてもあまりディスクの負担になりません)
webpackとwebpack-cliとwebpack-dev-serverをインストールする
cd YOUR-PROJECT-FOLDER
npm install webpack webpack-cli webpack-dev-server -D
npm init -y
なお、オプションの -D は --save-dev と同じです
https://docs.npmjs.com/misc/config
./src/index.js
import {hellowebpack} from './f';
hellowebpack();
./src/f.js
export function hellowebpack() {
alert('hellowebpack!!!');
}
npx webpack
./dist/main.js が以下のような内容で作成されます
!function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=0)}([function(e,t,r){"use strict";r.r(t),alert("helloメソッドが実行された。")}]);
javascriptのコードが圧縮されています。
これは 「 mode: 'production' 」な本番仕様です。
開発環境では圧縮しない 「 mode: 'development' 」を使用することでコンパイル時間を圧倒的に短縮することができます。
( ↓ やり方はこの後で)
webpack.config.js
watch: true を追加すると watch します
module.exports = {
........................
watch: true
};
./dist/index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>webpack test</title>
<script src="./main.js"></script>
</head>
<body>
</body>
</html>
mode: 'development' の記述はここに行います。
module.exports = {
devtool: 'inline-source-map' ,
mode: 'development', // (development: 開発 production: 本番)
entry: './src/index.js',
output: {
path: `${__dirname}/dist`,
filename: 'main.js'
},
devServer: {
contentBase: 'dist',
open: true
}
};
npx webpack-dev-server
これでサーバが起動し、自動的に ./dist/index.html を読み込んで「hellowebpack!!!」アラートが表示されれば成功です。
webpack-dev-serverを起動しておくと、対象ファイルが更新された時に自動でリコンパイルがかかります。 それを確認してみます。
./src/f.js を以下のように変更して保存する
export function hellowebpack() {
alert('hellowebpack!!! 変更しました。');
}
ブラウザに切り替えて、自動的に更新されていることを確認します。
自動更新機能は便利ですね!
「control + c 」で webpack-dev-serverを終了してから webpack ビルドを行う。
npx webpack
./dist/ 以下の全てのファイルを本番WEBサーバへアップロードして表示させて確認します。
webpack ではデフォルトでは js しか読み込めません。 css を読み込むようにするには
style-loader css-loader をインストールする
npm i -D style-loader css-loader
webpack.config.js の設定項目の一番下に以下を追加します。
module: {
rules: [
{
test: /\.css/,
use: [
'style-loader',
{loader: 'css-loader', options: {url: false}},
],
},
]
}
● webpack で js 以外に scss (sass) も読み込めるようにする こちらが今一番WEB制作的には一番現実的でしょう。
npm i -D webpack webpack-cli sass-loader sass style-loader css-loader
webpack.config.js を次のようにします。
// [定数] webpack の出力オプションを指定します
// 'production' か 'development' を指定
const MODE = "development";
// ソースマップの利用有無(productionのときはソースマップを利用しない)
const SOURCEMAP_FLAG = MODE === "development"; // true or false
const ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
// モード値を production に設定すると最適化された状態で、
// development に設定するとソースマップ有効でJSファイルが出力される
mode: MODE ,
module: {
rules: [
{
// 対象となるファイルの拡張子(scss)
test: /\.scss$/,
// Sassファイルの読み込みとコンパイル
use: ExtractTextPlugin.extract([
// CSSをバンドルするための機能
{
loader: 'css-loader',
options: {
// オプションでCSS内のurl()メソッドの取り込まない
url: false,
// ソースマップの利用有無
sourceMap: true,
// Sass+PostCSSの場合は2を指定
importLoaders: 2
},
},
// PostCSSのための設定
{
loader: 'postcss-loader',
options: {
// PostCSS側でもソースマップを有効にする
sourceMap: true,
// ベンダープレフィックスを自動付与する
plugins: () => [require('autoprefixer')]
},
},
// Sassをバンドルするための機能
{
loader: 'sass-loader',
options: {
// ソースマップの利用有無
sourceMap: SOURCEMAP_FLAG,
}
}
]),
},
],
},
plugins: [
new ExtractTextPlugin('style.css'),
],
// source-map方式でないと、CSSの元ソースが追跡できないため
devtool: "source-map"
};
引用元 : https://qiita.com/hiroseabook/items/383d54a87fd5ab4108bc
ES6で書いたJavaScriptは IE11 では使えないので babel をwebpackから呼び出してIE11でも使える状態でコンパイルします
./src/Myclass.js
export class Myclass {
constructor(id,userName) {
this.id = id;
this.userName = userName;
}
alertUserName() {
alert(this.userName);
}
}
./src/Myclass.js
import {hellowebpack} from './f';
import {Myclass} from './Myclass.js';
hellowebpack();
var m = new Myclass(1, 'DOWN TOWN');
m.alertUserName();
npm install -D webpack webpack-cli babel-loader @babel/core @babel/preset-env
webpackと合わせると 70MB くらいになります
下記のように書き換えます。
module.exports = {
mode: 'production', // development or production
entry: './src/index.js',
output: {
path: `${__dirname}/dist`,
filename: 'main.js'
},
devServer: {
contentBase: 'dist',
open: true
} ,
module: {
rules: [{
test: /\.js$/,
use: [{
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env',
]
}
}]
}]
}
};
npx webpack
本番サーバへアップロードして IE11で確認します。
Express を立ち上げるほどではないときは次のようにしてサーバを立ち上げます。
myserver.js
var fs = require('fs');
var http = require('http');
var server = http.createServer();
server.on('request', function(req, res) {
fs.readFile(__dirname + '/index.html', 'utf-8', function (err, data) {
if (err) {
res.writeHead(404, {'Content-Type' : 'text/plain'});
res.write('page not found');
return res.end();
}
res.writeHead(200, {'Content-Type' : 'text/html'});
res.write(data);
res.end();
});
});
server.listen(1337, '127.0.0.1');
console.log( 'Server Started.\nopen "http://127.0.0.1:1337/"' );
実行方法
node myserver.js
でWEBサーバを立ち上げた後 http://127.0.0.1:1337/ へアクセスします。
https://packagecontrol.io/packages/JsPrettier
Sublime Textのパッケージコントローラーからインストールします
(command + shift + p) →【Install Package を選択】→【Js Prettierを選択】
【Package settings】→【JsPrettier】→【settings - Default】を選択して設定ファイルを開きます
次の2つの項目のパスを設定します。
例:)
"prettier_cli_path": "/Users/hogehoge/.nodebrew/current/bin/prettier",
"node_path": "/Users/hogehoge/.nodebrew/current/bin/node",
which prettier
which node
(command + shift + p) →【JsPrettier:Format Codeを選択】
とても便利なのでぜひショートカットを設定しましょう。
// JsPrettier
{ "keys": ["ctrl+p"], "command": "js_prettier" } ,
今時ES6 JavaScriptで記述することが多くなったので
コード検証ツールにESLint、自動整形ツールにPrettierをインストールしてSublimeTextから使用できるようにします。
npm install -g eslint
npm install -g prettier
ここまでの状態で自動整形のテストを行います
test.js ファイルを用意して自動整形してみます
prettier test.js
ターミナル画面(標準出力)に自動整形した結果が表示されます。
実際に自動整形してファイルを更新するには( --write )オプションを使用します。
prettier --write test.js
eslint test.js と行きたいところですが、まず設定ファイルを作成します。 懸賞したいファイルがあるディレクトリから
eslint --init
を実行すると対応形式で設定ファイル( .eslintrc.js )が生成されます こんなファイルです
module.exports = {
"env": {
"browser": true,
"es6": true
},
"extends": "eslint:recommended",
"parserOptions": {
"sourceType": "module"
},
"rules": {
"indent": [
"error",
4
],
"linebreak-style": [
"error",
"unix"
],
"quotes": [
"error",
"single"
],
"semi": [
"error",
"always"
]
}
};
eslint test.js
でソースコードの検証が実行されます。
.eslintrc editor
https://pirosikick.github.io/eslintrc-editor/
「Airbnb JavaScript Style Guide」はなかなか厳格なルールなので
既存のプロジェクトにいきなり当てはめるには無理がありますが
どの程度厳格なソースフォーマット指定なのか体験しておくだけでも価値があると思います
https://github.com/airbnb/javascript
npm init -y
npm install --save-dev eslint-config-airbnb eslint-plugin-import eslint-plugin-react eslint-plugin-jsx-a11y eslint
{
"extends": "airbnb"
}
node.jsでオブジェクトの中身を一気に表示するにはconsole.logで表示しても良いのですが
次のようにすると楽に見れます
npm install util --save-dev
通常
console.log(results);
とする代わりに
var util = require('util');
console.log(util.inspect(results,false,null));
とします。
システムの開発がphpかつテンプレートエンジンTwigを使用する場合
デザイン過程で静的なhtmlを作成する場合にもTwigを使用しておくとプログラムへのテンプレート化する時に
作業を省くことができます
実はGulpにはPHPと同じTwigテンプレートがあるのでこちらを使用します。
node.js とgulp はあらかじめインストールしておきます。
npm install gulp-twig --save-dev
以下の仕様でコンパイルするよう設定を記述します
● ./twig/ ディレクトリ以下の全ての html ファイルをTwigテンプレートを使用してコンパイルし、./www/ ディレクトリ内に生成する。
● アンダースコアで始まるファイルはコンパイルしない。
gulpfile.js 以下のとおり作成する
// twig コンパイル設定
var gulp = require('gulp');
var twig = require('gulp-twig');
var rename = require('gulp-rename');
gulp.task('twig', function () {
'use strict';
gulp.src(['./twig/*.html', './twig/*/*.html', '!./twig/_*.html'])
.pipe( twig({}) )
.pipe(gulp.dest('./www/'));
});
gulp twig
テンプレートファイル内に以下のように記述します
{{ _target.relative }}
{{ _self.getTemplateName().__toString }}
_layout.htm
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>{{ title }}</title>
</head>
<body>
<header></header>
<div class="container">
{% block content %}{% endblock %}
</div>
<footer></footer>
</body>
</html>
<!-- {{ template_filename }} -->
index.htm
{# 継承元 #}
{% extends "_layout.htm" %}
{# ファイル名 #}
{% if _self.getTemplateName() %}
{% set template_filename = _self.getTemplateName().__toString %}
{% else %}
{% set template_filename = _target.relative %}
{% endif %}
{# ページタイトル #}
{% set title = 'ユーザー管理・データ編集の完了' %}
{% block title %}{{ title }}{% endblock %}
{# コンテンツ #}
{% block content %}
<!-- ここにコンテンツを記述します -->
...
...
...
<!-- ここにコンテンツを記述します -->
{% endblock %}
上の2つのファイルを用意して test.htm を gulp-twig でコンパイルすると次のようなファイルが生成されます。
test.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>ユーザー管理・データ編集の完了</title>
</head>
<body>
<header></header>
<div class="container">
<!-- ここにコンテンツを記述します -->
...
...
...
<!-- ここにコンテンツを記述します -->
</div>
<footer></footer>
</body>
</html>
<!-- test.html -->
electonとは html や css や javascript などといった web 制作の技術を使ってデスクトップ上のアプリケーションを制作しようというものです。 ( まず node js が必要になりますので node js のインストールを完了させておいてください )
npm install -g electron
npm install -g electron-packager
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello Electron!</title>
</head>
<body>
<h1>Hello Electron!</h1>
Node version: <script>document.write(process.versions.node)</script>,
Chrome version: <script>document.write(process.versions.chrome)</script>,
Electron version: <script>document.write(process.versions.electron)</script>.
</body>
</html>
main.js
const { app, BrowserWindow } = require('electron');
let win;
function createWindow() {
win = new BrowserWindow({ width: 800, height: 600 });
win.loadURL(`file://${__dirname}/index.html`);
win.on('closed', () => {
win = null;
});
}
app.on('ready', createWindow);
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
app.on('activate', () => {
if (win === null) {
createWindow();
}
});
package.json
{
"name": "myapp",
"version": "0.0.1",
"main": "main.js"
}
electron .
electron -v
(例 : v1.6.2)
electron-packager <ディレクトリ> <アプリ名(拡張子は除く)> --platform=darwin,win32 --arch=x64 --version=<バージョン> --overwrite
https://qiita.com/tags/electron
https://teratail.com/questions/search?q=electron&search_type=and
http://bit.ly/2nYCc4d
http://bit.ly/2n8dA47
https://github.com/djyde/iCultus
https://github.com/theodi/comma-chameleon
http://sachinchoolur.github.io/lightgallery-desktop/
nodebrew を使って以下のパッケージをインストールします
brew cask install xquartz(途中で管理者パスワードの入力を求められます)
brew install wine
brew uninstall nodebrew
brew uninstall node
curl -L git.io/nodebrew | perl - setup
.bashrc の最後にパスを追加
cd
vi .bash_profile
下記の2行を追加します
# nodebrew
export PATH=$HOME/.nodebrew/current/bin:$PATH
正しくインストールされたか確認します。
source ~/.bash_profile
nodebrew help
バージョンが表示されればOKです。
nodebrew ls-remote
nodebrew install-binary v9.5.0
nodebrew list
nodebrew use v9.5.0
node -v
バージョン名が正しく表示されればOKです。
npm install sqlite3
sqlite3 mydb.sqlite3
CREATE TABLE user_dt (
data_id INTEGER PRIMARY KEY AUTOINCREMENT,
user_name TEXT,
modified_date DATETIME
);
.quit
```
var sqlite3 = require('sqlite3').verbose();
var mydb = new sqlite3.Database('./mydb.sqlite3');
mydb.run("INSERT INTO user_dt (user_name,modified_date) VALUES ('taro yamada', datetime('now', 'localtime') )");
```
##● スクリプトを実行してデータベースにデータを1件登録する
```
node test.js
```
##● node.js + sqlite3 で使用できる クエリービルダー
http://knexjs.org
https://hiddentao.com/squel/
##● node.js + sqlite3 で使用できる O/Rマッパー
http://docs.sequelizejs.com/en/v3/
ヘッドレスブラウザとは「画面がないWEBブラウザ」の事です。
最近では Headless Chrome が人気です。 参考 : https://goo.gl/NQsFS2
が、npm だけでインストールできる phantomJS を紹介します。
WebKit(Safari) ベースのヘッドレス(画面なし)ブラウザ
npm install phantomjs
以下のパスを手動で追加します
./node_modules/phantomjs/bin/phantomjs
brew install phantomjs
yum -y install freetype
yum -y install fontconfig
npm install -g phantomjs
Gecko(firefox) ベースのヘッドレス(画面なし)ブラウザ
brew install slimerjs
npm install -g slimerjs
ヘッドレスブラウザを簡単に扱うライブラリ(JavaScript)です。 このcasperJSから「phantomJS」または「slimerJS」を操作します。
brew install casperjs
yum -y install freetype
yum -y install fontconfig
npm install -g casperjs
test.js で下記コードを保存
var AnchorArrays = [];
var casper = require('casper').create();
casper.start('http://flatsystems.net/kakunin.php', function() {
});
casper.then(function() {
casper.wait(3000, function() {
// xpath要素の取得
var xpath = "//*[@id='my_id']";
var element = this.evaluate(function(path){
return __utils__.getElementByXPath(path).innerHTML;
},xpath);
console.log( element );
//png
this.capture('kakunin.png');
console.log( 'キャプチャを作成しました。' );
});
});
casper.run();
casperjs test.js
casperjs --engine=slimerjs test.js
slimerJSで起動するときは --engine=slimerjs を追加します。
https://chrome.google.com/webstore/detail/resurrectio/kicncbplfjgjlliddogifpohdhkbjogm
Mac OSX の場合は brew でインストールできます
brew install slimerjs
インストールが完了したらバージョンを確認しておきます
slimerjs -v
```
var page = require("webpage").create();
page.open('http://zozo.jp/')
.then(function(status){
if(status === 'success'){
console.log(page.title);
page.render('test.png');
}
phantom.exit();
});
```
実行します
```
slimerjs test.js
```
# slimerjs をCUI環境で実行させる
slimerjsはGUI環境下でないと動作しません。
CUIで実行すると
```
slimerjs --debug=true XXXXX.js
```
```
Error: no display specified
```
というエラーになります。
そこで CUI でも実行できるように Xvfb( X virtual framebuffer ) をインストールします。
```
yum -y install xorg-x11-server-Xvfb
```
Xvfbの使い方は 実行したい処理の前に ```xvfb-run``` を付け加えます
```
Xvfb slimerjs --debug=true XXXXX.js
```
これでCUI下の環境でも実行できます。
Heroku上でヘッドレスWEBブラウザ phantom.js を使用するにはビルドパックを追加します。 ビルドパックをGithub上で公開してくれている方がいるのでありがたく利用させていただきます。
https://github.com/stomita/heroku-buildpack-phantomjs
ターミナルから以下を実行
cd "アプリのあるディレクトリ"
heroku login
heroku buildpacks:add --index 1 https://github.com/stomita/heroku-buildpack-phantomjs
git push heroku master
heroku run phantomjs -v
バージョンが帰ってくればOK
`
phantom_test.js`
ファイルを以下の内容で作成します。var page = require('webpage').create();
page.open('http://yahoo.co.jp/', function(status) {
console.log("Status: " + status);
if(status === "success") {
page.render('example.png');
}
phantom.exit();
});
git add .
git commit -m "add buildpack"
git push heroku master
heroku run phantomjs phantom_test.js
「Status: success」が帰ってくればOK
フォントは `
./fonts`
ディレクトリに .ttf フォントファイルを置いて git push すればOKです。
フォントファイルは著作権に注意して使用しましょう
https://www.google.com/get/noto/#sans-jpan
heroku run fc-match sans:lang=ja
Buildpacks | Heroku Dev Center
heroku buildpacks
heroku buildpacks:set "ビルドパック名またはURL"
heroku buildpacks:add "ビルドパック名またはURL"
heroku buildpacks:remove "ビルドパック名またはURL"
heroku buildpacks:clear
node.js から phantomJSを使用するには下記2つの方法がおすすめです。
npm install nightmare
npm install vo
`
test.js`
で保存var Nightmare = require('nightmare');
var google = new Nightmare()
.viewport(1000, 1000)
.useragent("Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.111 Safari/537.36")
.goto('http://google.com')
.evaluate(function () {
return {
title: document.title,
href : location.href
};
})
.run(function(err, nightmare) {
if (err) return console.log(err);
console.log('Done!');
console.log(nightmare);
});
node test.js
GoogleホームページのタイトルとURLが表示されればOKです。
`
niconico_login.js`
で保存var Nightmare = require('nightmare');
var vo = require('vo');
vo(function* () {
var nico_id = '###メールアドレス###';
var nico_pass = '###パスワード###';
var nightmare = Nightmare({ show: true });
var link = yield nightmare
.goto('https://account.nicovideo.jp/login')
.type('input[id="input__mailtel"]', nico_id)
.type('input[id="input__password"]', nico_pass)
.click('#login__submit')
.wait(2000)
.then(function() {
console.log('終了しました');
});
yield nightmare.end();
return link;
})(function (err, result) {
if (err) return console.log(err);
});
node niconico_login.js
ニコニコ動画にログインできればOKです。
npm install node-horseman
`
test.js`
で保存var Horseman = require('node-horseman');
var horseman = new Horseman();
var filename = 'test.png';
horseman
.userAgent('Mozilla/5.0 (Windows NT 6.1; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0')
.open('http://www.google.com')
.type('input[name="q"]', 'github')
.click('[name="btnK"]')
.keyboardEvent('keypress', 16777221)
.waitForSelector('div.g')
.count('div.g')
.log() // prints out the number of results
.screenshot(filename)
.log(filename)
.close();
node test.js
Googleの検索結果の画面が test.png に保存されれば正常に動作しています。
brew install phantomjs
http://phantomjs.org/download.html
console.log('Hello, world!');
phantom.exit();
phantomjs hello.js
Hello, world!が表示されればインストール成功です。
var page = require('webpage').create();
page.open('http://www.yahoo.co.jp', function(status) {
console.log("Status: " + status);
if(status === "success") {
page.render('page.png');
}
phantom.exit();
});
phantomjs page.js
同じフォルダに page.png というキャプチャ画像があれば成功です。
(「ユーザー登録してWEBアプリをデプロイしてHeroku上で実行する」までの方法)
https://www.heroku.com/
からユーザー登録を行う
https://devcenter.heroku.com/articles/heroku-command-line
からインストーラをインストール
heroku login
git clone https://github.com/heroku/ruby-getting-started.git
cd ruby-getting-started
heroku create
ここまで行うとURLが自動発行されます
https://XXXXX.herokuapp.com/ | https://git.heroku.com/XXXXX.git
git pushします
git push heroku master
No such app as XXXXX. というエラーが出るときは
git remote rm heroku
としてから
heroku create
git push heroku master
とします。
ブラウザで開く
heroku open
cd "アプリのディレクトリ"
git init
git add .
git commit -m "first commit"
heroku create
git push heroku master
heroku open
git add .
git commit -m "change xxxxx"
git push heroku master
heroku open
heroku login
「メールアドレス」「パスワード」を入力してログインします。
heroku apps
と入力すると herokuアプリが
hogehoge-fugafuga-12345
hunihuni-furifuri-67890
という風に表示されます。
アプリ hogehoge-fugafuga-12345 をブラウザで表示するには
heroku open --app hogehoge-fugafuga-12345
と入力します。 またはブラウザのアドレス欄に直接
https://hogehoge-fugafuga-12345.herokuapp.com
と入力してもOKです。
アプリ hogehoge-fugafuga-12345 を削除するには
heroku apps:destroy --app hogehoge-fugafuga-12345 --confirm hogehoge-fugafuga-12345
heroku apps:destroy --app hogehoge-fugafuga-12345
heroku run bash
・Heroku上のホームディレクトリのファイル一覧を表示
heroku run pwd ; ls -la
・Heroku上のphantomjsのバージョンを表示
heroku run phantomjs -v
node.js - How can I run latest version of node on Openshift? - Stack Overflow
Google App Engine Node.jsを試してみる。 GAE/Node.js - Qiita
Google App Engineを無料で運用する方法(2016年版) - koni blog
>Node.jsでWEBページのスクレイピングを行う際に必要となる文字コードの変換と、cheerioによってパースしたHTMLをjQueryのように操作できるHTTPクライアントモジュールです。
特徴 : 文字コード自動変換 , jqueryライクなセレクタ , フォーム簡易送信機能
https://www.npmjs.com/package/cheerio-httpcli
npm install cheerio-httpcli
>HTML/XML parser and web scraper for NodeJS.
特徴 : xpathで要素の取得が可能 , Aタグのリンクを自動的に辿れる
https://www.npmjs.com/package/osmosis
マニュアル : https://github.com/rchipka/node-osmosis/wiki
npm install osmosis
【osmosis node.js】で検索した結果のリンクURLをスクレイピングします。
var osmosis = require('osmosis');
var url = 'https://www.google.co.jp/search?client=safari&rls=en&q=osmosis&ie=UTF-8&oe=UTF-8&gfe_rd=cr&ei=JXMyWLv2NOjC8AernaPYAg#q=osmosis+node.js';
osmosis
.get(url)
.paginate("//*[@id='pnnext']",3) // 最大 3ページ目まで
.set({
'link_url' : ["//*[@id='rso']//h3/a/@href"] ,
'link_title': ["//*[@id='rso']//h3/a"] ,
})
.then(function( context, data){
// console.log(context.request);
console.log(data);
})
.done(function(){
console.log("=================================\nscrape done.\n");
});
その他のスクレイピングモジュール : http://blog.webkid.io/nodejs-scraping-libraries/