jsライブラリを作成するためにbabel7+webpack4で環境構築

# はじめに

jsのライブラリを作成しようと思い、イマドキの開発環境構築をしようとbabel7とwebpack４で環境構築した話です。

# 開発環境

windows10でもろもろのインストールはPowerShell経由でコマンド実行してます。

# 環境構築

### 下準備

まず、`npm init`して、`package.json`を準備します。
次に、babelとwebpackのモジュールをインストールします。

[最新版で学ぶwebpack 4入門 - Babel 7でES2018環境の構築（React, Vue, Three.js, jQueryのサンプル付き）](https://ics.media/entry/16028/)

こちらのページを参考にさせていただきました。

```
npm install -D webpack webpack-cli babel-loader @babel/core @babel/preset-env
```

次に、`webpack.config.js`を準備します。

```webpack.config.js
module.exports = {
  mode: "development",
  entry: "./src/index.js",
  module: {
    rules: [
      {
        test: /\.js$/,
        use: [
          {
            loader: "babel-loader",
            options: {
              presets: [
                "@babel/preset-env"
              ]
            }
          }
        ]
      }
    ]
  }
};
```

次に、`package.json`に`build`コマンドを追加します。

```package.json
・・・
"scripts": {
  "test": "echo \"Error: no test specified\" && exit 1",
  "build": "webpack",
},
・・・
```

これで、`npm run build`すると`webpack`コマンドが実行されます。
`webpack`を直接打ってもいいです。

最後に、コンパイルする処理を書きます。

```index.js
export default class {
  constructor (x) {
    this.x = x;
  }

  testFunction = () => {
    console.log(this.x);
  }
}
```

### エラーと戦う 

`npm run build`します。で、以下エラーがでます。

```
Support for the experimental syntax 'classProperties' isn't currently enabled
```

よくよく調べると、babelのgithubに同様のエラーについてのisuueがありました。

[Compilation error "Support for the experimental syntax 'classProperties' isn't currently enabled" despite having the plugin installed when using linked packages #8667](https://github.com/babel/babel/issues/8667)

ここに書いてある解決策は、`@babel/plugin-proposal-class-properties`をインストールすればエラーがでなくなるとのことだったので、インストールします。

```
npm install -D @babel/plugin-proposal-class-properties
```

再度、コンパイルをすると、無事エラーがなくなりました。

### ライブラリ化する

元々の目的がライブラリを作成することなので、ライブラリ化します。

以下ページを参考にさせていただきました。
[Webpackでライブラリを作る](https://qiita.com/jkr_2255/items/283bc12dd07bc237179e)

ライブラリ化するために`package.json`に`output`項目を追記します。

```package.json
module.exports = {
  mode: "development",
  entry: "./src/index.js",
  output: {
    library: "Test",
    libraryTarget: "umd"
  }
  module: {
    rules: [
　　　・・・
    ]
  }
};
```

次にコンパイルして、ブラウザに読み込ませます。

```
var test = new Test('a');
```

こんな感じでインスタンスを作成してみたんですが、エラーがでます。

```
Uncaught TypeError: Test is not a constructor
```

調べた結果、`webpack`でライブラリ化した場合、この`package.json`の記述だと、
`Test`という名前のクラスが作成されず、`Test.default`という名前で作成されることがわかりました。

なので、

```
var test = new Test.default('a');
test.testFunction();
=> a
```

こんな感じでインスタンスを作成するとうまくいきます。

ただ、`defalut`を付けたくなかったので、それをなくす設定を`package.json`に追記しました。
以下ページに詳細が記載されています。
[Ability to export only module's default when building a library #3929](https://github.com/webpack/webpack/issues/3929)

```package.json
・・・
  output: {
    library: "Test",
    libraryExport: "default",
    libraryTarget: "umd"
  }
・・・
```

これでコンパイルしてやると、

```
var test = new Test('a');
test.testFunction();
=> a
```

無事`defalut`なしでインスタンスを作成することができました。

# 最後に

今回の記事で書いたプログラミングの様子をYoutube上にアップロードしておりますので、是非ご覧ください。
[【実況】babel7+webpack4でライブラリ開発環境構築](https://www.youtube.com/watch?v=jd2c5ZrfsrQ)
[えんじにぁ〜TV](https://www.youtube.com/channel/UCYCbtkuInmgpK0Hv3W2orEg)