JavaScript
nodejs
webpack

webpackでパッケージしたJavaScriptファイルの動的読み込み(Node.js)


はじめに

Nodeで実行されるJavaScriptで、特定のフォルダに保存したJavaScriptファイル(webpackでパッケージ済み)を動的に読み込む方法をメモする。


前提環境

Mac 10.14.2

node 11.4.0

npm 6.5.0

npmにてdevDependencies(npm i -D 〜)として以下をインストール

@babel/cli: 7.2.3

@babel/core: 7.2.2

@babel/preset-env: 7.2.3


実施したこと


読み込まれる側のJavaScript

index.js

export default class AddJS {

・・・
}

webpack.config.jsは下記で実施した。

module.exports = {

mode: 'development',
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: __dirname + '/dist'
},
module: {
rules: [
{
test: /\.js$/,
use: [
{
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env'
]
}
}
]
}
]
}
}

パッケージを行うコマンドは以下である。

webpack


JavaScriptの読み込み側

ADD_JS_PATHに保存されたJavaScriptファイルを読み込むコードを下記する。

 import(ADD_JS_PATH + fileName)

.then(AddJS => {
let obj = new AddJS.default()
・・・
})
.catch(e => {
console.log('error : ', e)
})

export default classで宣言したJavaScriptファイルを読み込む際は<クラス名>。defaultで読み込む必要があるため注意。

requireで読み込むこともできるようだが、importとrequireの混在だとうまく読み込めないこともあるようなのでimportを利用することとした。

コンパイルは下記のコマンドで実施した。

babel src --out-dir dist && cp src/config.json dist/

このとき.babelrcには下記のように記載した。

{

"presets": ["@babel/preset-env"]
}

上記でコンパイルを行うと以下のエラーが出た。

Support for the experimental syntax 'dynamicImport' isn't currently enabled (xx:yy):

babelのdynamic-import-nodeプラグインが必要であることが分かったため追加する。

npm i -D dynamic-import-node

上記により下記が追加された。

babel-plugin-dynamic-import-node: 2.2.0

.babelrcは以下のように修正する。

{

"presets": ["@babel/preset-env"],
"plugins": ["dynamic-import-node"]
}

これで読み込む側のコンパイルができるようになった。


読み込みの動作確認

読み込み処理を実施すると以下のエラーが出た。

TypeError: AddJS is not a constructor

読み込まれる側のJavaScriptにconstructorを定義していても上記エラーとなってしまう。

色々調べると以下のサイトを見つけた。

https://stackoverflow.com/questions/48901262/unable-to-import-module-after-bundling-with-web-pack

このサイトからwebpack.config.jsに"libraryTarget: 'commonjs2'"の記載を追加すれば良さそうなことが分かったため実施した。

webpack.config.js

module.exports = {

mode: 'development',
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: __dirname + '/dist',
libraryTarget: 'commonjs2'
},
module: {
rules: [
{
test: /\.js$/,
use: [
{
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env'
]
}
}
]
}
]
}
}

再度JavaScriptを読み込む処理を実施した結果、無事読み込めるようになった。