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
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
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',
},
};
ソース
<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>
上記のような感じで読み込んでいるとする。
読み込みイメージ
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でビルドを通すことができる。
// コンパイルを通すため、外部から読み込む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のバージョンなど確認用としてそのまま出力。
{
"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"
}
}