はじめに
Vue等であればvue-cli
で新規プロジェクトを作ってしまえばいいのだが、
別にVue等を使わないCUIツールなり簡単なものをザクっと書きたいとき用に最小構成のものが欲しかったので作ってみた。
(あとはそもそもここ最近のモダンな構成をゼロから用意したことなかったので勉強がてら)
作ったもの
作ったものはこんな感じ。
├─dist │ └─── bundle.js │ ├─node_modules ├─src │ ├─── app.spec.ts │ └─── app.ts │ ├─ .gitignore ├─ .eslintrc.js ├─ .prettierrc ├─ jest.config.js ├─ package-lock.json ├─ package.json ├─ tsconfig.json └─ webpack.config.js
手順
プロジェクトの初期化
とりあえずプロジェクト用のディレクトリを切り、最低限のソースと.gitignore
を用意しておく。
$ mkdir minimum-ts-template && cd $_ $ npm init -y $ mkdir src && touch src/app.ts .gitignore
src/app.ts
export const SayHello = (): string => { return 'Hello! TypeScript!' } console.log(SayHello())
.gitignore
node_modules dist
TypeScript/Webpackの設定
必要なパッケージを追加し、それぞれの設定ファイルを作成。内容はお好きに変更してどうぞ。
$ npm i -D typescript ts-loader webpack webpack-cli $ touch tsconfig.json webpack.config.js
tsconfig.json
{ "compilerOptions": { "target": "ES2017", "module": "es2015", "baseUrl": ".", "paths": { "@/*": ["src/*"] }, "outDir": "./dist/", "removeComments": true, "strict": true, "noImplicitAny": true, "strictNullChecks": true, "strictFunctionTypes": true, "strictPropertyInitialization": true, "noImplicitThis": true, "alwaysStrict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "esModuleInterop": true }, "include": ["src/**/*"], "exclude": ["node_modules", "**/*.spec.ts"] }
webpack.config.js
const path = require('path') module.exports = { entry: './src/a.ts', module: { rules: [ { test: /\.ts$/, use: 'ts-loader', exclude: /node_modules/, }, ], }, resolve: { extensions: ['.ts', '.js'], }, output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist'), }, }
設定ファイルを追加したらpackage.json
にbuildスクリプトを追加。
package.json
"scripts": {
+ "build": "webpack --mode=development",
"test": "echo \"Error: no test specified\" && exit 1"
},
これで下記のようにTypeScriptのビルドが出来るようになる。
$ npm run build Hash: 12c5408bc864105b0202 Version: webpack 4.30.0 Time: 919ms Built at: 2019-04-19 14:09:37 Asset Size Chunks Chunk Names bundle.js 4.07 KiB main [emitted] main Entrypoint main = bundle.js [./src/app.ts] 97 bytes {main} [built]
$ node dist/bundle.js Hello! TypeScript!
ESlint/Prettierの設定
The future of TypeScript on ESLint
という事なのでTSLintではなくESLintにしましょう。
まずはパッケージの追加を行って各種設定ファイルを作成。細かいルールはお好きなように。
$ npm i -D eslint @typescript-eslint/eslint-plugin prettier eslint-config-prettier eslint-plugin-prettier $ touch .prettierrc .eslintrc.js
.prettierrc
{ "singleQuote": true, "semi": false, "trailingComma": "all" }
.eslintrc.js
module.exports = { extends: ["eslint:recommended", "plugin:prettier/recommended"], plugins: ["@typescript-eslint", 'prettier'], parser: "@typescript-eslint/parser", parserOptions: { sourceType: "module", project: "./tsconfig.json", }, env: { browser: true, node: true, es6: true, }, rules: { "no-console": "warn", "@typescript-eslint/adjacent-overload-signatures": "warn", "@typescript-eslint/no-unnecessary-type-assertion": "error", } }
設定ファイルを追加したらpackage.json
にlintスクリプトを追加。
package.json
"scripts": { "build": "webpack --mode=development", + "lint": "eslint --ext .js,.ts --ignore-path .gitignore .", + "lint:fix": "eslint --fix --ext .js,.ts --ignore-path .gitignore .", "test": "echo \"Error: no test specified\" && exit 1" },
これで下記のようにESLint/PrettierによるLintができるようになる。
$ npm run lint D:\workspace\javascript\minimum-ts-template\src\app.ts 2:10 error Replace `"Hello!·TypeScript!";` with `'Hello!·TypeScript!'` prettier/prettier 3:2 error Delete `;` prettier/prettier 5:1 warning Unexpected console statement no-console 5:24 error Delete `;` prettier/prettier ✖ 4 problems (3 errors, 1 warning) 3 errors and 0 warnings potentially fixable with the `--fix` option.
$ npm run lint:fix D:\workspace\javascript\minimum-ts-template\src\app.ts 5:1 warning Unexpected console statement no-console ✖ 1 problem (0 errors, 1 warning)
Jestの設定
最後にテストフレームワークのJestのパッケージを追加。やはり設定ファイルがあるのでそちらも追加。
$ npm i -D jest ts-jest @types/jest eslint-plugin-jest $ touch jest.config.js
ESLintに設定を追加。
.eslintrc.
module.exports = { extends: ["eslint:recommended", "plugin:prettier/recommended"], - plugins: ["@typescript-eslint", 'prettier'], + plugins: ["@typescript-eslint", 'prettier', "jest"], parser: "@typescript-eslint/parser", parserOptions: { sourceType: "module", project: "./tsconfig.json" }, env: { browser: true, node: true, es6: true, + "jest/globals": true, }, rules: { "no-console": "warn", "@typescript-eslint/adjacent-overload-signatures": "warn", "@typescript-eslint/no-unnecessary-type-assertion": "error", } }
設定ファイルを追加したらpackage.json
のtestスクリプトを修正。
package.json
"scripts": { "build": "webpack --mode=development", "lint": "eslint --ext .js,.ts --ignore-path .gitignore .", "lint:fix": "eslint --fix --ext .js,.ts --ignore-path .gitignore .", - "test": "echo \"Error: no test specified\" && exit 1" + "test": "jest" },
app.ts
に対するテストを書いてみる。
touch src/app.spec.ts
src/app.spec.ts
import { SayHello } from './app' describe('SayHello', () => { test('toBe "Hello! TypeScript!"', () => { expect(SayHello()).toBe('Hello! TypeScript!') }) test('not toBe "Hello! JavaScript!"', () => { expect(SayHello()).not.toBe('Hello! JavaScript!') }) })
これで準備は整ったのでテストを実行。
$ npm run test PASS src/app.spec.ts SayHello √ toBe "Hello! TypeScript!" (3ms) √ not toBe "Hello! JavaScript!" console.log src/app.ts:5 Hello! TypeScript! Test Suites: 1 passed, 1 total Tests: 2 passed, 2 total Snapshots: 0 total Time: 2.868s Ran all test suites.
以上で最小構成のプロジェクトが完成!
全然関係ないけどはてなブログのコードブロックもQiitaみたいにファイル名つけられるようになったらいいなぁ・・・