27
28

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[webpack]ts-loaderでJavaScriptをトランスコンパイルする(babel-loader不要)

Posted at

[webpack]ts-loaderでJavaScriptをトランスコンパイルする(babel-loader不要)

こちらにも同じ記事を書いています

ts-loaderはJavaScriptをトランスコンパイル出来るのか?

 ts-loaderはTypeScriptをトランスコンパイルするというのが、固定観念になっていないだろうか?しかしTypeScriptのパッケージに付属するtscではJavaScriptをコンパイル出来る。ならばts-loaderでも同様のことが出来て当然なはずだ。特にTypeScript3.7系統になってからは、JavaScriptのトランスコンパイル関する制約がかなり緩和された。ならば試してみるのが早い。

環境構築

パッケージのインストール

適当なディレクトリを作り、以下のコマンドを使ってパッケージを放り込む
コンパイルはTypeScriptにやらせるので、babel類はもちろんインストールしない

yarn init -y
yarn add -D typescript ts-loader webpack webpack-cli

Webpackの設定

今回はJavaScriptのトランスコンパイルが前提なので、最小限のビルド設定のみを記述している
modeをdevelopmentにしているのは、吐き出したソースの状態を視覚的に確認するためである

webpack.config.js
const path = require("path");
module.exports = {
  mode: "development",
  //  mode: 'production',
  entry: [path.resolve(__dirname, "src/index.js")],
  output: {
    filename: "bundle.js",
    path: path.resolve(__dirname, "dist/js")
  },
  module: {
    rules: [
      {
        test: /\.(js|ts)$/,
        exclude: /node_modules/,
        loader: "ts-loader"
      }
    ]
  },
  resolve: {
    extensions: [".ts", ".js"]
  },
  devtool: "source-map"
};

tsconfig.jsonの設定

ts-loaderを使う場合、JavaScriptのトランスコンパイルもtsconfig.jsonに記述することになる
重要項目はallowJsで、これをtrueに設定しておかなければJavaScriptはコンパイル出来ない

src/tsconfig.json
{
  "compilerOptions": {
    "target": "es5",      /*ES5にトランスコンパイル*/
    "module": "commonjs",
    "lib": [
      "es2018",
      "dom"
    ],
    "allowJs": true, /*JavaScriptのコンパイルには必須*/
    "checkJs": true, /*JavaScriptで簡易的な型チェックを行う*/
    "sourceMap": true,
    "inlineSources": true,
    "outDir": "../../dist",
    "strict": true,
  }
}

テスト用プログラムの作成

アロー関数とfor-ofはES5へのトランスコンパイルが行われる
bodyの取得にquerySelectorを使っているのは後でTypoの実験をするためなので気にしないで欲しい

src/index.js
addEventListener("DOMContentLoaded", () => {
  const message = "動作テスト\nを行う\nサンプル";
  const body = document.querySelector("body");
  if (body) {
    for (const msg of message.split("\n")) {
      const node = document.createElement("div");
      node.innerHTML = msg;
      body.appendChild(node);
    }
  }
});
dist/index.html
<!DOCTYPE html>
<html>
<head>
  <meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
  <meta charset="utf-8">
  <title>ts-loader sample</title>
  <script type="text/javascript" src="js/bundle.js"></script>
</head>
<body>
</body>
</html>

ビルドとその結果

ビルド

yarn webpack

出力コード(コメント部分は除去)

見事にES5へのトランスコンパイルが行われている
ts-loaderでJavaScriptのトランスコンパイルに成功したのだ!

dist/js/bandle.js
"use strict";

addEventListener("DOMContentLoaded", function () {
    var message = "動作テスト\nを行う\nサンプル";
    var body = document.querySelector("body");
    if (body) {
        for (var _i = 0, _a = message.split("\n"); _i < _a.length; _i++) {
            var msg = _a[_i];
            var node = document.createElement("div");
            node.innerHTML = msg;
            body.appendChild(node);
        }
    }
});

ts-loaderの利点

  • babel-loaderがいらない
    ts-loaderだけでトランスコンパイル出来るので、babel-loaderは必要なくなる
    polyfillのような機能は無いので、@babel/coreは必要に応じて追加すれば良い

  • 簡易的な型チェックが利用できる
    たとえば

const body = document.querySelector("body");

 を

const body = document.querySelect("body");

 というTypoをしたとすると、トランスコンパイル時に以下のように出力される

TS2551: Property 'querySelect' does not exist on type 'Document'. Did you mean 'querySelector'?

 JavaScriptを使っていながら、TypeScriptの恩恵にあずかれるのだ

  • TypeScriptとJavaScriptのやりとりにd.tsが不要となる
    TypeScript3.7系統はJavaScriptのコンパイル時、d.tsを自動生成する能力を持っている。この機能が働くと、TypeScriptからJavaScriptのファイルをimportするときに、d.tsを手動で作らなくてもそのまま読み込むことが可能だ。

  • JavaScriptからTypeScriptへの移行が楽になる
    JavaScriptをメインで使っている人も、ある日TypeScriptでコードが書きたくなったときに必要なのは拡張子をtsにしたファイルを作ることだけだ

jsとtsのプログラムを混在させる

src/add.ts
export function Add(a: number, b: number) {
  return a + b;
}
src/index.js
import { Add } from "./add";

addEventListener("DOMContentLoaded", () => {
  const body = document.body;
  if (body) body.innerHTML = `10+20=${Add(10, 20)}`;
});

結果

10+20=30

JavaScriptからTypeScriptを呼び出しているが、もちろん逆も可能だ。

まとめ

JavaScriptとは型指定を省略できるTypeScriptなのだ

という感覚でプログラムが書ける。
これからTypeScriptへ移行しようかと迷っている方々は、とりあえずローダーだけts-loaderに差し替えてみてはどうだろうか?

27
28
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27
28

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?