ブラウザJS と node.js で互換を持たせるコード
下記コードでブラウザJSと同じ環境を作りました
// main.js
if(typeof require !== 'undefined') {
function evaluate(fileName) {
var fs = require("fs");
const vm = require('vm');
const code = fs.readFileSync(fileName, 'utf-8');
// 読み込んだソースコードを本スコープに展開する
vm.runInThisContext(code);
}
evaluate("./utils.js");
evaluate("./runtime.js");
evaluate("./operations.js");
evaluate("./parser.js");
}
指定したファイルをグローバルスコープで実行し、クラスや変数等を使えるようにしています。
node の export, require
main.js, util.js があり
util.js で作成した Util クラスを main.js で使いたい場合を考えます
// util.js
function Util() {
var self = this;
self.hello = function(name) {
console.log("Hello, " + name + "!");
};
}
// これで他のファイルから `require()` できるようになる
module.exports = Util;
// main.js
const Util = require('./util'); // 拡張子 .js は省略可能
const util = new Util();
util.hello('Node.js'); // 出力: Hello, Node.js!
ブラウザJavaScript には module.exports, require が無いので、main.js で Util を使うには
<script src="util.js"></script>
としてグローバルスコープで util.js を実行し Util クラスを作成する必要があります
そこで,指定したJSファイルをグローバルスコープで実行すればブラウザJS同等の動作になるというのが本記事の考え方です
至る理由
ブラウザJSで使用する機能をnodeで作成していたのですが、コード規模が大きくなりファイル分けが必要になりましたが、当たり前ですが node は export して require する仕組みなのでブラウザJSのようにグローバル空間で適当に作ることが許されていません
色々悩んだ結果面倒だから eval でいいやとなりましt
真面目にやると色々めんどくさい
検索して下記サイトに真面目なやり方が書いてありましたが、面倒だなーと思った。
https://crocro.com/write/js_sample/?act=vw_itm&itm=browser_and_node
chatGPTに聞いても前述のサイトと同じ回答を出してきたのできっとこれが王道というか真面目にやったらそうなんだろうなという感じですが、nodeの仕様と真面目に向き合いたくないなという手抜き実装をしたというお話でした
追記
chatGPT に node.js で実行しているかを判定するコード書いてとお願いしたら下記が出てきました
多分こっちのほうがいいのかな
function isNode() {
return typeof process !== 'undefined' &&
typeof process.versions === 'object' &&
typeof process.versions.node === 'string';
}
if (isNode()) {
console.log("Running in Node.js");
} else {
console.log("Not Node.js (maybe browser)");
}