LoginSignup
10
5

More than 5 years have passed since last update.

ローカルファイルを監視してS3に自動アップロード(Node.js & Chokidar)

Last updated at Posted at 2018-07-26

はじめに

やることはタイトルそのまんま。色々な使い道があると思うのですが、
僕がやりたかったのは「JavaScriptコードをS3でホスティングしながら開発」
もっと言うと「kintoneでJavaScriptカスタマイズ中のデバッグ」なんです。

Dropboxで同期するのが常套手段なんですが、
最近Dropboxの同期後にkintoneに反映されるのがとても遅くて
なんかとても開発効率下がってたんですよね。

なので、これを機にAWS S3を使って脱Dropboxしちゃおうと思ったのでした。

コード

nodejs aws-sdkでs3ファイルアップロード
をかなり参考にさせていただきました。ありがとうございます!

rootkey.json
{
  "accessKeyId": "xxxxxxxxxxxxxxxxxxxx",
  "secretAccessKey": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
s3.js

#!/usr/bin/env node

const AWS = require('aws-sdk')
const fs = require('fs')
const path = require('path')
const chokidar = require('chokidar')

AWS.config.loadFromPath('./rootkey.json')
AWS.config.update({ region: 'リージョン名' })

const s3 = new AWS.S3()
const params = {
  Bucket: 'バケット名',
  ContentType: 'application/javascript', // JS以外も混じる場合は一工夫必要
  ACL: 'public-read',
}

const FILES = [
  'ソースコード1.js',
  'ソースコード2.js',
  'ソースコード3.js',
  'ソースコード4.js',
  'ソースコード5.js',
  'ソースコード6.js',
  'ソースコード7.js',
  'ソースコード8.js',
]
const S3_FOLDER = 'S3のフォルダ名'
const RANDOM = 'no3EGxETfddCoouWXV77'

chokidar.watch(FILES).on('all', (event, filePath) => {
  console.log(event, filePath)
  if (!(event === 'add' || event === 'change')) {
    return
  }

  params.Body = fs.readFileSync(filePath)

  const ext = path.extname(filePath)
  const filePathWithoutExt = filePath.replace(new RegExp(ext + '$'), '')
  params.Key = `${S3_FOLDER}/${filePathWithoutExt}-${RANDOM}${ext}`

  s3.putObject(params, function(err, data) {
    if (err) console.log(err, err.stack)
    else console.log(data)
  })
})

実行

Node.jsがインストールされている状態で、

$ npm i -g aws-sdk
$ npm i -g chokidar
$ node s3.js

これでFILES配列に列挙したJSソースコードが監視されて、
エディタでファイルを保存次第、随時S3にアップロードされます!

解説

  • Node.jsのChokidarライブラリでファイル監視
  • 定義済みファイルが追加・更新されたらaws-sdkライブラリでS3にアップロード

というのが基本の仕組みです。
S3の設定周り詳細は割愛しますが、ググったらすぐ情報見つかるはず。

デフォルト設定から変更してる部分はここですね。

  ContentType: 'application/javascript',
  ACL: 'public-read',

そしてこのランダム文字列。

const RANDOM = 'no3EGxETfddCoouWXV77'

これはなくても動作しますが、ファイル名を予測され辛くしておかないと
ホスティングされてるURLが暴かれてしまう危険性があるので、その工夫です。

本当はS3側で細かくいろいろ設定してやればセキュアに出来るんでしょうけど、
本番環境では使わない想定なので、そこまで面倒なことはしたくなかったので。
その辺はDropboxの公開URLの仕様に似せてます。

ちなみにフォルダ名じゃなくてファイル名の末尾に付けた理由は、
「ファイルパスの途中まで読めば何のファイルか分かるから」です。
kintoneにURL載せる時とか、末尾は省略されちゃうんでね。

ランダム文字列の生成は、Macだとこんなワンライナーで。

env LC_CTYPE=C tr -dc "a-zA-Z0-9" < /dev/urandom | head -c 20

Webpackを使っている場合

outputに出力されるJSファイルをこの方法で監視すればできますが、webpack-s3-pluginを使うともっとスムーズです。また早めに記事書きたいなー。

参考サイト

10
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
5