LoginSignup
8
13

More than 5 years have passed since last update.

typescriptで import しなくても jqueryが使えるようになっていたので、他の外部ライブラリとしてchart.jsを読み込んでみたメモ

Last updated at Posted at 2018-12-30

jQueryを使おうと思ったら、今は import しなくてもよいらしい。

chart.jsやfirebaseも同じように行けるかなと思ったけれども、そうはいかなかったのでメモ。

vueの型定義が読み込めず、typescriptのビルドが通らなかったので型定義に書いたが、
どうすればよかったのだろう。 node_modules/vue/types/vue.d.tsは確かにあったのだが、、
tscでトランスパイルしてから、webpackでバンドルする想定。

環境

  • virtualbox 5.2.22
  • vagrant 2.2.2
  • Ubuntu 18.04.1 LTS (GNU/Linux 4.15.0-29-generic x86_64)
  • Docker version 18.09.0, build 4d60db4
  • docker-compose version 1.23.2, build 1110ad01
docker/webpack/Dockerfile
FROM node:11.5.0
WORKDIR /app
RUN npm init -y
RUN yarn add --dev @babel/core \
                  @babel/cli \
                  @babel/preset-env
RUN yarn add @babel/polyfill
RUN yarn add --dev typescript
RUN yarn add --dev tslint tslint-config-airbnb
RUN yarn add --dev webpack
RUN yarn add --dev webpack-cli
RUN yarn add --dev webpack-dev-server
RUN yarn add --dev @types/jquery
RUN yarn add --dev @types/materialize-css
RUN yarn add --dev @types/chart.js
webpack.config.js
module.exports = {
  mode: MODE,
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: { loader: 'babel-loader' },
      },
    ],
  },
  // cdnから読み込むものはここに
  externals: {
    jquery: 'jQuery',
    firebase: 'firebase',
    firebaseui: 'firebaseui',
    vue: 'Vue',
    'chart.js': 'Chart',
  },
};

ソース

src/index.html
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-rc.2/js/materialize.min.js"></script>
    <script src="https://www.gstatic.com/firebasejs/5.4.1/firebase.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script>
    <script type="text/javascript" src="bundle.js"></script>
  </body>
</html>

上記のような感じで読み込んでいるとする。

読み込みイメージ

src/index.ts
import { Chart } from 'chart.js';
import * as firebase from 'firebase';
// Vueとvueで名前が異なっており、tslintでfixされてしまうので、disable-lineを指定。
import Vue from 'vue'; // tslint:disable-line 

 $('.sidenav').sidenav();

 // document.querySelector('.my-chart')! ... (non-null-assertion-operator)を付与するとtypescriptのnullチェックによるコンパイルエラーを回避できる
const canvas = document.querySelector('.my-chart')! as HTMLCanvasElement;
const ctx = canvas.getContext('2d')!;

const data = {/*省略*/};
const options = {/*省略*/};
const myRadarChart = new Chart(ctx, {type: 'radar',options,data,});

if (!firebase.apps.length) {
  const config = require('./_config'); // tslint:disable-line no-var-requires
  firebase.initializeApp(config);
}

const app = new Vue({
  el: '#editform',
  data: {/* 省略 */ },
});

jquery

上記で分かるように、突然 $()のように使用しても、問題はなかった。
型定義があれば、拡張も反映されており、ビルドが通る。

chart.jsなども型定義を読み込んでいるが、こちらはimportしてやらないとビルドが通らない。

型定義ファイル

  • 以下のように定義してやれば、外部から読み込むファイルもtypescriptでビルドを通すことができる。
src/type.d.ts
// コンパイルを通すため、外部から読み込むjsライブラリの宣言を行う。
declare module 'firebase';
declare module 'firebaseui';
declare module 'vue';

// JQueryのインタフェースの拡張を行う。
// yarn add --dev @types/materialize-cssで型定義ファイルを入手していれば不要だが、参考までに。
interface JQuery {
  sidenav(): JQuery;
}

参考用:使用例

参考

TypeScript の型定義ファイルと仲良くなろう
TypeScript で型定義ファイル( d.ts )がないときの対処法
Stack Over Flow : typescript document.getElementByIDで HTMLElement | null の型のせいでエラー
typescriptでjqueryを拡張
tslint ルール一覧

おまけ

検証環境のpackage.json。elmなども入っているが、typescriptのバージョンなど確認用としてそのまま出力。

package.json
{
  "name": "app",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "watch": "chokidar '/app/**/*.pug' -p -c 'npm run build-pug' ",
    "build-pug": "pug /app/src -o /app/dist ",
    "pug": "pug -o /app/dist -P ",
    "elm-watch": "yarn run chokidar '/app/**/*.elm' -p -c 'yarn run build-elm' ",
    "build-elm": "yarn run elm make /app/src/assets/elm/ElmTest.elm --output=/app/dist/elm/ElmTest.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@babel/cli": "^7.2.3",
    "@babel/core": "^7.2.2",
    "@babel/preset-env": "^7.2.3",
    "@types/chart.js": "^2.7.42",
    "@types/jquery": "^3.3.29",
    "@types/materialize-css": "^1.0.6",
    "autoprefixer": "^9.4.3",
    "babel-loader": "^8.0.4",
    "chokidar": "^2.0.4",
    "chokidar-cli": "^1.2.1",
    "clean-webpack-plugin": "^1.0.0",
    "copy-webpack-plugin": "^4.6.0",
    "cpx": "^1.5.0",
    "css-loader": "^2.1.0",
    "cssnano": "^4.1.8",
    "elm": "^0.19.0-bugfix2",
    "elm-format": "^0.8.1",
    "esdoc": "^1.1.0",
    "esdoc-standard-plugin": "^1.0.0",
    "eslint": "^5.11.0",
    "eslint-config-airbnb-base": "^13.1.0",
    "eslint-plugin-import": "^2.14.0",
    "eslint-plugin-jasmine": "^2.10.1",
    "file-loader": "^3.0.1",
    "globule": "^1.2.1",
    "html-loader": "^0.5.5",
    "html-minifier-webpack-plugin": "^2.0.0",
    "html-webpack-plugin": "^3.2.0",
    "mini-css-extract-plugin": "^0.5.0",
    "node-sass": "^4.11.0",
    "postcss": "^7.0.7",
    "postcss-cli": "^6.1.0",
    "pug": "^2.0.3",
    "pug-cli": "https://github.com/pugjs/pug-cli.git",
    "style-loader": "^0.23.1",
    "stylelint": "^9.9.0",
    "stylelint-config-sass-guidelines": "^5.3.0",
    "stylelint-order": "^2.0.0",
    "stylelint-scss": "^3.4.4",
    "tslint": "^5.12.0",
    "tslint-config-airbnb": "^5.11.1",
    "typedoc": "^0.13.0",
    "typescript": "^3.2.2",
    "uglify-js": "^3.4.9",
    "webpack": "^4.28.2",
    "webpack-cli": "^3.1.2",
    "webpack-dev-server": "^3.1.14",
    "webpack-merge": "^4.1.5"
  },
  "dependencies": {
    "@babel/polyfill": "^7.2.5"
  }
}
8
13
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
8
13