一応こんなんがあります.
ブラウザのscriptで動かす前提のものをNodeな環境でテストするのもなんでかは気になりますが,今どきブラウザでもNodeでもESModuleが使えるのでそのうちこんなことしなくてもよくなるかもしれません.
Node.jsでJavaScriptをimportする。script.js
でexportを記述せずにMyClassをインポートしたいです。目的は、ブラウザで動作するJavaScriptをテストするためです。なのでexportみたいなNode.jsの記述を入れたくないです。eval()も試しましたがダメダメでした。
class MyClass {
hello() {
return 'こんにちは'
}
}
import './script.js'
import assert from 'assert'
console.log(MyClass)
describe('JavaScriptのテスト', function() {
it('あいさつ出来ること', function() {
const myClass = new MyClass()
assert.equal(myClass.hello(), 'こんにちは')
})
})
エラー内容
$ node main.mjs
file:///workspaces/KiZooNa.js/main.mjs:3
console.log(MyClass)
^
ReferenceError: MyClass is not defined
at file:///workspaces/KiZooNa.js/main.mjs:3:13
at ModuleJob.run (node:internal/modules/esm/module_job:222:25)
at async ModuleLoader.import (node:internal/modules/esm/loader:323:24)
at async loadESM (node:internal/process/esm_loader:28:7)
at async handleMainPromise (node:internal/modules/run_main:113:12)
Node.js v20.12.2
よくわかんにゃい
一応こんなんがあります.
ブラウザのscriptで動かす前提のものをNodeな環境でテストするのもなんでかは気になりますが,今どきブラウザでもNodeでもESModuleが使えるのでそのうちこんなことしなくてもよくなるかもしれません.
@7mpy
Questionerありがとうございます。スタバの通りevalを使ったのですが無理みたいです😭
eval('class MyClass {}')
console.log(MyClass)
$ node hoge.mjs
file:///workspaces/KiZooNa.js/hoge.mjs:3
console.log(MyClass)
^
ReferenceError: MyClass is not defined
at file:///workspaces/KiZooNa.js/hoge.mjs:3:13
at ModuleJob.run (node:internal/modules/esm/module_job:222:25)
at async ModuleLoader.import (node:internal/modules/esm/loader:323:24)
at async loadESM (node:internal/process/esm_loader:28:7)
at async handleMainPromise (node:internal/modules/run_main:113:12)
Node.js v20.12.2
また、script.jsでnode.js環境のみexportしようとすると怒られちゃいます😭😭
class MyClass {
hello() {
return 'こんにちは'
}
}
if (typeof window === 'undefined') {
export {
MyClass
}
}
@7mpy
Questionerいったんこれでいっか...
class MyClass {
hello() {
return 'こんにちは'
}
}
import { readFileSync } from 'node:fs'
import assert from 'assert'
eval(readFileSync('script.js') + ';global.MyClass=MyClass')
console.log(MyClass)
describe('JavaScriptのテスト', function() {
it('あいさつ出来ること', function() {
const myClass = new MyClass()
assert.equal(myClass.hello(), 'こんにちは')
})
})
@7mpy
Questionerglobal
に変数毎回定義するのはだるい気がするけど...global
をglobalThis
にしてもいける...
@7mpy
Questionerこっちの方が、MyClass
が未定義ジャマイカの警告でないかも
import { readFileSync } from 'node:fs'
const { MyClass } = await import(`data:text/javascript;base64,${Buffer.from(readFileSync('script.js') + ';export {MyClass}').toString(`base64`)}`)
import assert from 'assert'
console.log(MyClass)
describe('JavaScriptのテスト', function () {
it('あいさつ出来ること', function () {
const myClass = new MyClass()
assert.equal(myClass.hello(), 'こんにちは')
})
})
@7mpy
Questioner
@7mpy
Questionerどちらにせよ。毎回エクスポートする変数を指定するのはだるい。自動で全部エクスポートしてほしい
@7mpy
デフォルト private みたいなものなので 公開したいものは頭に export つければいいだけなのでは……?
function C {}
const v = 1;
↓
export function C {}
export const v = 1;
import も
import * as MyClasses from "./path.js";
@7mpy
Questionerなるほど!でも、<script type="module" src="script.js"></script>
みたいにtype="module"
つけないといけないのは若干抵抗がある気がする
@7mpy
Questionerfrom XXXX
のXXXX
を動的に作るのはNode.jsではできないっぽいぉ
import { readFileSync } from 'node:fs'
import { MyClass } from `data:text/javascript;base64,${Buffer.from(readFileSync('script.js') + ';export {MyClass}').toString(`base64`)}`
import assert from 'assert'
console.log(MyClass)
describe('JavaScriptのテスト', function () {
it('あいさつ出来ること', function () {
const myClass = new MyClass()
assert.equal(myClass.hello(), 'こんにちは')
})
})
globalThis
に生やせばいいのでは……?
globalThis.MyClass = MyClass;
@7mpy
Questionerなるほど!その手があったかっ!でもテストするだけのためにグローバル汚染いやです(すっとぼけ
@juner
でも最適解な気はしますね...
class MyClass {
hello() {
return 'こんにちは'
}
}
globalThis.MyClass = MyClass
import '../script.js'
import assert from 'assert'
console.log(MyClass)
describe('JavaScriptのテスト', function() {
it('あいさつ出来ること', function() {
const myClass = new MyClass()
assert.equal(myClass.hello(), 'こんにちは')
})
})
嫌 なら public 修飾子つける感覚で export つけましょう
@7mpy
Questionerhahaha
@7mpy
QuestionerNode.js環境のときだけ、晒すでもいいのかなと。。。動作未確認
class MyClass {
hello() {
return 'こんにちは'
}
}
if (typeof global === 'object') global.MyClass = MyClass