カテゴリー: テクノロジー

npm-scriptsでSCSSをコンパイルしてみよう!

sassをコンパイルする方法として、gulpを使っていますが、npm-scriptsが主流になってきています。npm-scriptsを使うメリットとして、記述がシンプルでバージョン依存が少なく共有がしやすいことが挙げられます。

今回はnpm-scriptsを使ってSass/Scssのコンパイルする方法についてまとめてみようと思います。

準備とSCSSをコンパイル

まずは任意のディレクトリにサンプルとして「sass_test」ディレクトリを作成し移動します。

mkdir sass_test
cd sass_test

今回使用するsassファイルを作成します。
ディレクトリは下記を想定しています。

sass_test
└resources
 └sass
  └style.scss
└dist
 └sass
  └style.css

「sass_test」の中でpackage.jsonを生成します。
「sass_test」に移動して、ターミナルで下記のコマンドを入力すると「package.json」が生成されます。
(質問は全てenterで大丈夫です)

npm init

sassのコンパイルとして、「Sass」をインストールします。

npm install sass --save-dev

package.jsonの「scripts」欄を次のように変更します。

  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },

  "scripts": {
    "sass": "sass resources/sass/:dist/css/ --no-source-map --watch"
  },

sassをコンパイルするために下記を「sass_test」の階層で実行します。

npm run sass

「dist/css/」ディレクトリに「style.css」が生成されたと思います。
(終了するには[Ctrl + C]を押します。)
sassをコンパイルするのみならこれだけです。

自動でベンダープレフィックスを付与

自動でベンダープレフィックスを付与するために「autoprefixer」をインストールします。
合わせて「postcss」「postcss-cli」をインストールします。

npm install postcss postcss-cli autoprefixer --save-dev

複数のnpm-scriptsを実行するために「npm-run-all」をインストールします。

npm install npm-run-all --save-dev

ファイル変更の監視をするために「watch」をインストールします。

npm install watch --save-dev

package.jsonの「scripts」欄を次のように変更します。

  "scripts": {
    "all": "run-p watch",
    "watch": "watch 'run-s scss postcss' ./resources/sass",
    "scss": "sass resources/sass/:dist/css/ --no-source-map",
    "postcss": "postcss dist/css/style.css -o dist/css/style.css"
  },

pakcage.jsonと同じ階層に「postcss.config.js」を作成します。

module.exports = {
  plugins: [
    require('autoprefixer')()
  ]
}

そしてpakcage.jsonと同じ階層に「.browserslistrc」を作成します。
ブラウザリストはここで調整します。

last 2 versions
ie >= 11
Android >= 7

それではコンパイルしてみましょう。
「resources/sass/style.scss」に下記を記載します。

a{
  transition: 0.3s all;
  color: red;
  
  p{
    color: green;
  }
}

次にターミナルでpackage.jsonと同じ階層で下記を実行します。

npm run all

そうすると、「dist/css/style.css」に下記が出力されています。

a {
  -webkit-transition: 0.3s all;
  transition: 0.3s all;
  color: red;
}
a p {
  color: green;
}

無事にsassがベンダープレフィックスがついてコンパイルされていることが確認できました。
(終了するには[Ctrl + C]を押します。)

以上がnpm-scriptsを使ったsassのコンパイル方法をです。
読んでいただいた方の参考になればと思います!


[Solr]バックアップの置き場をS3にする

Solr には予め設定しておいたレポジトリにバックアップする機能があります。
レポジトリには以下の種類があります。

  • ローカルファイルシステム
  • HDFS
  • GCS(Google Cloud Storage)
  • Amazon S3

ここではローカルファイルシステムとS3の設定例を見てみます。

LocalFileSystemRepository

バックアップレポジトリの設定は solr.xml に書きます。

<backup>
  <repository name="local_repo" class="org.apache.solr.core.backup.repository.LocalFileSytemRepository">
    <str name="location">solr/backup_data</str>
  </repository>
</backup>

LocalFileSystemRepository の場合、設定項目は location だけです。

以下のようにAPIを利用してバックアップを実行した場合、Solr のインストールディレクトリを $SOLR_DIR とすると $SOLR_DIR/server/solr/backup_data/backup1 にコレクション backup_test のバックアップが作られます。

$ curl 'http://localhost:8983/solr/admin/collections?action=BACKUP&name=backup1&collection=backup_test&repository=local\
_repo'

S3BackupRepository

S3BackupRepository を使うためにはプラグインの設定が必要です。
$SOLR_DIR/server/solr/lib を作成し、dist/solr-s3-repository-8.10.0.jar と contrib/s3-repository/lib/*.jar をコピーして
solrconfig.xml に以下を追加します。

<lib dir="./lib" />                                                                                                     

レポジトリの設定はsolr.xmlに追加します。

<backup>
  <repository name="s3_repo" class="org.apache.solr.s3.S3BackupRepository" default="false">
    <str name="s3.bucket.name">XXXX.splout.co.jp</str>
    <str name="s3.region">us-west-2</str>
  </repository>
</backup>

s3.bucket.name でバケット名を、s3.region でリージョン名を指定します。
その他に S3 のエンドポイントを指定する s3.endpoint、プロキシを設定するための s3.proxy.url, s3.proxy.useSystemSettings \
があります。

上記の設定例の場合、以下のようにAPIを利用してバックアップを実行した場合、s3://XXX.splout.co.jp/backup2 にコレクション backup_test のバックアップが作られます。

$ curl 'http://localhost:8983/solr/admin/collections?action=BACKUP&name=backup2&collection=backup_test&repository=s3_re\
po'

[Solr]分散検索でどのレプリカに検索リクエストを送るのかを制御する

SolrCloud でシャードに複数のレプリカを作った場合、検索リクエストを処理する際にどのレプリカを優先するのかを shards.preference パラメータで指定できます。

以下の形式で優先順を指定します。
shards.preference=属性1:値1,属性2:値2,…
左側にあるものほど優先度が高くなります。

指定できる属性は以下の通りです。

replica.type

レプリカの種類(PULL, TLOG, NRT)を指定します

replica.location

http://hostname:port から始まる文字列でレプリカの場所を指定します。前方一致でレプリカを選びます。

特殊なケースとして “local” を指定した場合、リクエストを処理するサーバと同じサーバにある Solr インスタンスのレプリカが選ばれます。フィールド数が多い、巨大なフィールドがある、などの理由で検索結果のデータサイズが大きい場合に有効です。特定のレプリカに障害が発生した場合の影響範囲を小さくする効果もあります。

replica.base

優先順位が同じレプリカが存在するときに、それらの間でどれを優先するかを決めるためのルールを指定します。

  • random ランダムに1つ選びます
  • stable:dividend:パラメータ名 指定したパラメータに対応する整数値をレプリカ数で割った余りで決定します
  • stable[:hash[:パラメータ名]] 指定したパラメータに対応する文字列のハッシュ値をレプリカ数で割った余りで決定します。パラメータ名が指定されない場合はメインのクエリである q の値が使われます。

node.sysprop

指定したシステムプロパティの値が同じレプリカが選ばれます。
たとえば同じラックに属する Solr インスタンスが同じ rack プロパティの値を持つように -Drack=rack1 のように設定しておき、検索時に shards.preference=node.sysprop:sysprop.rack を指定すると、リクエストを処理している Solr インスタンスと同じ rack プロパティの値を持つ(=同じラックに属する)レプリカが選ばれます。

replica.leader

リーダーレプリカを優先するかどうかを true または false で指定します。たとえばレプリカが6台ある状態で replica.leader:false が指定されるとリーダー以外の5台が分散検索の対象となります。


SolrCloudにおけるレプリカの種類

ドキュメント数の非常に多いコレクションを扱う場合、複数のシャードを作ってデータを分けることができます。ドキュメントはそれぞれ複数のシャードのどれか1箇所にだけ属します。
シャードは1個以上のレプリカから構成されます。同じシャードに属するレプリカの内容はすべて同じです。シャードのうちどれか一つがリーダーとして選ばれます。

インデックス対象のドキュメントがSolrに送られてきたとき、まずそのドキュメントがどのシャードに属するべきかが決定され、そのシャードのリーダーにドキュメントが送られます。そして同じシャードに属する他のレプリカすべてにリーダーからドキュメントが転送されます。

レプリカにはいくつか種類があります。

NRT(= NearRealTime)

  • デフォルトの設定。トランザクションログを保持しつつ自身のローカルのインデックスの更新も行う。
  • リーダー選出の候補となる。

TLOG

  • トランザクションログの維持はするが、自身ではローカルのインデックス更新は行わない。
  • このタイプのレプリカはコミットを実行する必要が無いのでインデックスの速度向上が見込める。
  • このタイプのレプリカでインデックスを更新するには、リーダーからインデックスをレプリケートする。
  • リーダー選出の候補となる。
  • もしもリーダーに選出された場合には、NRTレプリカと同様に動作する。

PULL

  • トランザクションログの維持もローカルのインデックス更新もせず、リーダーのインデックスのレプリケーションのみを行う。
  • リーダー選出の候補にはならない。

レプリカのうちどれかはリーダーにならなければならないので、シャードのレプリカをすべてPULLだけで構成することはできません。
Solrリファレンスでお薦めされているレプリカタイプの組み合わせは以下の通りです。

すべてNRT

更新のリアルタイム性が必要でありインデックス更新のスループットがそれほど大きくない場合、この組み合わせにする。
特にSoft Commitが必要な場合はNRTしか選択肢が無い。

すべてTLOG

インデックス更新のリアルタイム性が必要でなくシャード内のレプリカが非常に多い場合、すべてのレプリカで更新リクエストを扱えるようにしておきたいと考えるならば、この組み合わせにする。

TLOGとPULLの組み合わせ

インデックス更新のリアルタイム性が必要でなくシャード内のレプリカが非常に多い場合、多少古い検索結果を許容しつつ検索クエリへの応答能力拡大をするにはこの組み合わせにする。


経験の浅いプログラマーにVimを推奨すべきかせぬべきか

エディターは人それぞれですし歴史があり宗教戦争に発展するので他人にとやかくいうものではないと思います。でもそこに経験の浅いプログラマーが入ってきた場合は?この場合おすすめするかどうかは非常に悩みどころです。

遠い遠い昔の初めてプログラミングを行った専門学校の時代はPCに入っていたメモ帳での開発でした。当時のことを思い返せばよくもまぁ全角スペースすら見落としやすいメモ帳で100ファイル近くのファイルを管理してjavaで卒業作品にゲームを作ったなと思います。その後に最初の会社でEmEditorに出会いこんなに便利なエディターがあるんだと感動しEclipceの当時の重さに苦慮しつついつからかVimがおすすめと言われてVimを使い出しました。

vim

vimは便利です。慣れれば今でも十分使えるし使いやすいエディタだと思っています。大体のUnix系OSに入ってるので特にサーバーで作業する際とか緊急時の対応とかに助かります。軽いしターミナルだけで作業できるしマウスいらずで便利です。でもこれはvimを長年使っているから言えることです。

vimは最初のとっかかりに戸惑います。いろいろ操作やコマンドを覚えたり設定を行なったりプラグインを入れたりすればすごく使いやすいのですがそこまでいくのに時間がかかります。入ってすぐにいろいろなことを覚えないといけない状況でVimまで覚えることになると負担が大きいので基本的になしかなと個人的に思ってます。今ならもうvim以外のエディターで軽くてお手軽に始められて拡張性もよく使い勝手のいいものは既に出てるのでは?と考えてしまうことも多々あります。メモ帳代わりに使ってますがVSCode辺りがそれに近そうです。

自分の出した結論は基本的には推奨すべきでない。仕事に慣れて余裕ができて興味があってようやくレベルかなと・・・ターミナルだけで作業できてマウスいらずで便利なんですけどね

上記だけで終わるとアレなので自分がよく使っているコマンド等を記載して終わります。

1行削除の「dd」
1行コピーの「yy」
ペーストの「p」
末尾に移動する「$」
123行目へ移動する「123G」
特定の文字に囲まれている中を削除する「di’」「di”」
ビジュアルモードでの加工や範囲選択での置換
インサートモードから抜けるEscの代わりに「jj」
=などのインデントを自動で行ってくれる自動整形プラグイン
構文エラーチェックのシンタックスエラー検知のプラグイン

特に行番号への移動や行コピーや行削除、ビジュアルモードでの加工はよく使います。