Kuzunoha-NEのブログ

プログラミングなどの勉強をしてます

【TypeScript】Webpackでフロントにnpmモジュールを使う

こんばんは、葛の葉です。

今回はWebpackを使います。

Webpackとは

Webpackとはざっくり説明すると、複数のJavascriptをまとめて一つにしてくれるものです。これを使用することでnpm経由でインストールしてきたモジュールをフロントで使用することができます。

webpack.js.org

インストールします

npm i --save-devを使ってwebpackをインストールをします。またwebpackはver4.0なのでwebpack-cliというものもインストールします。ver3.0以下の場合はwebpack-cliはいらないみたい。

npm i --save-dev webpack webpack-cli

また、今回はTypescriptを使いたいのでwebpack用のモジュールを使います。

www.npmjs.com

npm i --save-dev typescript ts-loader 

ts-loaderを使うにはtsconfig.jsonが必要です。

npx tsc --init

上記のコマンドを使うとtsconfig.jsonが出来上がります。しかし、strict": trueのところはコメントアウトしておきます。以下のような形になります。

// tsconfig.json
{
  "compilerOptions": {
    "target": "es5",                          /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
    "module": "es2015",                       /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
    "esModuleInterop": true                   /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
  }
}

次にwebpackを使うために以下のようなwebpack用のコンフィグを作ります。名前はwebpack.config.jsです。

// webpack.config.js

module.exports = {
    entry: './src/index.ts',
    output: {
        path: __dirname + '/dist',
        filename: 'app.js',
    },
    optimization: {
        minimize: true,
    },
    module: {
        rules: [
            {
                test: /\.ts$/,
                use: 'ts-loader'
            }
        ]
    },
    resolve: {
        extensions: [ '.ts', '.js' ]
    }
};

ディレクトリの構造を以下のようにします。index.tsの中身は全く無しにします。

// index.ts
// 何も書かない
├── dist
│   ├── index.html
│   └── (app.js #あとから出来上がる)
├── package-lock.json
├── package.json
├── src
│   └── index.ts
├── tsconfig.json
└── webpack.config.js

srcディレクトリに今後TypeScriptを書いていきます。そしてwebpackを使ってdistディレクトリにapp.jsを出力するようになってます。

npx webpack 

そうすると少しWarningが出ますが、dist/app.jsが出来上がります。内容を見てみると以下のようなものでした。

!function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=0)}([function(e,t){}]);

改行や空白がなく人間には非常に読みにくいjsが出てきました。これがwebpackで生成されたjsになります。このように空白がない方が読み込みは早くなるようです。これはwebpack.config.jsoptimizationminimizeを変更すればもっと人間が読みやすい形になります。

    optimization: {
        minimize: false,
    },
/******/ (function(modules) { // webpackBootstrap
/******/    // The module cache
/******/    var installedModules = {};
/******/
/******/    // The require function
/******/    function __webpack_require__(moduleId) {
/******/
/******/        // Check if module is in cache
// 長いので省略

モジュールを使おう

今回はAwesompleteというモジュールを使います。これはきれいにオートコンプリート機能を実装することができる代物です。

leaverou.github.io

npm i --save awesompletenpm i --save-dev @types/awesompleteと実行しインストールします。

そうしましたらindex.tsを以下のようにしましょう。

import Awesomplete from 'awesomplete';

const input = document.getElementById("awesome");

// wordsの配列の中身は好きに変更してください。
const words = ["徳川家康", "徳川吉宗", "徳川綱吉", "天草四郎", "パトリック・ジェーン"];

const awesom = new Awesomplete(input, {list:words});

また、AwesompleteはオートコンプリートをCSSで表現しています。そのCSSnode_modules/awesomplete/awesomplete.cssにあります。そのCSSdistディレクトリにコピーします。

 cp node_modules/awesomplete/awesomplete.css dist/

今度はWebpackで合体したjavascriptを読み込むindex.htmlを作成します。

<html>
    <header>
        <link rel="stylesheet" type="text/css" href="awesomplete.css">
        <meta charset="utf8">
    </header>
    <body>
        <div>
            <input id="awesome">
        </div>
        <script src="app.js"></script>
    </body>
</html>

そうしたらnpx webpackと打ちましょう。app.jsが生成されているはずです。そうして、index.htmlを表示してみましょう。以下のgifのようにオートコンプリートが動作しているはずです。

f:id:Kuzunoha-NE:20191002234413g:plain