TypeScript×Vue.jsにMoment.jsを導入しようとした時にエラーが発生したので
- TypeScript×Vue.js環境へのMoment.js導入方法
- 発生したエラーの解決方法
をまとめます。
バージョン
- Vue.js 2.6.12
- TypeScript 3.9.9
- Moment.js 2.29.1
全てpackage.json
に記載の情報です。
実行コマンド
Moment.jsのインストール
$ npm install -D moment
VueコンポーネントでMoment.jsのimport
import moment from "moment"
-D
は--save-dev
と同じオプションです。
(この記事では開発環境を想定)
ビルド
以下どちらでも同じエラーに
$ docker-compose exec app npm run dev
$ docker-compose exec app npm run watch
Docker環境で開発しているのでDocker環境ではない方はnpm run dev
or npm run watch
でOKです。
エラー出力
エラーはインストール、インポートの後のビルド実行時に発生しました。
(略)
TS1259: Module '"/var/www/html/node_modules/moment/ts3.1-typings/moment"'
can only be default-imported using the 'allowSyntheticDefaultImports' flag
/var/www/htmlはDockerコンテナ内のルートディレクトリのパスなのでここは各ユーザーで異なります。
[補足]Moment.jsについて
Moment.jsはざっくり言うと「日付を扱うための便利なパッケージ」です。
JavaScriptで日付を扱うオブジェクトを文字列を変換したり、文字列を日付のオブジェクトに変換したりしてくれる機能を持ちます。
この記事はMoment.jsの使い方について割愛させていただきます。
以下が公式ドキュメントです。
JavaScriptで日付を扱うDateオブジェクトが準備されていますが、Moment.jsの方が便利なのかなと思いました。
エラーの解決方法
エラー文の意味
まず、エラー文の抜粋です。
can only be default-imported using the 'allowSyntheticDefaultImports' flag
Google翻訳さん曰く
‘allowSyntheticDefaultImports’フラグを使用してのみデフォルトでインポートできます
とのこと。
なるほど、allowSyntheticDefaultImportsというものがいるということはわかりました。
ということで、Moment.jsの公式ドキュメントを見ています。
[公式ドキュメント]Moment.js-TypeScript
上記リンクからTypeScript環境で使う場合の設定が書かれており、要約すると以下の通り。
- Typescript 2.xの場合、
tsconfig.json
のcompilerOptions
に"moduleResolution": "node"
を追加 - Typescript 1.xの場合、
tsconfig.json
のcompilerOptions
に"allowSyntheticDefaultImports": true
を追加

TypeScript 3.xの場合は…?
という疑問は残りつつ、エラー文の通り、後者の対応をします。
tsconfig.jsonにallowSyntheticDefaultImportsフラグを追記する
先ほど記述した通り、tsconfig.json
にallowSyntheticDefaultImports: true
を追記します。
{
"compilerOptions": {
// 略
"allowSyntheticDefaultImports": true
},
"include": [
// 略
]
}
この後、以下コマンドでビルドする問題なくビルドされました。
// Docker環境
$ docker-compose exec app npm run dev
$ docker-compose exec app npm run watch
// ローカル
$ npm run dev
$ npm run watch
[補足]tsconfig.jsonとは
こちらのサイトから引用させていただきます。
tsconfig.jsonファイルは、TypeScriptを開発言語としたプロジェクトにおいて、アプリのビルド時にJavaScriptへコンパイルする対象となる(プロジェクトに含まれる)TypeScriptファイル(.tsファイル)と、それらをJavaScriptコードへコンパイルする際のコンパイルオプションなどを指定するファイルだ。通常は、プロジェクトのルートディレクトリに配置する。
https://www.atmarkit.co.jp/ait/articles/1603/08/news029.html
TypeScript用の設定ファイルのことで、TypeScriptを使う時はマストなファイルですね。
tsconfig.jsonの設定項目はこちらの記事にまとまっていました。
導入方法まとめ
$ npm install -D moment
import moment from "moment"
{
"compilerOptions": {
// TypeScript 1.xの場合
"moduleResolution": "node"
// TypeScript 1.xの場合
"allowSyntheticDefaultImports": true
},
"include": [
// 略
]
}
$ npm run dev
$ npm run watch
[重要]Moment.jsの新規プロジェクトへの導入は非推奨
ここまでMoment.jsの導入方法をまとめましたが、Moment.jsは今後は新規開発をしないので新規プロジェクトで使うなら別のライブラリを使うことが公式からも推奨されています。
セキュリティサポートやバグ対応は引き続き行うようなので、現在導入済みの場合は問題ないかと。
以下が公式のツイートです。
公式ドキュメントでは以下の別のライブラリを使うことを推奨しています。
- Luxon
- Day.js
- date-fns
- js-Joda
もしくはライブラリは使わず、JavaScriptのDateオブジェクトを使う方法です。
Moment.js Documentation – Project Status
本記事では実務で既に導入済みのプロジェクトに携わっており、「へえ、Moment.jsとかあるんだ〜」という感じで調べて書いている記事です。実際にこのタイミングで新規導入した訳ではありません。
最後に
JavaScriptで以下コマンドでimportする場合は上手く行きますが、TypeScirptを使う場合には別途設定が必要なことがわかりました。
import moment from "moment"
あと、TypeScript 3.xの場合の正しい設定方法を公式ドキュメントに追記して欲しいなとちょっとだけ思いました。
これでTypeScript×Vue.jsの環境でも日付データを便利に使えるMoment.jsを使えるようになりました。
P.S.
公式ドキュメントを見れば大体のことは解決する
コメント