2018.11.15
Ionicを使ってスマホアプリ開発をしていて、アプリケーションの規模が大きくなるにつれて徐々にディレクトリ構造がカオスなことになってきた。リファクタリングしようと細かめにディレクトリを分けたら、今度は他のコンポーネントやサービスのimport
がimport { AnalyticsService } from '../../../../services/core/analytics.service';
のようにひたすら../../
が並ぶ状況になってしまった。tsconfig.json
の変更で解決できるとの情報を見て試してみたのだが、これがまた全くうまくいかない。
Ionicプロジェクトのディレクトリは以下のようになっている。(必要なもののみに絞ってある)
├── config.xml
├── ionic.config.json
├── package.json
├── platforms
├── plugins
├── resources
├── src
│ ├── app
│ ├── assets
│ ├── components
│ ├── constants
│ ├── directives
│ ├── index.html
│ ├── manifest.json
│ ├── models
│ ├── pages
│ ├── pipes
│ ├── service-worker.js
│ ├── services
│ └── theme
├── tsconfig.json
├── tslint.json
├── tslint.json.default
└── webpack.config.js
定数を管理するファイルをsrc/constants/app.constant.ts
に配置して運用している。この定数をimport { AppConstant } from '@constants/app.constant';
で読み込めるようにしてみる。
export const AppConstant = {
apiRoot: 'http://localhost:3000',
// 本当はもうちょっといくつか設定がある
}
compilerOptions
のセクションに以下を追加した。カンマをつけるところ、つけないところに注意が必要。
"baseUrl": "src",
"paths": {
"@constants/*": [ "constants/*" ]
}
変更後のtsconfig.json
は以下の通り。
{
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"declaration": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": [
"dom",
"es2015"
],
"module": "es2015",
"moduleResolution": "node",
"sourceMap": true,
"target": "es5",
"baseUrl": "src",
"paths": {
"@constants/*": [ "constants/*" ]
}
},
"include": [
"src/**/*.ts"
],
"exclude": [
"node_modules",
"src/**/*.spec.ts",
"src/**/__tests__/*.ts"
],
"compileOnSave": false,
"atom": {
"rewriteTsconfig": false
}
}
以下の内容でwebpack.config.js
を作成する。要はnode_modules/@ionic/app-scripts/config/webpack.config
の設定をベースに自分の設定を追加している。
const path = require('path');
const webpackConfig = require('./node_modules/@ionic/app-scripts/config/webpack.config');
webpackConfig.dev.resolve.alias = {
'@constants': path.join(__dirname, './src/constants')
};
package.json
の一番浅い階層にconfig
セクションを追加して以下のような設定を追加する。
"config": {
"ionic_source_map_type": "source-map",
"ionic_webpack": "./webpack.config.js"
}
以下がpackage.json
の全体像。だいぶ省略したので、このまま貼り付けても動かないことに注意。config
セクションをどこに配置するかの参考として。
{
"name": "myapp",
"version": "0.0.1",
"author": "Ionic Framework",
"homepage": "http://ionicframework.com/",
"private": true,
"scripts": {
"clean": "ionic-app-scripts clean",
"build": "ionic-app-scripts build",
"lint": "ionic-app-scripts lint",
"ionic:build": "ionic-app-scripts build",
"ionic:serve": "ionic-app-scripts serve"
},
"dependencies": {
"@angular/animations": "5.2.9",
// その他いろいろ
},
"devDependencies": {
"@ionic/app-scripts": "3.1.8",
"typescript": "~2.6.2"
},
"description": "An Ionic project",
"cordova": {
"plugins": {
"cordova-plugin-whitelist": {},
// その他いろいろ
},
"platforms": [
"ios"
]
},
"config": {
"ionic_source_map_type": "source-map",
"ionic_webpack": "./webpack.config.js"
}
}
これで無事import { AppConstant } from '@constants/app.constant';
ができるようになった。これで多少のディレクトリの移動は全く問題なくなった!リファクタリングが捗る!??
tsconfig.json
の変更だけではうまくいかないとわかり、webpack.config.js
との格闘開始。webpack.config.js
のどこかにalias
というセクションがあり、そこにまずは自分の設定を入れてみないと記事の情報が正しいか間違っているかが判断できないと考えた。webpack.config.js
は見たところJavaScriptなので、console.log
で設定内容が見られるかと仮説を立ててみたら、案の定みることができた。alias
セクションを追加すればいいかあたりをつけてやってみたら、動いた。だいぶ格闘方法が洗練されてきた。