2017年08月

いろいろ作っていると、TypeScriptに限らず別のプロジェクトで作ったコード使い回せそうだなとかある。(最初から使い回せるように作る場合も)C言語だとライブラリ作るんだけどNode.js、TypeScriptだとどうするんだろう?ってなったわけだ。で、調べてみた。
npmの2.0からローカルにあるパッケージ(モジュールというべき?)をインストールできるようになったらしいんそれを使う。

例として、複数プロジェクトで使うモジュールをcommonという名前で作る。

commonディレクトリを作って、そこでnpm initを実行して、package.jsonを適当に作る。
このモジュールは公開しないので念のためprivateフィールドをtrueで追加する。TypeScriptの場合、typesフィールドを追加して、モジュールの型情報ファイルをしてする。

{
  "name": "common",
  "version": "1.0.8",
  "description": "",
  "main": "test1.js",
  "types":"test1.d.ts",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "private": true
}

つぎにTypeScriptの準備。
tsc --initを実行して、tsconfig.jsonを作成する。まー、特に変更するところはない。
外部モジュールのコード(test1.ts)はこんな感じにして、tscを実行する。

export function print() {
    console.log("Test1モジュール");
}

tsc -Dを実行して型情報ファイルを生成する。(test1.d.tsができる)

次にこのモジュールを使う方だ。

commonディレクトリと同列(隣)にtestと言うディレクトリを作って、そこを使うことにする。 npm initやtsc --initでpackage.json、tsconfig.jsonを作成する。

$ npm install ../common --save

を実行して、commonモジュールをインストールする。testプロジェクトのnode_modulesフォルダにコピーされる。

commonモジュールを使うコードはこんな感じになる。

import * as hoge from "common";

hoge.print();

これで気になるのが、package.jsonのdependenciesフィールドにcommonが絶対ディレクトリで指定されるんだよな。他のPCに持って行ったときにちょっと困りそうだが、直接このフィールドを編集して相対パスで指定しても良さそうだ。

  "dependencies": {
    "common": "file:../common"
  }

追記 2017/9/10
なんか、npm installで型定義ファイルがコピーされなくなってる。

追記 2017/9/10 その2
どうも、.gitignoreに*.d.tsを指定していたせいみたいだ。
型定義ファイルはtscで生成するからと思い.gitignoreに*.d.tsを指定していた。



らずぱいで、VisualStudioCode (ビルドして、実行) - Qiita

ラズパイでも動くんだな。まー、そりゃそーか。

JSON5とCSONについて |

JSON5でC++やJava見たいなコメントが入っているJSONを読める。

このエントリーをはてなブックマークに追加 Clip to Evernote
ブログランキング・にほんブログ村へ
にほんブログ村

[Node.js] Webサーハ゛を作る。(2)が古くなったんで書き直してみた。clusterとmimeモジュールも使うようになってる。
説明はソースのコメントにしておいたので省略(^^;)

import * as http from "http";
import * as cluster from "cluster";	// (1)
import * as os from "os";
import * as url from "url";
import * as path from "path";
import * as querystring from "querystring";
import * as fs from "fs";
import * as mime from "mime";

const port = 8080;					// 待ち受けポート番号
const contentsDir = "www";			// コンテンツフォルダ
const defaultHtml = "index.html";	// ファイル名が省略された場合(ディレクトリを指定された場合)
									// 読み込むファイル名

// コンテンツフォルダのフルパスを生成
const wwwRoot = path.join(__dirname, contentsDir);
console.log("wwwRoot=" + wwwRoot);

// コア数取得
const numCPUs = os.cpus().length;

if(cluster.isMaster) {	// マスターなら
	// CPUコア数のワーカーを起動 (2)
	for(let i = 0; i < numCPUs; i++) {
		cluster.fork();
	}
	cluster.on("exit", (worker, code, signal)=>{
		console.log(`worker ${worker.process.pid} died`);
	});
} else {
	// サーバ起動
	const server = http.createServer((req, res)=>{
		console.dir(req.headers);
		const reqUrl = url.parse(<string>req.url, true);
		const contentsFile = path.join(wwwRoot, querystring.unescape(<string>reqUrl.pathname));
			
		// ファイルの情報を取得する。そして、コールバック関数でファイルやエラーをクライアントに返す。
		fs.stat(contentsFile, (err, stats)=>{
			if(err) {	// エラーなら、404エラーをクライアントに返す。
				console.log(err);
				responseError404(res);
				return;
			} else {
				responseContent(contentsFile, stats, res);
			}
		});
	})
	.listen(port);
}

// ファイルを返す。
function responseContent(contentsFile:string, stats:fs.Stats, res:http.ServerResponse) {
	if(stats.isDirectory()) {	// ディレクトリなら、defaultHtml(index.html)を追加して
								// fs.statを呼ぶ。
		const indexFile = path.join(contentsFile, defaultHtml);
		fs.stat(indexFile, (err, stats)=>{
			if(err) {	// エラーなら、404エラーをクライアントに返す。
				console.log(err);
				responseError404(res);
				return;
			} else {
				responseContent(indexFile, stats, res);
			}
		});
		return;
	} else if(stats.isFile()) {	// ファイルなら、ファイルを返す。
		// 拡張子からMIMEタイプを取得してヘッダに設定する。
		const extname = path.extname(contentsFile).toLocaleLowerCase();
		const mimeType = mime.lookup(extname);

		// レスポンスヘッダを設定
		responseSetHeader(res, 200, mimeType, stats.mtime);
		
		// ファイルのストリームを作って、クライアントに返す。
		//		pipe()でresにデータを流すようにする。
		// 		resはWritableインターフェイスが実装されているのでpipe()に渡すことができる。
		fs.createReadStream(contentsFile)
			.pipe(res);
	} else {	// ファイルでもディレクトリでもないなら
		// ファイルがなかったことにする。(404エラーをクライアントに返す)
		responseError404(res);
	}
}

// 404エラーをクライアントに返す。
function responseError404(res:http.ServerResponse):void {
	res.writeHead(404, { "Content-Type":"text/plain" });
	res.write("404 Not Found.\n");
	res.end();
}

// レスポンスヘッダを設定
function responseSetHeader(res:http.ServerResponse, statusCode:number, mimeType:string | null,
			lastModified:Date, nocache:boolean=false):void {
	if(mimeType) {
		res.setHeader("Content-Type", mimeType);
	}
	if(nocache) {
		res.setHeader("Pragma", "no-cache");
		res.setHeader("Cache-Control", "private, no-store, no-cache, must-revalidate");
		res.setHeader("Expires", new Date().toUTCString());
	}
	res.setHeader("Last-Modified", lastModified.toUTCString());
	res.statusCode = statusCode;
}


↑このページのトップヘ