Web制作向けnpm-scripts

更新版
[Web制作向けnpm-scripts 3](https://qiita.com/takeshisakuma/items/34db1aa11a4e25508f66)


# npm-scriptsのWeb制作向けタスクランナー
Web制作は細かいやることが多いので、少しでも自動化して手作業を減らしたいと考えました。

一人で完結する作業であれば、[Prepros](https://prepros.io/)や[Koala](http://koala-app.com/)(開発終了)などGUIのツールや、エディタの標準、拡張機能で実現できる事も多いですが、複数人で作業を行う場合、無駄な作業やトラブルを避けるために環境を統一する、コーディング規約を遵守するなどかなり面倒です。

そこでよく使われるGulpやWebpackですが、学習コストがかかる上に、Web制作ではそこまでの機能はいらない場合が多いので、比較的入門しやすいと感じたnpm-scriptsでWeb制作向けのタスクランナーを作ってみました。



## やりたい事
Web制作の効率化のため、作業の自動化を設定します。


|  |HTML  |CSS  |JavaScript  |
|---|---|---|---|
|変換元  |Pug,EJS  |CSS,Stylus |TypeScript |
|旧ブラウザ対応 |-  |Autoprefixer |transpile |
|SourceMap|- |〇|〇|
|圧縮|-|〇|〇|
|整形|-|〇|〇|
画像ファイルのデータ圧縮
Browser-Syncによるオートリロード
※TypeScriptを使わず、JavaScriptを直接記述するパターンを追加しました。
※この記事内では触れていないのですが、TypeScriptのtranspileが必要な場合、tsconfig.jsonのオプションの設定を行ってください。

### altで書いて変換するメリット
HTML、CSS、JavaScriptでは使えない機能が使えます。

||メリット|
|---|---|
|altHTML(Pug,EJS)|条件分岐　ファイルの分割管理　変数の使用　など|
|altCSS(SCSS,Stylus)|ファイルの分割管理　mixin　など|
|altJS(TypeScript)|古いJavaScriptへの変換　型の使用 など|

## 0. 準備

### 0.1 エディタの設定変更
コードフォーマットやAutoprefixerなどタスクランナーで処理する事は、エディタ側であらかじめ無効にしておいてください。

### 0.2 Node.jsのインストール
Node.jsのパッケージを使って処理を自動化するので、最初に、Node.jsのインストールを行います。
Node.jsのパッケージ管理ツールのnpm(Node Package Manager)も一緒にインストールされます。
npmを使って、必要なパッケージをインストールしていきます。
[Node.js](https://nodejs.org/en/download/)

Node.jsとnpmが正常にインストールされたか確認します。
Windows環境で「Command prompt」を使い、作業を進めていきます。
「Command prompt」は、Mac環境の場合は「Terminal」と読み替えてください。

「Command prompt」を立ち上げ、下記のコマンドを実行し、バージョンが表示されればインストールできています。
(Command promptは場合によっては管理者として起動が必要になるかもしれません。)

``` 
$ node -v
$ npm –v
```
-vは--versionの短縮形で、Node.js、npmの現在インストールされているバージョンを表示します。

### 0.3 プロジェクトディレクトリの準備
ディレクトリ「website」(任意の名前)を作成し、中に移動します。
npmも一緒にインストールされます。

```
$ cd (デスクトップなど、プロジェクトを置きたい場所)
$ mkdir website
$ cd website
```

ディレクトリをnpmの管理下に置きます。

```
$ npm init -y
```
initはinitializeを意味します。
-yオプションは、これからされるはずだった質問に、すべてyesと答えるものです。
今回はスキップするため、指定しておきます。
プロジェクトディレクトリのルートにpackage.jsonファイルが生成されます。

### 0.4. 必要なファイルの準備
src配下のファイルを用意してください。
PugとEJS、SCSSとStylusはそれぞれどちらか片方だけで良いです。
PugとEJSの、includeさせたいファイルがある場合は、_includeディレクトリに配置してください。
※他の設定ファイル群は作業を進めていく時に作成します。

```
website
├ src
│　├ pug
│　│ └ index.pug
│　│
│　├ ejs
│　│ └ index.ejs
│　│
│　├ _include
│　│ └ _included.pug(_included.ejs)
│　│
│　├ img
│　│ ├ img.jpg
│　│ ├ img.png
│　│ ├ img.svg
│　│ └ img.gif
│　│ 
│　├ scss(stylus)
│　│ └ style.scss(style.styl)
│　│
│　├ ts
│　│ └ main.ts
│　│
│　└ js
│　  └ main.js
│
├ package.json
├ package-lock.json
│
├ imagemin.js
│
├ tsconfig.json
│
├ .browserslistrc
│
├ .eslintrc.json 
│
├ .prettierrc.json　
│
├ .stylelintrc.json(.stylintrc.json)
│
└ .stylelintignore 
```

## 1. 変換

### 1.1. HTML
altHTML(EJSまたはPug)をHTMLに変換します。(導入はどちらか片方だけで良いです。)
パーツの共通化を行う都合上、どこから参照されてもいいように、サイト内へのリンクはルートパスで記述します。
ルートパスで書かれたHTMLファイルをそのままブラウザで開くと別ページへのリンクやCSSファイルへのパスが合わないので、確認は1.2.のBrowser-Syncで行います。

#### 1.1.1. EJSをHTMLに変換する場合
Pugを使う場合は飛ばして1.1.2に進んでください。

##### 1.1.1.1. パッケージのインストール
ejs-cliと、chokidar-cliのインストールを行います。

```
$ npm i ejs-cli -D
$ npm i chokidar-cli -D
```

ejs-cliはファイル監視機能を持たないので、ファイルの更新を監視して処理を行うchokidarもインストールしています。

|キーワード|内容|
|---|---|
|install(i)|指定したNode.jsのパッケージをインストール|
|--save-dev(-D)|プロジェクトディレクトリ内へのインストールを指定|

初回のパッケージインストールは、package-lock.jsonと「node_modules」ディレクトリが生成され、ejs-cli以外のパッケージもインストールされるので、少し時間がかかります。

##### 1.1.1.2. package.jsonへの追記

```json:package.json
"scripts": {
  "compile:ejs2html": "ejs-cli -b src/ejs/ \"/**/*.ejs\" -o dist/",
  "watch:ejs2html": "chokidar \"src/ejs/\" -c \"npm run compile:ejs2html\" --initial"
}
```

|タスク|処理内容|
|---|---|
|compile:ejs2html|EJSファイルをhtmlファイルに変換(実行時)|
|watch:ejs2html|EJSファイルをhtmlファイルに変換(実行時、EJSファイル変更時)|


|キーワード|内容|
|---|---|
|ejs-cliの--base-dir(-b)|ベースとなるディレクトリを指定|
|ejs-cliの--out(-o)|出力先のディレクトリを指定|
|chokidarの--command(-c)|実行したいタスクを指定|
|chokidarの--initial|ファイルの変更時だけでなく、起動時にも一度実行|
ejs-cliは、特に指定しなくても階層構造を維持してファイルを出力します。

##### 1.1.1.3. タスクの実行
下記のコマンドで変換を実行します。

```
$ npm run watch:ejs2html
```
dist配下にHTMLファイルが生成されます。
EJSファイルを更新すると、HTMLファイルも更新されます。
確認できたら、Ctrl+Cで処理を終了します。

#### 1.1.2. PugファイルをHTMLファイルに変換する場合
EJSを使う場合は1.1.1を参照してください。

##### 1.1.2.1 パッケージのインストール
pug-cliをインストールします

```
$ npm i github:pugjs/pug-cli#master -D
```

|キーワード|内容|
|---|---|
|install(i)|指定したNode.jsのパッケージをインストール|
|--save-dev(-D)|プロジェクトディレクトリ内へのインストールを指定|

※本来は、「npm i pug-cli -D」でインストールするところですが、別のPugをincludeしたときにincludeされる側のファイルも別ファイルとして出力されてしまうので、出力されないように改善されたバージョンをインストールしています。

初回のパッケージのインストールは、package-lock.jsonと「node_modules」ディレクトリが生成され、pug以外のパッケージもインストールされるので、少し時間がかかります。

##### 1.1.2.2. package.jsonへの追記

```json:package.json
"scripts": {
  "watch:pug2html": "pug src/pug/ --hierarchy -o dist/ -w -P"
}
```

|タスク|処理内容|
|---|---|
|watch:pug2html|PugファイルをHTMLファイルに変換(実行時、Pugファイル変更時)|

|キーワード|内容|
|---|---|
|--hierarchy|階層構造を保つ|
|--out(-o)|出力先のディレクトリを指定|
|--watch(-w)|ファイルを監視して、更新がある度に処理を実行|
|--pretty(-P)|インデントを有効化|

##### 1.1.2.3 タスクの実行

```
$ npm run watch:pug2html
```
dist配下にHTMLファイルが生成されます。
Pugファイルを更新すると、HTMLファイルも更新されます。
確認できたら、Ctrl+Cで処理を終了します。






### 1.2.Browser-Sync
生成したファイルを確認するため、Browser-Syncを導入します。

#### 1.2.1. パッケージのインストール

Browser-Syncをインストールします。

```
$ npm i browser-sync -D
```
#### 1.2.2. package.jsonへの追記

```json:package.json
"scripts": {
  "start:server": "browser-sync start -s dist -w src/*.html src/css/*.css src/js/*.js"
}
```

|タスク|処理内容|
|---|---|
|start:server|Browser-Syncを起動|

|キーワード|内容|
|---|---|
|start|Browser-Syncを開始する|
|--server(-s)|開くディレクトリを指定|
|--watch(-w)|監視するファイルを指定|


#### 1.2.3. タスクの実行

```
$ npm run start:server
```
ブラウザが立ち上がって、dist/index.htmlが表示されます。
※dist/index.htmlが存在しないと、「Cannot GET /」と表示されます。

Browser-SyncをCtrl+Cで終了します。


### 1.3. Autoprefixer
ベンダープレフィックスの追加は、SCSSファイルやStylusファイルを汚さないため生成したCSSに適用します。

#### 1.3.1. パッケージのインストール
postcss-cliとautoprefixerをインストールします。

```
$ npm i postcss-cli -D 
$ npm i autoprefixer -D
```

(2021/1/30)パッケージのアップデートをしたところ、postcssの8以上を入れるように言われるようになったので、下記も追加

```
$ npm i postcss -D 
```

#### 1.3.2. package.jsonへの追記
```json:package.json
"scripts": {
  "compile:css2cssprefix": "postcss dist/css/style.css -u autoprefixer -o dist/css/style.css"
}
```

|タスク|処理内容|
|---|---|
|compile:css2cssprefix|CSSファイルにベンダープレフィックスを追加(実行時)|

|キーワード|内容|
|---|---|
|--use(-u)|プラグインを指定|
|--output(-o)|出力先を指定|


#### 1.3.3. 設定ファイルの準備
プロジェクトルートに.browserslistrcファイルを作成し、対象ブラウザを記述します。

```
defaults
```
設定は下記URLを参考に適宜変更してください。
https://github.com/browserslist/browserslist
[.browserslistrcで対象ブラウザを指定する](https://qiita.com/takeshisakuma/items/0bc1c39ee976bd1f52d7)
[.browserslistrcに設定した対象ブラウザの確認](https://browserl.ist/)

コマンドで対象ブラウザを確認することもできます。

```

$ npx browserslist
```

まだ、CSSファイルを生成していないので、Autoprefixerの追加処理は実行せずに次に進みます。


### 1.4 CSS
SCSSファイルもしくはStylusファイルをCSSファイルに変換します。

#### 1.4.1. SCSSファイルをCSSファイルに変換する場合
Stylusファイルを使用する場合は、1.4.2に進んでください。

##### 1.4.1.1 パッケージのインストール
node-sassとnode-sass-globbingとnpm-run-allをインストールします。

```
$ npm i node-sass -D
$ npm i node-sass-globbing -D
$ npm i npm-run-all -D
```
##### 1.4.1.2.package.jsonへの追記

```json:package.json
"scripts": {
  "compile:scss2css": "node-sass src/scss/style.scss --importer node_modules/node-sass-globbing/index.js dist/css/style.css --output-style expanded --source-map dist/css/",
  "compile:scss2cssprefix":"run-s compile:scss2css compile:css2cssprefix",
  "watch:scss2cssprefix":"chokidar \"src/scss/\" --command \"npm run compile:scss2cssprefix\" --initial"
}
```

|タスク|処理内容|
|---|---|
|compile:scss2css|SCSSファイルをCSSファイルに変換(実行時)|
|compile:scss2cssprefix|SCSSファイルをCSSファイルに変換し、Autoprefixを追加(実行時)|
|watch:scss2cssprefix|SCSSファイルをCSSファイルに変換し、Autoprefixを追加(実行時、SCSSファイル変更時)|

|キーワード|内容|
|---|---|
|--importer|カスタムインポーターのJavaScriptファイルへのパスを指定|
|--output-style|出力するCSSファイルの整形タイプを選択(nested、expanded、compact、compressed)|
|--source-map|SourceMapを出力する|

##### 1.4.1.3. glob
node-sass-globbingは、globという機能を使うために必要です。
globは、同じディレクトリからのimportを行う時ファイル名を個別に指定せずワイルドカードで済ませることができるため、SCSSファイルが増えるたびにimportを記述せずに済みます。

SCSSファイルを個別にインポートする場合

```scss:style.scss
@import "layout/_header";
@import "layout/_footer";
```

SCSSファイルをglobで一括してインポートする場合

```scss:style.scss
@import "layout/*";
```

##### 1.4.1.4. タスクの実行

```
$ npm run watch:scss2cssprefix
```
dist/css配下にCSSファイルが生成されます。
SCSSファイルを更新すると、CSSファイルも更新されます。
SCSSファイルの内容と、.browserslistrcの内容次第で、CSSファイルにベンダープレフィックスが追加されます。
確認できたら、Ctrl+Cで処理を終了します。




#### 1.4.2. StylusファイルをCSSファイルに変換する場合
SCSSファイルを使用する場合は、1.4.1を参照してください。

##### 1.4.2.1. パッケージのインストール

stylusとmkdirpとnpm-run-allをインストールします。

```
$ npm i stylus -D
$ npm i mkdirp -D
$ npm i npm-run-all -D
```

##### 1.4.2.2. package.jsonへの追記

```json:package.json
"scripts": {
  "precompile:stylus2css": "mkdirp dist/css",
  "compile:stylus2css": "stylus src/stylus/style.styl -o dist/css/ -m",
  "compile:stylus2cssprefix":"run-s compile:stylus2css compile:css2cssprefix",
  "watch:stylus2cssprefix":"chokidar \"src/stylus/\" -c \"npm run compile:stylus2cssprefix\" --initial"
}
```

|タスク|処理内容|
|---|---|
|precompile:stylus2css|dist/cssフォルダを作成|
|compile:stylus2css|SCSSファイルをCSSファイルに変換|
|compile:stylus2cssprefix|StylusファイルをCSSファイルに変換し、Autoprefixを追加(実行時)|
|watch:stylus2cssprefix|StylusファイルをCSSファイルに変換し、Autoprefixを追加(実行時、SCSSファイル変更時)|

stylusでの変換は、dist/cssフォルダが存在しないとエラーになってしまうため、変換の前にmkdirpでdist/cssディレクトリを作成します。

|キーワード|内容|
|---|---|
|--out(-o)|出力先の指定|
|--sourcemap(-m)|SourceMapを出力|

##### 1.4.2.3. glob
Stylusはデフォルトでglobに対応しています。
globは、同じディレクトリからのimportを行う時ファイル名を個別に指定せずワイルドカードで済ませることができるため、stylファイルが増えるたびにimportを記述せずに済みます。

stylファイルを個別にインポートする場合

```scss:style.scss
@import "layout/_header"
@import "layout/_footer"
```

stylファイルをglobで一括してインポートする場合

```scss:style.scss
@import "layout/*"
```

##### 1.4.2.4 タスクの実行

```
$ npm run watch:stylus2cssprefix
```

dist/css配下にCSSファイルが生成されます。
Stylusファイルを更新すると、CSSファイルも更新されます。
Stylusファイルの内容と、.browserslistrcの内容次第で、CSSファイルにベンダープレフィックスが追加されます。
確認できたら、Ctrl+Cで処理を終了します。




### 1.5. JavaScript
TypeScriptを記述してJavaScriptに変換するか、直接JavaScriptを記述します。

#### 1.5.1. TypeScriptをJavaScriptに変換する場合
TypeScriptを使わず、直接JavaScriptを記述する場合は1.5.2に進んでください

##### 1.5.1.1. パッケージのインストール

```
$ npm i typescript -D
```

##### 1.5.1.2 設定ファイルの準備
tsconfig.jsonを作成します。

```
$ tsc --init
```
SourceMapを出力しないので、    // "sourceMap": true,のコメントアウトを解除します。

設定は下記URLを参考に適宜変更してください。
https://www.typescriptlang.org/docs/handbook/tsconfig-json.html
TypeScriptのtranspileが必要な場合、tsconfig.jsonのtargetオプション等で設定を行ってください。

##### 1.5.1.3. package.jsonへの追記

```json:package.json
"scripts": {
  "watch:ts": "tsc --rootDir src/ts --outDir dist/js -w"
}
```

|タスク|処理内容|
|---|---|
|watch:ts|TypeScriptファイルを監視してJavaScriptに変換|

|キーワード|内容|
|---|---|
|--rootDir|入力ファイルのルートディレクトリを指定(--outDirでの出力ディレクトリ制御)|
|--outDir|出力構造をディレクトリにリダイレクト|
|--watch(-w)|ファイルの変更を監視|


##### 1.5.1.4. タスクの実行

```
$ npm run watch:ts
```
dist/js配下にJavaScriptファイルと、SourceMapファイルが生成されます。
TypeScriptファイルを更新すると、JavaScriptファイルとSourceMapファイルが更新されます。
Ctrlで処理を終了します。

#### 1.5.2 JavaScriptを直接記述する場合
TypeScriptを使用する場合は、1.6に進んでください。

##### 1.5.2.1 パッケージのインストール
```
$ npm i cpx -D
```

##### 1.5.2.2. package.jsonへの追記

```json:package.json
"scripts": {
  "watch:js": "cpx \"src/js/*.js\" dist/js/ -w"
}
```
|タスク|処理内容|
|---|---|
|watch:ts|src/js/配下のJavaScriptファイルを監視してdist/js配下にコピー|

|キーワード|内容|
|---|---|
|--watch(-w)|ファイルの変更を監視|

##### 1.5.2.3. タスクの実行

```
$ npm run watch:js
```
dist/js配下にJavaScriptファイルがコピーされます。
JavaScriptファイルを更新すると、JavaScriptファイルが再度コピーされます。
Ctrlで処理を終了します。

### 1.6. 画像
使用する画像を圧縮して容量を削減します。
[TinyPNG](https://tinypng.com/)などのWebサービスを使うことでも削減可能ですが、追加や変更の度に手間がかかるためnpm scriptsで処理します。

#### 1.6.1. パッケージのインストール

imagemin-cli、imagemin-keep-folder、imagemin-mozjpeg、imagemin-pngquant、imagemin-gifsicle、imagemin-svgoをインストールします。

```
$ npm i imagemin-cli -D
$ npm i imagemin-keep-folder -D
$ npm i imagemin-mozjpeg -D
$ npm i imagemin-pngquant -D
$ npm i imagemin-gifsicle -D
$ npm i imagemin-svgo -D
```

#### 1.6.2. 設定ファイルの準備
プロジェクトルートにimagemin.jsを配置します。

```js:imagemin.js
const keepfolder = require('imagemin-keep-folder');
const mozjpeg = require('imagemin-mozjpeg');
const pngquant = require('imagemin-pngquant');
const gifsicle = require('imagemin-gifsicle');
const svgo = require('imagemin-svgo');

keepfolder(['src/img/**/*.{jpg,png,gif,svg}'], {
  plugins: [
    mozjpeg({
      quality: 85
    }),
    pngquant({
      quality: [.7, .8]
    }),
    gifsicle(),
    svgo()
  ],
  replaceOutputDir: output => {
    return output.replace(/img\//, '../dist/img/')
  }
});
```


#### 1.6.3. package.jsonへの追記

```json:package.json
"scripts": {
  "watch:img": "chokidar \"src/img/**/*\" --command \"node imagemin.js\" --initial"
}
```

|タスク|処理内容|
|---|---|
|watch:img|画像の圧縮(実行時、ファイル変更時)|

#### 1.6.4. タスクの実行

```
$ npm run watch:img
```
dist/imgディレクトリ配下に容量が削減された画像ファイルが生成されます。






### 1.7 distディレクトリの削除
以前の作業で生成したファイルがdistに残っているとトラブルにつながる恐れがあるため、削除します。

#### 1.7.1. パッケージのインストール

rimrafをインストールします。

```
$ npm i rimraf -D
```
rimrafは、ファイルやディレクトリの削除を行います。

#### 1.7.2. package.jsonへの追記

```package.json
"scripts": {
  "delete:dist": "rimraf dist"
}
```

|タスク|処理内容|
|---|---|
|delete:dist|実行時に、distディレクトリを削除|


#### 1.7.3.  タスクの実行
```
$ npm run delete:dist
```

distディレクトリが削除されます。


### 1.8 ファイルのコピー
HTML、CSS、JavaScriptの以外にもdist配下に生成したいファイルがある場合に毎回手動でコピーするのは手間になるので、src配下に配置しておいてコピーします。
今回は、sitemap.xml、robots.txt、humans.txt、manifest.json、favicon.ico、apple-touch-icon.pngをコピーするようにします。

#### 1.8.1 パッケージのインストール
1.5.2でcpxをインストールしていない場合はインストールが必要です。

```
$ npm i cpx -D
```



#### 1.8.2. package.jsonへの追記
1.5.2.2. ではファイルを監視して、変更がある度にファイルコピーを行っていましたが、あまり変更が入らないファイルのコピーを想定しているので、```-w``` オプションは付けません。

```json:package.json
"scripts": {
"copy:sitemapxml": "cpx \"src/sitemap.xml\" dist/",
"copy:robotstxt": "cpx \"src/robots.txt\" dist/",
"copy:humanstxt": "cpx \"src/humans.txt\" dist/",
"copy:manifestjson": "cpx \"src/manifest.json\" dist/",
"copy:faviconico": "cpx \"src/favicon.ico\" dist/",
"copy:apple-touch-iconpng": "cpx \"src/apple-touch-icon.png\" dist/"
}
```

#### 1.8.2. タスクの実行

```
$ npm run copy:sitemapxml
```

srcフォルダ直下にあるsitemap.xmlがdist直下にコピーされます。
実行時にはsrcフォルダ直下にsitemap.xmlを置くのを忘れないようにしてください。

### 1.9. タスクの連携
これまで、個別に作成してきたタスクを、同時に実行できるように組み合わせていきます。
・HTML、CSS、JavaScriptへの変換を同時に行います。
・CSSファイルにはAutoprefixerを適用します。
・Browser-Syncで、変換されたファイルをブラウザのリロードなしに表示します。
・連携タスクの実行前に、distディレクトリの削除を行い、favicon.icoなどコーディング時に変更の少ないファイルのコピーを行います。

#### 1.9.1. package.jsonへの追記

```package.json
"scripts": {
  "prewatch:all": "run-s delete:dist copy:sitemapxml copy:robotstxt copy:humanstxt copy:manifestjson copy:faviconico copy:apple-touch-iconpng",
  "watch:all": "run-p watch:pug2html watch:scss2cssprefix watch:ts watch:img start:server"
}

```
|タスク|処理内容|
|---|---|
|prewatch:all|distディレクトリを削除(実行時)、指定ファイルのコピー|
|watch:all|PugをHTMLに変換、SCSSをCSS(Autoprefix追加)、TypeScriptをJavaScriptに変換もしくはJavaScriptをコピー、画像を圧縮し、Browser-Syncを起動|
EJSファイルを使用している場合はwatch:pug2htmlをwatch:ejs2htmlに変更してください。
Stylusファイルを使用している場合はwatch:scss2cssprefixをwatch:stylus2cssprefixに変更してください。
JavaScriptを直接記述している場合はwatch:tsをwatch:jsに変更してください。

#### 1.9.2. タスクの実行

```
$ npm run watch:all
```

Ctrl+cでタスクを終了します。
※dist/index.htmlが生成されているのに、ブラウザに「Cannot GET /」と表示される場合はリロードしてみてください。



## 2. 整形

### 2.1. SCSSの整形

#### 2.1.1. パッケージのインストール

stylelint、stylelint-scss、stylelint-config-recommended-scss、stylelint-order、prettier、stylelint-config-prettier、stylelint-prettierをインストールします。

```
$ npm i stylelint -D
$ npm i stylelint-scss -D
$ npm i stylelint-config-recommended-scss -D
$ npm i stylelint-order -D
 
$ npm i prettier -D
$ npm i stylelint-config-prettier -D
$ npm i stylelint-prettier -D
```

|パッケージ|内容|
|---|---|
|stylelint|stylelint本体|
|stylelint-scss|stylelintのscss用ルールを使う|
|stylelint-config-recommended-scss|SCSS用のルールセット|
|stylelint-order|プロパティの順番を整える|
|prettier|prettier本体|
|stylelint-config-prettier|Prettierと競合する可能性があるStylelintのルールを無効化|
|stylelint-prettier|StylelintルールとしてPrettierを実行|

#### 2.1.2. 設定ファイルの準備
.stylelintrc.jsonを準備します。

```json:.stylelintrc.json
{
  "extends": "stylelint-config-prettier",
  "plugins": [
    "stylelint-order",
    "stylelint-prettier"
  ],
  "rules": {
    "prettier/prettier": true,
    "indentation": 4,
    "declaration-colon-newline-after": null,
    "value-list-comma-newline-after": "never-multi-line",
    "order/properties-alphabetical-order": true
  }
}
```
設定は下記URLを参考に適宜変更してください。
[.stylelintrc](https://qiita.com/takeshisakuma/items/a7a3b8cc0ce05422f686)



プロジェクトルートに.prettierrc.jsonを準備します。

```json:.prettierrc.json
{
  "semi":  true,
  "trailingComma":  "all",
  "singleQuote":  true,
  "printWidth":  120,
  "tabWidth":  4,
  "useTabs": false,
  "proseWrap": "preserve",
  "endOfLine": "auto"
}
```
設定は下記URLを参考に適宜変更してください。
[.prettierrc](https://qiita.com/takeshisakuma/items/bbb2cd2f1c65de70e363)

.stylelintignoreファイルを作成します。
※特定のディレクトリを排除する場合のみ

```.stylelintignore

(対象外にしたいディレクトリ名)
```

#### 2.1.3. package.jsonへの追記

```json:package.json
"scripts": {
  "lint:scss": "stylelint \"**/*.scss\"",
  "format:scss": "stylelint --fix \"**/*.scss\""
}
```

|タスク|処理内容|
|---|---|
|lint:scss|SCSSファイルの構文をチェック|
|format:scss|SCSSファイルの構文をチェックし、修正する|

|キーワード|内容|
|---|---|
|--fix|コードを修正|

#### 2.1.4. タスクの実行

```
$ npm run format:scss
```


### 2.2 Stylusの整形

#### 2.2.1. パッケージのインストール

stylus-supremacyとstylintをインストールします。

```
$ npm i stylus-supremacy -D
$ npm i stylint -D
```

#### 2.2.2. 設定ファイルの準備
プロジェクトルートに.stylintrc.jsonを作成します。

```json:.stylintrc.json
{
  "blocks": false,
  "brackets": "never",
  "colons": "always",
  "colors": "always",
  "commaSpace": "always",
  "commentSpace": "always",
  "cssLiteral": "never",
  "customProperties": [],
  "depthLimit": false,
  "duplicates": true,
  "efficient": "always",
  "exclude": [],
  "extendPref": false,
  "globalDupe": false,
  "groupOutputByFile": true,
  "indentPref": false,
  "leadingZero": "never",
  "maxErrors": false,
  "maxWarnings": false,
  "mixed": false,
  "mixins": [],
  "namingConvention": false,
  "namingConventionStrict": false,
  "none": "never",
  "noImportant": true,
  "parenSpace": false,
  "placeholders": "always",
  "prefixVarsWithDollar": "always",
  "quotePref": false,
  "reporterOptions": {
    "columns": ["lineData", "severity", "description", "rule"],
    "columnSplitter": " ",
    "showHeaders": false,
    "truncate": true
},
  "semicolons": "never",
  "sortOrder": "alphabetical",
  "stackedProperties": "never",
  "trailingWhitespace": "never",
  "universal": false,
  "valid": true,
  "zeroUnits": "never",
  "zIndexNormalize": false
}
```
設定は適宜変更してください。
https://www.npmjs.com/package/stylint


#### 2.2.3. package.jsonへの追記

```json:package.json
"scripts": {
  "format:stylus": "stylus-supremacy format src/**/*.styl -p .stylintrc.json -r"
}
```

|タスク|処理内容|
|---|---|
|format:stylus|画像の圧縮(実行時、ファイル変更時)|

|キーワード|内容|
|---|---|
|format|Stylusファイルをフォーマット|
|--options(-p)|独自のフォーマットオプションを指定|
|--replace(-r)|Stylusファイルを上書き|


#### 2.2.4. タスクの実行

```
$ npm run format:stylus
```



### 2.3. TypeScript、JavaScriptの整形

#### 2.3.1. パッケージのインストール
eslint、@typescript-eslint/parser、@typescript-eslint/eslint-plugin、prettier、eslint-config-prettier、eslint-plugin-prettierをインストールします。
※prettierは2.1.ですでにインストールしている場合は、インストール不要です。

```
$ npm i eslint -D
$ npm i @typescript-eslint/parser -D
$ npm i @typescript-eslint/eslint-plugin -D

$ npm i prettier -D
$ npm i eslint-config-prettier -D
$ npm i eslint-plugin-prettier -D
```

|パッケージ|内容|
|---|---|
|eslint|eslint本体|
|@typescript-eslint/parser|ESLintがTypeScriptコードをチェックできるようにする|
|@typescript-eslint/eslint-plugin|TypeScriptのESLintルール|
|prettier|prettier本体|
|eslint-config-prettier|prettierと矛盾する可能性があるESLintのルールを無効化|
|eslint-plugin-prettier|ESLintルールとしてPrettierを実行|


#### 2.3.2. 設定ファイルの準備
プロジェクトルートに.prettierrc.jsonを作成します。
2.1.ですでに作成している場合は不要です。

```json:.prettierrc.json
{
  "semi":  true,
  "trailingComma":  "all",
  "singleQuote":  true,
  "printWidth":  120,
  "tabWidth":  4,
  "useTabs": false,
  "proseWrap": "preserve"
}
```
設定は下記URLを参考に適宜変更してください。
https://qiita.com/iewori/items/8a08678b86e69dba233b


.eslintrc.jsonファイルを作成します。

```json:.eslintrc.json
{
  "parser": "@typescript-eslint/parser",
  "extends":[
    "plugin:@typescript-eslint/recommended",
    "prettier/@typescript-eslint",
    "plugin:prettier/recommended"
  ],
  "parserOptions":  {
    "ecmaVersion":  2018,
    "sourceType":  "module"
  }
}
```
設定は下記URLを参考に適宜変更してください。
https://eslint.org/docs/user-guide/configuring


#### 2.3.3 package.jsonへの追記
TypeScriptの場合はlint:tsとformat:ts、JavaScriptの場合はlint:jsとformat:jsを記述してください。

```json:package.json
"scripts": {
  "lint:ts": "eslint src/ts/**/*.ts",
  "format:ts": "eslint src/ts/**/*.ts --fix"

  "lint:js": "eslint src/js/**/*.js",
  "format:js": "eslint src/js/**/*.js --fix"
}
```

|キーワード|内容|
|---|---|
|--fix|コードを修正|

#### 2.3.4. タスクの実行

TypeScriptの場合はnpm run format:ts、JavaScriptの場合はnpm run format:jsを実行してください。

```
$ npm run format:ts

$ npm run format:js
```










### 2.4 altCSS、altJSの一括整形

#### 2.4.1. package,jsonへの追記

```
"scripts": {
  "format:all":"run-p format:scss format:ts"
}
```
|タスク|処理内容|
|---|---|
|format:all|SCSSとJavaScriptの整形|
Stylusを使用する場合は、format:scssをformat:stylusに変更してください。

#### 2.4.2. タスクの実行

```
$ npm run format:all
```







## 3. 本番公開対応
本番公開時に不要なSourceMapファイルの削除、CSSファイルとJavaScriptファイルのminifyを行います。

### 3.1. パッケージのインストール

```
$ npm i uglify-es -D
$ npm i clean-css-cli -D
```
uglify-esはJavaCsriptの圧縮
clean-css-cliはCSSの圧縮

### 3.2 package.jsonへの追記

```json:package.json
"scripts": {
  "min:css":"cleancss -o dist/css/style.css dist/css/style.css",
  "min:js": "uglifyjs dist/js/main.js -o dist/js/main.js",
  "delete:map":"rimraf dist/**/*.map",
  "prepare:all":"run-p min:js min:css delete:map"
}
```

|タスク|処理内容|
|---|---|
|min:js|main.jsを圧縮(実行時のみ)|
|min:css|style.cssを圧縮(実行時のみ)|
|delete:map|SourceMapファイルを削除(実行時のみ)|
|prepare:all|main.jsとstyle.cssを圧縮し、SouceMapファイルを削除(実行時のみ)|

|キーワード|内容|
|---|---|
|uglifyjsの--output(-o)|出力するファイル名を指定|
|cleancssの--output(-o)|出力するファイル名を指定|


## 4. 制作環境の共有
共同作業者とタスクランナーを共通化します。
コードフォーマットやAutoprefixerなど、これからタスクランナーで処理する作業は、エディタ側であらかじめ無効にしておいてください。

### 4.1. package.json、package-lock.jsonの共有
package.json、package-lock.jsonをプロジェクトディレクトリに配置します。

### 4.2. パッケージのインストール
package-lock.jsonの情報をもとにパッケージの一括インストールできます。

```
$ npm ci
```


## 5. パッケージ管理

### パッケージの個別のアップデート

```
$ npm update (アップデートしたいパッケージ名)
```
パッケージのアップデートは仕様が変わる場合があるので、注意が必要です。
メジャーアップデートなど、そのままアップデートできない場合は一度アンインストールして再インストールすると最新版　にできます。

### パッケージのアンインストール

```

$ npm uninstall (削除したいパッケージ名)
```

### 最新になっていないパッケージを一覧表示

```
$ npm outdate
```


### npm自体のアップデート

```
$ npm update npm
```

### パッケージの一括アップデート

```
$ npm update
```
パッケージのアップデートは仕様が変わる場合があるので、注意が必要です。


## 6. まとめ

Web制作時

```
$ npm run watch:all
```

コード整形時

```
$ npm run format:all
```

公開前

```
$ npm run prepare:all
```

dist配下のファイルをそのままアップロードする

リポジトリ
https://github.com/takeshisakuma/npm-scripts_for_webdesign