6時だョ!!全員集合!!

Rails・JavaScrictを中心にアウトプットします。

2022年5月7日 アルゴ式 番外編

プログラム上で入力を扱う

Ruby
N, V = gets.split(' ').map!(&:to_i)
A = gets.split(' ').map!(&:to_i)

puts N
puts V
puts A.class
JavaScript
function main(input) {
  const args = input.split("\n");
  const inputArray = args.map((n) => n.split(" "));
  const array1 = inputArray[0].map((n) => parseInt(n, 10));
  const N = array1[0];
  const V = array1[1];
  const A = args[1].split(" ").map((n) => parseInt(n, 10));
  console.log(N);
  console.log(V);
  console.log(A);
}

main(require('fs').readFileSync('/dev/stdin', 'utf8'));
  • String.prototype.split()は、引数に渡した改行コードや空白文字にマッチする部分を取り除いて、その部分をコンマで要素を区切り配列を返します。
  • parseInt()は整数の文字列をNumber型に変更します。第二引数は10進数を指定しています。

今回の問題

配列の全探索 2

Image from Gyazo

Ryuji's answer

javascript

function main(input) {
const args = input.split("\n");
  const inputArray = args.map((n) => n.split(" "));
  const array1 = inputArray[0].map((n) => parseInt(n, 10));
  const N = array1[0];
  const V = array1[1];
  const A = inputArray[1].map((n) => parseInt(n, 10));

  const results = A.filter(word => word === V);
  console.log(results.length);

}

main(require('fs').readFileSync('/dev/stdin', 'utf8'));

typescript

import * as fs from 'fs'
const input       = fs.readFileSync("/dev/stdin", "utf8")
const [nv, alist] = input.split("\n")

const [n,v,..._]  = nv.split(" ").map(Number)
const list        = alist.split(" ").map(Number)

const results: number[] = list.filter(word => word === v);
console.log(results.length);
  • 次回から関数で書いていきます!

    Yano's answer

N, V = gets.split(' ').map!(&:to_i)
A = gets.split(' ').map!(&:to_i)

count_v = A.select { |n| n == V }.size

puts count_v
  • rubyではfilterとselectは同じ結果が得られます。
function main(input) {
  const args = input.split("\n");
  const inputArray = args.map((n) => n.split(" "));
  const array1 = inputArray[0].map((n) => parseInt(n, 10));
  const N = array1[0];
  const V = array1[1];
  const A = args[1].split(" ").map((n) => parseInt(n, 10));
  
  countV = A.filter(n => n === V).length
  console.log(countV);
}

main(require('fs').readFileSync('/dev/stdin', 'utf8'));
  • countVの定義時にconstをつけ忘れていましたが出力に問題はありませんでした。
    • 変数宣言が行われていない変数に値を格納した場合は、グローバルスコープの変数として宣言したとみなされます。strictモードではエラーになります。

Yuki's answer

import * as fs from 'fs'
const input       = fs.readFileSync("/dev/stdin", "utf8")
const [nv, alist] = input.split("\n")

const [n,v,..._]  = nv.split(" ").map(Number)
const list        = alist.split(" ").map(Number)

type CountSameNum = {
  (targetNum: number, array: number[]): number;
};

const countSameNum: CountSameNum = (targetNum, array) => {
  const resultArray = array.filter((num) => num === targetNum);
  return resultArray.length;
};

console.log(countSameNum(v, list));
◆ 型エイリアスで呼び出し可能オブジェクトを定義する

省略なし

type Fn = {
  (num1: number, num2: number): number
}

省略記法

type Fn = (num1: number, num2: number) => number

参考

Tricky use case

2022年5月6日 りあクト! 第7章 Reactをめぐるフロントエンドの歴史 (p.86~)

フロントエンドの歴史

出来事
2005 Googleマップが登場
2006 jQueryが登場
2008 GoogleChromeJavaScriptエンジンであるV8をオープンソース化して公開
2009 V8エンジンを採用したJavaScriptの実行環境であるNode.jsがリリース
2009 ES5を発表
2010 Backbone.js、Knockout、AngularJSなどのフレームワークが登場(後のVue.jsにも影響を与えたKnockoutの影響でJQueryへの依存が断ち切られる)
2011 Flash Playerの開発が中止される
2013 Reactが公開
2021 HTML5が廃止され、HTML Living Standardが標準になる

Reactを読み解く6つのキーワード

  • Declarative (宣言的)
  • Component-Based (コンポーネントベース)
  • Just The UI (UIにしか関知しない)
  • Virtual DOM (仮想DOM)
  • One-Way Dataflow (単方向データフロー)
  • Learn Once, Write Anywhere (ひとたび習得すれば、あらゆるプラットフォームで開発できる)

Reactの宣言的とは (Declarative)

宣言的プログラミングとは

出力の性質やあるべき状態を記述してプログラムを構成する事です。

命令型プログラミングとは

最終的な出力を得るために、時系列に沿って直前の状態に依存しながら命令を順番に書いていく手法の事です。


Reactの特徴の一つに、宣言的が掲げられています。 Reactは宣言的というコンセプトを2つの系統から得ました。

どんなデータを表示されるべきかを記述しておくことでReactがそのデータを表示して適切なタイミングで表示を更新します。 (UIを宣言的に表現する)

参照透過性とは

参照透過性とは、同じ入力に対しては必ず同じ出力が得られることです。参照透過性が担保された関数は、同じ引数に対して、必ず同じ戻り値が返ってきます。

参考

りあクト! TypeScriptで始めるつらくないReact開発 第3.1版【Ⅱ. React基礎編】 p.86~

2022年5月5日 Railsガイド Active Record の関連付け

has_many :through 関連付け

Physician・・・・医者

Appointment・・・診察予約

Patient・・・患者

class Physician < ApplicationRecord
  has_many :appointments
  has_many :patients, through: :appointments
end

class Appointment < ApplicationRecord
  belongs_to :physician
  belongs_to :patient
end

class Patient < ApplicationRecord
  has_many :appointments
  has_many :physicians, through: :appointments
end
  • 医者は、複数の診察予約を持つことができ、複数の患者を担当することが出来ます。
  • 患者は、複数の診療予約を持つことができ、複数の医者から担当されることが出来ます。
  • 診療予約にはどの医者とどの患者が関連付けされているかを、2つの外部キーで判断することが出来ます。
  • throughオプションで2つの外部キーを持つ診療予約を参照することできます。
    • physician.patientsで医者に診療予約した患者のリストを出すことが出来ます。
    • patient.physiciansで患者が担当される医者のリストを出すことが出来ます。

中間テーブルの存在意義

usersとcourcesテーブルがあるとして、多対多のアソシエーションを直接紐付けると、1カラムの中にデータは1つずつしか入れられないため、1人のuserがいくつのcourceを選択するかわからないため、選択をしなかった場合に空のカラムができてしまい良くないテーブル設計になってしまいます。

ここで中間テーブルでそれぞれのuser_idとcources_idという外部キーを持たせたテーブルを用意する事で、空のカラムを作る事なく多対多のアソシエーションを組むことができます。

中間テーブルを使わない場合のデメリット

  • カラム数が多くなる

  • 未使用(NULL)のカラムが多くなる

  • NULLが沢山入ってしまうアンチパターンという良くない設計になる

中間テーブルとは?

"join table もしくは junction table"とも呼ばれ、その名の通り、2つのテーブルの中間にもう一つ、それぞれに接続されたテーブルを指します。

中間テーブルには、接続先の外部キー同士を紐付けて格納しています。

例) twitterの良いね機能を考えます。 この場合、良いねする人(userテーブル)と良いねされる投稿(boardテーブル)があります。1人のユーザーは、複数の投稿に良いねでき、1つの投稿に対して複数のユーザーから良いねをもらうことができます(多対多)。このような場合に中間テーブルを使うことで良いねしたユーザーのuser_idと良いねされた投稿のboard_idをそれぞれ紐づけて格納してくれます。中間テーブルを使う場合、throughを使います。

class User < ApplicationRecord
  has_many :boards
  has_many :favorites # 中間テーブルと紐づけるための記述
  has_many :favorite_boards, through: :favorites, source: :board
end

# いいねする人といいねした投稿を紐付ける中間テーブル
# 外部キーであるuser_idとboard_idを格納しています。
class Favorite < ApplicationRecord
  belongs_to :user
  belongs_to :board
end

class Board < ApplicationRecord
  has_many :users
  has_many :favorites # 中間テーブルと紐づけるための記述
  has_many :favorite_users, through: :favorites, source: :user
end
  • user.favorite_boardsでユーザーが良いねした投稿の一覧を取得します。
  • board.favorite_usersで投稿に良いねしたユーザーの一覧を取得します。

参考

Railsガイド Active Record の関連付け
Qiita-やさしい図解で学ぶ 中間テーブル 多対多 概念編

2022年5月3日 りあクト! 第6章 stylelint (p.74~)

stylelintとは

stylelintはCSSのlinterです。

使用するには4つのパッケージをインストールします。

  • stylelint ... stylelint本体です。
  • stylelint-config-standard ... stylelint公式による標準の共有設定です。
  • stylelint-order ... stylelintの並び順に関するルールセットのプラグインです。
  • style-config-recess-order ... RECESSに基づくCSSの並び替えのための共有設定です。
yarn add -D stylelint stylelint-config-standard stylelint-order stylelint-config-recess-order

(typesync) ← 型定義ファイルの読み込みはpackage.jsonのpreinstallに設定してあるのでインストール前に自動で走ります。
yarn  ← yarn installの省略

stylelint導入後の設定

プロジェクトルートに.stylelintrc.jsを配置し、設定を追記します。

.stylelintrc.js
  module.exports = {
    // extendsに共有設定を書く
    extends: [
      'stylelint-config-standard',
      // リセスはTwitterが提供していたCSSのコード品質ツール
      // リセスをstylelint-orderに移植したものが以下の設定。
      'stylelint-config-recess-order'
    ],
    // pluginsにプラグインルールを書く
    plugins: [
      'stylelint-order'
    ],
    ignoreFiles: [
    // node_modulsディレクトリ配下にあるCSSを対象外する。
      '**/node_modules/**'
    ],
    // rulesはリンターが何を探し、何を訴えるかを決定します。
    // Stylelint には 170 以上のルールが組み込まれています。 
    // デフォルトではどのルールもオンになっておらず、
    // デフォルト値もありません。各ルールを有効にするには、明示的に設定する必要があります。
    // キーはルールの名前、値はルールの設定です。
    rules: {
      'string-quotes': 'single'
    }
  }; 
  • stylelint-config-standardは公式が提供している標準の共有設定です。
  • 今回採用しませんでしたがstylelint-config-recommendedの方が広く使用されています。
  • style-config-standardは、stylelint-config-recommendedを拡張しつつGoogleAirbnb が定めた CSS スタイルガイドを適用した厳格な設定です。

VSCodeのsettings.jsonに設定する

設定を追加します。

{
+ "css.validate": false,
+ "less.validate": false,
+ "scss.validate": false,
  "editor.codeActionsOnSave": {
  "source.fixAll.eslint": true,
+ "source.fixAll.stylelint": true
  },
  "editor.formatOnSave": false,
  ︙

package.jsonにnpm scriptsの登録をする

ESlintやPrettierとまとめて走るようにします。

  "scripts": {
...
    "lint": "npm run -s lint:style; npm run -s lint:es",
    "lint:fix": "npm run -s lint:style:fix && npm run -s lint:es:fix",
    "lint:es": "eslint 'src/**/*.{js,jsx,ts,tsx}'",
    "lint:es:fix": "eslint --fix 'src/**/*.{js,jsx,ts,tsx}'",
    "lint:conflict": "eslint-config-prettier 'src/**/*.{js,jsx,ts,tsx}'",
    "lint:style": "stylelint 'src/**/*.{css,less,sass,scss}'",
    "lint:style:fix": "stylelint --fix 'src/**/*.{css,less,sass,scss}'",
    "preinstall": "typesync || :"
  },
  • ESLintは"lint:es"というオプション名に変更し、stylelintは"stylelint:es"としてオプションを追加します。
  • 元々"lint"として設定していたESLintのオプションはlint:esとstylelint:esオプションをまとめて実行出来るように変更します。
--fix

ESLint や stylelint を --fix モードで走らせると、簡単なルール違反は自動で修正してくれますが、直しきれない複雑なものは手動で修正する必要があります。

Git Hooks

特定のアクションが発生したときに任意のスクリプトを走らせるGitのしくみです。 Git Hooksを管理するsimple-Git-hooksというツールがあります。 huskyというツールの方が有名です。しかし、5系以降に複雑な設定が増えた為、現在はsimple-Git-hooksも使われています。

上記のツールを用いてGitのコミットやプッシュ前後にLintのスクリプトを実行する設定をすることが出来ます。

参考

りあクト! TypeScriptで始めるつらくないReact開発 第3.1版【Ⅱ. React基礎編】 p.74~

Configuration

2022年5月2日 Rails開発者が採用面接で聞かれる想定Q&A 53問(翻訳)を深ぼる(Q1〜Q10)

基本的な用語

コレクション

コレクションとは,いくつかのオブジェクトをまとめて取り扱うための「容器」として振る舞うオブジェクトです。Rubyの標準ライブラリはいくつかのコレクション・クラスを提供しています。代表的なものはArray(配列)とHash(ハッシュまたは連想配列)です。 引用

Rubyにおけるオブジェクト

オブジェクト指向言語におけるオブジェクトとは、クラスのインスタンスのことです。 全てのインスタンス(オブジェクト)を作るクラスはclassクラスを継承しています。 class自体がclassクラスのインスタンスです。

irb(main):002:0> Class.class
=> Class

オブジェクト指向言語

オブジェクトを基本的な単位としてプログラムをつくることが出来る言語です。 オブジェクト指向とはそのプログラミングの性質のことをいいます。

オブジェクト指向言語ではオブジェクトの雛形であるクラス(class)やプロトタイプ(prototype)、および内部のメソッド(method)やプロパティ(property)を定義する構文や、オブジェクトのインスタンス化、メソッド呼び出しなどの機能が提供されています。

インスタンス変数

class User
  def initialize(name)
    @name = name
  end
  
  # クラス内で定義したインスタンス変数は、
  # クラス内で自由に使うことができます。
  def hello
    puts "Hello, I am #{@name}"
  end
end

user = User.new('Alice')
user.hello # => Hello, I am Alice
class User
  # インスタンス変数を参照するためには、ゲッターを定義する
  attr_reader :name
  def initialize(name)
    @name = name
  end
  
  def hello
    puts "Hello, I am #{@name}"
  end
end

user = User.new('Alice')
user.hello # => Hello, I am Alice
puts user.name # => Alice

ローカル変数

  • ローカル変数とは、メソッドやブロックの内部で作成される変数です。
  • @がついていない変数です。
  • ブロックの外では使用出来ません。

sendメソッド

sendとは、レシーバの持っているメソッドを引数に渡すことで呼び出してくれるメソッドです。

obj.hello  #=> 'hello'
obj.send(:hello) #=> 'hello'
  • objは何かのクラスのインスタンスで、そのクラス内でhelloメソッドが定義されているという前提です。
  • objはhelloメソッドを持つため、sendを経由して実行することが出来ます。

デザインパターン

デザインパターンとは、「よく出会う問題とそれにうまく対処するための設計」をまとめたものです。

引用

セッター・ゲッター

Rubyではゲッター(getter)を用いてインスタンス変数にアクセスでき、セッター(setter)を用いてインスタンス変数に値を設定できます。

セッター(クラス内)

  def name_change=(name)
      @name = name
  end

クラス内で上記のようにセッターを定義することで値の変更を出来るようになります。 attr_writerやアクセサーを定義することで、上記の定義をせずにセッターが使用できます。

class User
  attr_reader :name
  attr_writer :name
  def initialize(name)
    @name = name
  end
  
  def hello
    puts "Hello, I am #{@name}"
  end
end

user = User.new('Alice')
# インスタンスは、所属しているクラスに定義してあるメソッドを呼び出すことができる
user.hello # => Hello, I am Alice
puts user.name # => Alice
user.name ="YUKI";
user.hello

ActiveRecordを継承したモデルのインスタンスの場合は、生成した段階でアクセサーが自動的に定義されるため、セッターやゲッターを自分で定義しなくても使用することが出来ます。

irb(main):001:0> @user = User.new()
=> #<User id: nil, email: nil, crypted_password: nil, salt: nil, created_at: nil, updated_at: nil, first_name: nil, last_name: nil, avatar: nil, reset_password_token: nil, reset_password_token_expires_at: nil, reset_password_email_sent_at: nil, access_count_to_reset_password_page: 0, role: "general">
# respond_to?を使うことで、オブジェクトがメソッドを持つかを判定できます。
irb(main):002:0> @user.respond_to?(:email)
=> true
irb(main):003:0> @user.respond_to?(:email=)
=> true

参考

デザインパターンの基本 Rails開発者が採用面接で聞かれる想定Q&A 53問(翻訳) 7 Design Patterns to Refactor MVC Components in Rails

2022年4月30日 アルゴ式 番外編

アルゴ式とは

プログラミングを解くドリルが提供されているWEBサービスである。by yano

今回の問題

配列の全探索 1 Image from Gyazo

Ryuji's answer

JavaScript

function main(input) {
const args = input.split("\n");
  const inputArray = args.map((n) => n.split(" "));
  const array1 = args[0].split(" ").map((n) => parseInt(n, 10));
  const N = array1[0];
  const V = array1[1];
  const A = args[1].split(" ").map((n) => parseInt(n, 10));

  const found = A.find(e => e === V);

  found ? console.log("Yes") : console.log("No");


}

main(require('fs').readFileSync('/dev/stdin', 'utf8'));
  • ArrayのメソッドをMDNに見にいきました。
  • メソッドを閲覧している時にfindメソッドが目に止まりました。
  • Node.jsでSequelizeのfindOneメソッドでログインの処理を実装したときにデータベースに登録してあるメールアドレスと入力したメールアドレスを照合する時のロジックが頭の中で浮かび、findメソッドでできそうだと仮説を立てて挙動を確認したら今回の問題に使えると思いました。
  • Aの配列の中からVに一致する値をfound変数に代入するようにしました。
  • 三項演算子を使い実行結果を条件分岐し提出したところLGTMでした。

Yano's answer

N, V = gets.split(' ').map!(&:to_i)
A = gets.split(' ').map!(&:to_i)

if A.include?(V)
  puts "Yes"
else
  puts "No"
end

pメソッドを使用するとテストが通らず不正解になるため、注意です。

N, V = gets.split(' ').map!(&:to_i)
A = gets.split(' ').map!(&:to_i)

puts A.include?(V) ? "Yes" : "No"

三項演算子パターンの場合、上記で正解となります。

map!(&:to_i)

以下とほぼ同義です。 map!とするとレシーバを破壊的に変更することができます。

.map {|n| n.to_i}

Yuki's answer

JavaScript

function main(input) {
  const args = input.split("\n");
  const inputArray = args.map((n) => n.split(" "));
  const array1 = args[0].split(" ").map((n) => parseInt(n, 10));
  const N = array1[0];
  const V = array1[1];
  const A = args[1].split(" ").map((n) => parseInt(n, 10));

  const hasArray = A.find((num) => num === V) ? "Yes" : "No";
  console.log(hasArray);
}

main(require('fs').readFileSync('/dev/stdin', 'utf8'));

TypeScript

import * as fs from 'fs'
const input = fs.readFileSync("/dev/stdin", "utf8")
const [nv, alist] = input.split("\n")

const [n,v,..._] = nv.split(" ").map(Number)
const list = alist.split(" ").map(Number)

const hasArray = list.find((num) => num === v) ? "Yes" : "No";
console.log(hasArray);
  • 条件に一致する配列の要素が存在する場合、Yesを返しています。

Yui's answer

// 入力値を受け取る
function main(input) {
  const args = input.split("\n"); // 入力文字列を改行で分割し、新しい配列を作成
  const inputArray = args.map((n) => n.split(" ")); // さらに空白文字列で配列を分割
  const array1 = args[0].split(" ").map((n) => parseInt(n, 10));
  const N = array1[0];
  const V = array1[1];
  const A = args[1].split(" ").map((n) => parseInt(n, 10));

 
  // 配列の要素の中に整数Vが含まれるか判定
  if (A.find((element) => element === V)){
    console.log("Yes");
  } else {
    console.log("No");
  }
}

main(require('fs').readFileSync('/dev/stdin', 'utf8'));
  • readFileSyncメソッドは、同期的にファイルを読み込むfsモジュールのメソッドです。fs.readFileSync(path\[, options\])が基本形です。
  • fsモジュールは、Node.jsでファイルの読み書きを行うための基本的な関数を提供するモジュールです。

参考

アルゴ式 Beta JavaScript標準入力まとめ【パターン別】

2022年4月29日 りあクト! 第6章 特別なフォーマッタ 『Prettier』 (p.67~)

Prettier

Prettierはフロントエンドのメジャーどころをほぼ網羅しているフォーマッタです。 TypeScript、HTML、CSS、Vue、Angular、GraphQL、CSS in JS の styled-components など

コードフォーマッタとは

インデントや改行などの記述スタイルのフォーマットを統一して整形するツールを指します。

導入するメリット

開発者がコードの書き方のスタイルをめぐる論争をやめさせる目的で開発されているので、新人からベテランまで一律のコードに直してくれるところです。(無駄な言い争いがなくなります) 具体的には以下になります。

  • ソースコードの品質を保つため(コードのスタイルの一貫性を保つため)
  • コードレビュー時に、設計や命名などの重要な箇所に集中するため(コードのスタイルの指摘に時間を割くのを防ぐため)
  • 複数のメンバーが各自の整形ルールを適用し、更新する度に余計な差分が発生することを防ぐため
  • ソースコードを綺麗にするための労力(スタイル定義の議論や時間)を費やさなくて済むため
  • ツールに任せられることはツールに任せてしまった方が今後楽になるため

ESLintとPrettierを併用する理由

Prettier 入門 ~ESLintとの違いを理解して併用する~に、ESLintとPrettierを併用する理由が詳しく記載されているので、以下に引用します。

ESLint でもeslint --fixでコード整形ができるが、Prettier の方がコード整形が優れているから。

具体的には以下の点が優れている。

・ESLint では整形できないコードを整形できる
・ESLint と比べて手軽で確実に整形できる

但し、PrettierはESLintのような構文チェック機能がない

そのため、コードの整形は Prettier が行い、コードの構文チェックは ESLint が行うように併用する必要があります。

Prettierの環境を作る

パッケージの導入

ESLintの環境にPrettierを加えるには、以下の2つのパッケージを導入します。

  • prettier
    • Prettier本体
  • eslint-config-prettier
    • Prettierと競合する可能性のあるESLintの各種ルールを無効にする共有設定

パッケージをインストールしたら.eslintrc.jsのextendsオプションの最後に'prettier'を追加します。

.prettierrcでPrettierのオプションを設定

設定オプション一覧はドキュメントに記載があります。 https://prettier.io/docs/en/options.html

書籍では以下の3項目の設定を変更していました。

{
  "singleQuote": true,
  "trailingComma": "all",
  "endOfLine": "auto"
}

カスタマイズした設定以外はデフォルト値が適用されます。

ESlintで設定したルールとPrettierで設定したルールが衝突していないかをチェックする

$ npx exlint-config-prettier 'src/**/*.{js,jsx,ts,tsx}'
No rules that are unnecessary or conflist with Prettier were found.

上記は衝突していない場合に表示されます。

衝突した場合
The following rules are unnecessary or might conflict with Prettier:
- @typescript-eslint/indent

この場合は@typescript-eslint/indentの設定が不要なので .eslintrc.js から削除します。

Prettierがnpmのscriptsで実行されるようにpackage.jsonに登録する

"scripts": {
 ︙
 "eject": "react-scripts eject",
+ "fix": "npm run -s format && npm run -s lint:fix",
+                 " f o r m a t " : " p r e t t i e r - - w r i t e - - l o g l e v e l = w a r n
'{public,src}/**/*.{js,jsx,ts,tsx,html,gql,graphql,json}'",
    "lint": "eslint 'src/**/*.{js,jsx,ts,tsx}'",
    "lint:fix": "eslint --fix 'src/**/*.{js,jsx,ts,tsx}'",
+   "lint:conflict": "eslint --print-config .eslintrc.js | eslint-config-prettier-check",
     "preinstall": "typesync"
},

衝突ルールの検出もしています。

VSCodeの設定

settings.jsonに追記します。

"editor.defaultFormatter": "esbenp.prettier-vscode",
"[graphql]": {
  "editor.formatOnSave": true
},
"[javascript]": {
  "editor.formatOnSave": true
},
"[javascriptreact]": {
  "editor.formatOnSave": true
},
"[json]": {
  "editor.formatOnSave": true
},
"[typescript]": {
  "editor.formatOnSave": true
},
"[typescriptreact]": {
  "editor.formatOnSave": true
},

VSCodeのデフォルトのフォーマッタにPrettierを設定して各種言語の保存時に自動整形できるようにしています。

保存時に自動整形できるようになりました。

メモ

パスを通すとは

コマンド検索パス(コマンドサーチパス) を追加することです。

パスを通す理由

コマンド名と同じファイル名を持つ実行ファイルを探索できるようにするためです。パスを通すことで、実行ファイルのパスを入力しなくても、コマンドで実行ファイルを実行できます。

source

パスの内容をその場で反映させるためのコマンドです。

echo

画面にメッセージを表示させるためのコマンドです。 「echo $変数名」など環境変数やシェル変数を表示する際にも使用します。

参考

りあクト! TypeScriptで始めるつらくないReact開発 第3.1版【Ⅱ. React基礎編】 p.67~

Prettier 入門 ~ESLintとの違いを理解して併用する~