gulp, webpack, Babelを使った環境構築(on WordPress)

# Node.jsを構築する
Node.jsのプロジェクトを構築します. 

# 前提
Linux環境またはWindows10のWSL


## Node.jsインストール
Node.jsがインストールされていない場合はまずインストールする.
LTSのバージョンがおすすめです.
[Node.jsのサイト](https://nodejs.org/ja/)に行ってダウンロードしてもいいし,
下記のようにパッケージ管理ツールからインストールしてもいいです.
Windows環境でPowerShellで使ったりする場合はインストーラーでインストールするのがいいと思います.

WSLの場合は

```bash:
$curl -sL https://rpm.nodesource.com/setup_14.x | bash -
$apt install -y nodejs
```

または

```bash:
wget https://nodejs.org/dist/v14.15.4/node-v14.15.4-linux-x64.tar.xz
tar -xvf node-v14.15.4-linux-x64.tar.xz
cp node-v14.15.4-linux-x64/bin/node /bin/node
rm -rf node-v14.15.4-linux-x64
rm -rf node-v14.15.4-linux-x64.tar.xz
```

等で直接配置してもいいです.


## npmインストール
Node.js製のパッケージ管理ツール(これがないと始まらない).
Node.jsが入った状態で

```bash:
$ node install npm
```

Docker等で仮想化していない場合はバージョンを色々変えたいときがあろうかと思うので, 
バージョン管理ツールをインストールしておきましょう. 主に下記のようなものがあります.
- nvm : https://github.com/nvm-sh/nvm

```bash:
$npm install nvm
```

- n : https://www.npmjs.com/package/n

```bash:
$npm install n
```

- nvm-windows : https://github.com/coreybutler/nvm-windows

- nodebrew : https://github.com/hokaccha/nodebrew
等, 多数あります. それぞれ一長一短あると思うので環境に合わせて好きなものを使いましょう.

## npm installとpackage.json
package.jsonがあるディレクトリで

```bash:
#babel
$npm install
```

と打てば依存関係の全てのパッケージが自動でインストールされます.

ない場合は下記の通り.


## ローカルのNode.js環境の初期構築
とりあえず, sass compile, babelのコンパイルなどを使うなら以下の通り

### gulp
Node製のタスクランナー, 設定ファイルがjsで書かれている.

```bash:
$ cd /path/to/project/root
$npm install -D gulp
#その他必要なパッケージは適宜インストールする
```

プロジェクトルートディレクトリにgulpfile.js (babelを使う場合はgulpfile.babel.js)を作成し, 以下のように記述していく.

```javascript:
const themeName = 'seiaikai-southerncross.com';
//
var gulp = require('gulp');
var plumber = require('gulp-plumber');
var rename = require('gulp-rename');
var sass = require('gulp-sass');
var csslint = require('gulp-csslint');
var autoPrefixer = require('gulp-autoprefixer');
//if node version is lower than v.0.1.2
require('es6-promise').polyfill();
var cssComb = require('gulp-csscomb');
var cmq = require('gulp-merge-media-queries');
var cleanCss = require('gulp-clean-css');
var uglify = require('gulp-uglify');
var concat = require('gulp-concat');
var merge = require('merge-stream');

//webpack
var webpack = require('webpack');
var webpackStream = require('webpack-stream');
var webpackConfig = require('./webpack.config.js');


const paths = {
  css:{
    main:`./httpdocs/cms/wp-content/themes/${themeName}/css/main.css`,
    pages:`./httpdocs/cms/wp-content/themes/${themeName}/css/pages`
  },
  scss: {
    main:`./httpdocs/cms/wp-content/themes/${themeName}/css/main.scss`,
    pages:`./httpdocs/cms/wp-content/themes/${themeName}/css/pages/*.scss`,
  },
  js:{
    rootDir:`./httpdocs/cms/wp-content/themes/${themeName}/js`,
    index:`./httpdocs/cms/wp-content/themes/${themeName}/js/index.js`,
  }
}
gulp.task('sass',function(done){
    // main.scss
    var main = gulp.src([paths.scss.main])
        .pipe(plumber({
            handleError: function (err) {
                console.log(err);
                this.emit('end');
            }
        }))
        .pipe(sass())
        .pipe(autoPrefixer())
        .pipe(cmq({log:true}))
        .pipe(gulp.dest(paths.css))
  //pages sass compile
    var pages = gulp.src([paths.scss.pages])
        .pipe(plumber({
            handleError: function (err) {
                console.log(err);
                this.emit('end');
            }
        }))
        .pipe(sass())
        .pipe(autoPrefixer())
        .pipe(cmq({log:true}))
        .pipe(gulp.dest(paths.css.pages))
    return merge(main, pages);
});

gulp.task("webpack", function(done){
  webpackStream(webpackConfig, webpack)
    .pipe(gulp.dest( paths.js.rootDir ));
  done();
});

gulp.task('sass:watch',function(){
    gulp.watch(`httpdocs/cms/wp-content/themes/${themeName}/css/*.scss`, gulp.task('sass'));
    gulp.watch(`httpdocs/cms/wp-content/themes/${themeName}/css/*/*.scss`, gulp.task('sass'));
    gulp.watch(`httpdocs/cms/wp-content/themes/${themeName}/js/*/*.js`, gulp.task('babel'));
    gulp.watch(`httpdocs/cms/wp-content/themes/${themeName}/js/*.js`, gulp.task('babel'));
    done();
});
```


この状態でプロジェクトルート(gulpfileがあるディレクトリ)で



```bash:
$npx gulp タスクの名前(i.e. sass or babel)
```


などと打つと実行されます 


### webpack
```bash:
#webpack
$npm install -D webpack webpack-stream terser-webpack-plugin \
webpack-cli @webpack-cli/init
#その他必要なパッケージは適宜インストールする
```

ここでは数々のjsファイルをindex.jsにexportで集めて, index.bundle.js に書き出すこととします.
ディレクトリ構造は

js/modules/
js/pages/
js/index.js
js/index.babel.js
などとしておきます.


```javascript:
const themeName = 'seiaikai-southerncross.com';
const path = require('path');
const url = require('url');
const webpack = require('webpack');
const TerserPlugin = require('terser-webpack-plugin');
const paths = {
  url:"",
  js:{
    rootDir:`httpdocs/cms/wp-content/themes/${themeName}/js`,
    index:`httpdocs/cms/wp-content/themes/${themeName}/js/index.js`,
    bundle:`httpdocs/cms/wp-content/themes/${themeName}/js/index.bundle.js`
  },
}
//master branch の場合は mode: "production" としてpushしてデプロイする.
module.exports = {
  mode: 'development',
  entry: {
    index: path.resolve(__dirname, paths.js.index)
    //相対パスの場合
    //index: path.join(__dirname, 'httpdocs', 'cms', 'wp-content', 'themes', `${themeName}`, 'js','index.js')
  },
  output: {
    filename: path.join('[name].bundle.js'),
    path: path.join(__dirname, paths.js.rootDir)
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        use: [
          {
            loader: 'babel-loader',
            options: {
              presets: [
                ['@babel/preset-env', {
                  'modules': false
                }]
              ]
            }
          }
        ]
      }
    ]
  },
  devtool: 'source-map',

  optimization: {
    minimizer: [ // js圧縮
    new TerserPlugin({
        extractComments: 'all', // コメント削除
        terserOptions: {
            compress: {
              drop_console: false, // console.log削除 boolean
            },
        },
    }),
  ],
}
};
```

### babel 

```bash:
#babel
$npm install -D webpack babel-loader @babel/core @babel/preset-env babel-preset-env
#その他必要なパッケージは適宜インストール
```



# 参考
## 一次ソース
https://gulpjs.com/
https://webpack.js.org/
https://babeljs.io/

## 日本語の参考記事
https://webpack.js.org/loaders/babel-loader/
https://qiita.com/KoichiSugimoto/items/d8a5563f197682dea0f4
https://qiita.com/bakira/items/3c4e2d10aae085767817
https://qiita.com/am10/items/2516fa04def815195ffe
https://qiita.com/tmiki/items/86abc565d06ced78d968