JavaScript のモジュール管理

JavaScript のモジュール管理について、個人的メモ。

モジュール管理ライブラリ

JavaScriptECMAScript 2015 (ECMAScript 6) になるまで、他のスクリプトを参照する機能は言語機能として提供されてこなかった。しかしながらサーバサイドで動作する node.js が生まれた頃からその必要性に駆られ、さまざまなモジュール管理ライブラリが登場した。
現在メジャーなモジュール管理ライブラリは次の二つ。

  • Asynchronous Module Design (AMD)
  • CommonJS (CJS)

ECMAScript 2015 の登場

ECMAScript 2015 では言語機能として import 文および export 文が追加された。

Babel

現在 import 文および export 文 をサポートするブラウザはないが、Babel というツール (トランスパイラ) を使うと現在のブラウザが実行できる形に変換できる。

Babel は npm からインストールすることができる。ローカルインストールが推奨されている。

% npm install --save-dev babel-cli babel-preset-es2015

実行する前に設定ファイル .babelrc を作成する。

{
    "presets": ["es2015"]
}

src.js を dest.js にコンパイル

% babel src.js --output dest.js

Webpack

Webpack は JavaScript だけでなく CSS や画像も含めて管理することができるツール。TypeScript や CoffeeScript で書かれたスクリプトや、Sass や Less で書かれたスタイルシートも、最終的に実行できる形に変換してくれる。

Windows で npm run が動かない場合

WindowsError: Cannot find module '…\webpack.config.js;' と言われ動かない場合、複数のコマンドを続けて実行するときのセミコロンが原因。Windows では ; の代わりに & を使わないといけない。

xyzzy で Less CSS を編集するための less-mode

xyzzy でも快適に Less を書きたかったので less-mode を作った。ベースは c-mode。

導入は簡単。GitHub からダウンロードして適宜 etc/Less, site-lisp/less-mode.l を配置する。
そして、 .xyzzy に次の 2 行を追加する。

(load-library "less-mode")
(pushnew '("\\.less$" . less-mode) *auto-mode-alist*)

インデントを設定する

初期設定でタブ幅 4、インデントにはタブ文字を使わない設定になっている。これ以外のタブ幅を使っている場合や、どうしてもタブ文字を使えない事情がある場合は次のように設定する。

(setq ed::*less-mode-hook*
      '(lambda ()
        ;; タブ幅を 5 に設定する
        (setq c-indent-level 5)
        (setq c-brace-offset -5)
        (setq c-argdecl-indent 5)
        ;; インデントにスペースを使う
        (setq indent-tabs-mode nil)
       ))

キーワードファイルの場所を指定する

xyzzy 本体を更新した場合に、etc ディレクトリの内容が置き換わってしまう場合がある。変更したキーワードファイルを誤って上書きされないようにするには、キーワードファイルの場所を違う場所に設定すればよい。

;; ホームディレクトリの xyzzy/etc をキーワードファイル置き場にする
(setq *keyword-load-path* '("~/xyzzy/etc"))

NHK の受信料収入と契約件数の推移

先日、ワンセグ携帯を所有した場合に NHK の放送契約を結ぶ義務があるかどうか裁判が行われたというニュースがあった。放送法64条の「受信設備を設置」に電話の「携帯」の意味を含めるのは「無理がある」として NHK は敗訴。

NHK(および総務省)が受信料の取り立てを強化したい背景として、都市部の若者を中心に受信料の未払いが増えているという説をよく耳にする。実際のところどうなのか、NHK の公表する決算書から受信料収入と契約数を調べてみた。

すると2001年度から2015年度までの受信料収入は横這いで、契約数は増加している傾向が見て取れた。契約数の増加は衛星契約の増加によるものが大きい(衛星契約を含まない地上契約は減少)。ここ数年に限って見れば、衛星契約の増加とともに受信料収入も増加している。

この結果には、契約数の減少が危機的だという印象があったため驚いた。

調査用に作成したデータ

Windows 上で .htpasswd を生成する

Apache において Basic 認証のユーザ名とパスワードを管理する .htpasswd ファイルは、LinuxFreeBSD, OS X では htpasswd コマンドで実行できるが、実は Windows 版の Apache にも同様のプログラムが含まれている。
そのプログラムは、Apache をインストールしたディレクトリの bin 以下にある。XAMPP でインストールした場合は通常 C:/xampp/apache/bin/htpasswd.exe にある。
使い方は htpasswd コマンドと同じで、たとえば .htpasswd を新規作成する場合は次のコマンドで行える。

> C:\xampp\apache\bin\htpasswd -c \path\to\.htpasswd ユーザ名
New password: ******** (パスワードを入力)
Re-type new password: ******** (同じパスワードを再度入力)
Adding password for user ユーザ名

こうすることで \path\to\.htpasswd にパスワードファイルが生成される。

主な使い方

パスワードファイルを新規作成する (-c)。すでにファイルがある場合は以前の内容は消去される。

htpasswd -c パスワードファイル ユーザ名

既存のパスワードファイルにユーザ名とパスワードの組み合わせを追記する。このとき引数は不要。

htpasswd パスワードファイル ユーザ名2

パスワードをコマンドライン引数として渡す (-b)。バッチ処理の際に使用する。

htpasswd -cb パスワードファイル ユーザ名 パスワード

テストのため、ファイルに書き込まず、標準出力に結果を出力する (-n)。

htpasswd -n パスワードファイル ユーザ名
htpasswd -nb パスワードファイル ユーザ名 パスワード

ハッシュアルゴリズムの指定

パスワードは通常、MD5 アルゴリズムでハッシュされる。変更するには次のオプション引数を指定する。

-m  MD5 アルゴリズムを使用する(デフォルト)
-B  bcrypt アルゴリズムを使用する(より安全)
-d  CRYPT アルゴリズムを使用する
-s  SHA アルゴリズムを使用する
-p  パスワードを平文で保存する

たとえば bcrypt を使用し、パスワードファイルを新規作成する場合は次のようになる。

htpasswd -cB パスワードファイル ユーザ名

Basic 認証の設定

Basic 認証は Apache の設定ファイルに次のように書くことで適用できる。通常 httpd.conf(あるいはそこから読み込まれる設定ファイル) の <Directory>〜</Directory> セクションまたは、Basic 認証を適用したいディレクトリの .htaccess に書く。

AuthUserfile /path/to/.htpasswd
AuthGroupfile /dev/null
AuthName "Please enter your ID and password"
AuthType Basic
require valid-user

.htpasswd のパスはフルパスで書く必要があることに注意。

NewsDigest の短縮URL ndjust.in を経由させない

NewsDigest(株式会社JX通信社運営)という Android/iOS アプリからシェアしたリンクは、 ndjust.in で始まる転送用アドレスを経由するよう変換される。
この ndjust.in には Google Analytics が設定されているのみだが、気持ち悪いので直接元のページに移動するようにしよう。


ここではローカルで Apache を動かしている場合の設定方法を説明する。
まず /etc/hosts (Windows の場合は通常 C:/Windows/System32/drivers/etc/hosts) に次の記述を行い、 ndjust.in へのアクセスをすべてローカルの Apache へ向ける。

127.0.0.1	ndjust.in

次にバーチャルホストの設定を行うが、他のサイトや書籍を参考にしてほしい。その際、次のような設定を行い、mod_rewrite を用いてすべてのアクセスを /index.php へ向け、GET パラメータ _url に短縮 URL の ID を格納するようにする。

RewriteRule ^(.*)$ index.php?_url=$1 [L]

そして移動先ページの URL を取得するスクリプトは次のようになる。自動でのリダイレクトはしないようにした。

<?php
// コンソールでのテスト用
$path = isset($_GET['_url']) ? $_GET['_url'] : '6zMYUOOtsI';

$addresses = array(
	'54.192.233.19',
	'54.192.233.62',
	'54.192.233.93',
	'54.192.233.116',
	'54.192.233.173',
	'54.192.233.187',
	'54.192.233.191',
	'54.192.233.244',
);
$protocol = 'http://';
$host = 'ndjust.in';
$timeout = 5;

$headers = array(
	'Host: ' . $host,
	'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
	'Accept-Encoding: gzip,deflate',
	'Accept-Language: ja,en-us;q=0.7,en;q=0.3',
	'User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:48.0) Gecko/20100101 Firefox/48.0',
);

shuffle($addresses);
$url = $protocol . $addresses[0] . '/' . $path;

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_NOBODY, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($ch);
curl_close($ch);

$redirectTo = null;
if (preg_match('{<a href="(https?://.*?)" id="destination">}', $data, $matches)) {
	$redirectTo = $matches[1];
}
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>NewsDigest 経由のリダイレクト警告</title>
</head>
<body>
<?php if ($redirectTo) : ?>
<p>次の URL へリダイレクトしようとしています</p>
<p><a href="<?= htmlspecialchars($redirectTo) ?>"><?= htmlspecialchars($redirectTo) ?></a></p>
<?php else : ?>
<p>リダイレクト先が見つかりません</p>
<?php endif; ?>
</body>
</html>

以上で NewsDigest からシェアされたリンクに安心してアクセスできる。