1. zackey2

    Posted

    zackey2
Changes in title
+gulp + babel7 + uglify 導入方法(2019年1月)
Changes in tags
Changes in body
Source | HTML | Preview
@@ -0,0 +1,259 @@
+## はじめに
+
+本記事では、[gulp-uglify](https://www.npmjs.com/package/gulp-uglify)を使ってJavasciptを圧縮する方法について記載します。
+また、それに伴って、ES6(2015)のコードをES5に変換するがありましたので、それについても記載します。
+
+意外とすんなりできなかったので、失敗例とうまく言ったやり方を書いておきます。
+
+## まとめ
+- uglifyはES6を圧縮できない
+- 圧縮には`@babel/core`, `@babel/preset-env`を使う
+- そもそも`uglify`じゃなく`babel-preset-minify`えばよかったかも?
+
+## うまく行ったやり方
+
+yarnを使う前提です。使いたくない人はnpmでインストールしてください。
+
+```:ファイル構成
+- src/sample_es6.js
+- gulpfile.js
+```
+
+`src/sample_es6.js`は今回の変換対象のJSです。
+ES6で使えるconst、let、アロー関数式を含んでいます。
+
+```javascript:src/sample_es6.js
+// ES6
+'use strict';
+
+const MESSAGE = "Hello!";
+
+let greet = () => {
+ console.log(MESSAGE);
+ };
+
+greet();
+```
+
+gulpfile.jsには、babelによる変換および圧縮を行うタスクを記載します。
+`default`タスクなので、gulpを実行するとそのタスクが実行されます。
+
+```javascript:gulpfile.js
+const gulp = require('gulp');
+const uglify = require('gulp-uglify');
+const rename = require('gulp-rename');
+const babel = require('gulp-babel');
+
+gulp.task("default", function () {
+ return gulp.src('src/sample_es6.js')
+ .pipe(babel({
+ "presets": ["@babel/preset-env"]
+ }))
+ .pipe(uglify())
+ .pipe(rename({
+ extname: '.min.js'
+ }))
+ .pipe(gulp.dest('dest/'));
+});
+```
+
+必要なパッケージをインストールします。
+
+```bash
+# yarn add --dev gulp
+# yarn add --dev gulp-uglify gulp-rename
+# yarn add --dev gulp-babel @babel/core @babel/preset-env
+```
+`babel-core`, `babel-preset-env`というパッケージも存在しますが、
+babel7では、`@babel/`から始まるパッケージをインストールする必要があります。
+
+これで、gulpを実行しましょう。
+
+```bash
+# gulp
+```
+
+destディレクトリに、圧縮されたJSファイルができます。
+成功です。
+
+```javascript:dest/sample_es5.min.js
+"use strict";var MESSAGE="Hello!",greet=function(){console.log(MESSAGE)};greet();
+```
+
+ここまでやった状態のファイルをGitHubに載せておきます。
+https://github.com/y-tsuzaki/test-gulp-babel-uglify
+
+
+ところが……
+[babel-preset-minify](https://www.npmjs.com/package/babel-preset-minify)とかいうパッケージを見つけました。
+もしかすると、uglifyではなくbabel関連パッケージを使った方がシンプルだったかもしれません。
+
+そのうち試してみます。
+
+以下、つまずいた点を記載しておきます。
+
+## 失敗1 : ES6(ES2015)が圧縮できない。
+
+**結論:uglifyはES5しか圧縮できません!**
+
+https://qiita.com/ichigo_daifuku3/items/9f559b646d5b2508039d を参考に圧縮を試みました。
+
+```bash
+# yarn add --dev gulp
+# yarn add --dev gulp-uglify gulp-rename
+```
+
+```javascript:gulpfile.js
+const gulp = require('gulp');
+const uglify = require('gulp-uglify');
+const rename = require('gulp-rename');
+
+gulp.task("default", function() {
+ return gulp.src('src/sample_es6.js')
+ .pipe(uglify())
+ .pipe(rename({
+ extname: '.min.js'
+ }))
+ .pipe(gulp.dest('dest/'));
+});
+```
+タスクの実行時に次のようなエラーが出て圧縮できませんでした。
+
+```bash
+[18:49:46] GulpUglifyError: unable to minify JavaScript
+Caused by: SyntaxError: Unexpected token: keyword (const)
+File: /mnt/d/work/_study/gulp-uglify-babel/test01/src/sample_es6.js
+Line: 4
+```
+
+「`const`なんてキーワードしらねーよ!」っていうエラーですね。
+
+残念ながら、uglifyはES5しか対応しておらず、
+ES6(ES2015)のコードは圧縮できずエラーとなってしまうようです。
+なので、uglifyで圧縮する前に、ES6(ES2015)からES5にコンパイルしましょう。
+コンパイルには、**babel(gulp-babel)**が必要です。
+
+じゃあ、それを設定すればいいんだろと思ったんですが、それもまたうまくいきませんでした。
+
+## 失敗2: babelを普通にインストールしても動かない
+
+**結論: インストールするパッケージが違う**
+
+http://cly7796.net/wp/other/try-using-babel-in-gulp/
+https://qiita.com/gigazombie/items/4227cdf25580a6c539f8
+
+このあたりを参考にやってみました
+
+```bash
+# yarn add --dev babel-preset-es2015 gulp-babel babel-core
+```
+```bash
+warning babel-preset-es2015@6.24.1: 🙌 Thanks for using Babel: we recommend using babel-preset-env now: please read babeljs.io/env to update!
+```
+babel-preset-es2015のインストールで「babel-preset-envがおすすめですよ」とやんわり怒られました。
+まあ警告なので、いったん無視します。
+
+
+```javascript:gulpfile.js
+const gulp = require('gulp');
+const uglify = require('gulp-uglify');
+const rename = require('gulp-rename');
+const babel = require('gulp-babel');
+
+gulp.task("default", function() {
+ return gulp.src('src/sample_es6.js')
+ .pipe(babel({
+ "presets":["babel-preset-es2015"]
+ }))
+ .pipe(uglify())
+ .pipe(rename({
+ extname: '.min.js'
+ }))
+ .pipe(gulp.dest('dest/'));
+});
+```
+
+```bash
+# gulp
+internal/modules/cjs/loader.js:583
+ throw err;
+ ^
+
+Error: Cannot find module '@babel/core'
+ at Function.Module._resolveFilename (internal/modules/cjs/loader.js:581:15)
+ at Function.Module._load (internal/modules/cjs/loader.js:507:25)
+ at Module.require (internal/modules/cjs/loader.js:637:17)
+ at require (internal/modules/cjs/helpers.js:20:18)
+ at Object.<anonymous> (/mnt/d/work/_study/gulp-uglify-babel/test02/node_modules/gulp-babel/index.js:7:15)
+ at Module._compile (internal/modules/cjs/loader.js:689:30)
+ at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
+ at Module.load (internal/modules/cjs/loader.js:599:32)
+ at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
+ at Function.Module._load (internal/modules/cjs/loader.js:530:3)
+```
+
+タスクを実行すると`@babel/core`が見つかんねーぞ的なエラーが。
+`babel-core`インストールしたんだけどなんで?と思ったんですが、
+`gulp-babel`は`babel-core`じゃなくて`@babel/core`が必要みたいです。
+(バージョアップでパッケージ名が変わったようです。)
+
+ちなみに、`@babel`の部分は、スコープモジュール(scoped module)というらしいです。
+https://docs.npmjs.com/about-scopes
+
+というわけで、インストールするパッケージを変えてやり直してみましょう。
+
+```bash
+yarn remove babel-core
+yarn add --dev @babel/core
+```
+
+これでもう一度`gulp`を実行します。
+
+```bash
+# gulp
+[19:24:12] Error in plugin "gulp-babel"
+Message:
+ Plugin/Preset files are not allowed to export objects, only functions. In /mnt/d/work/_study/gulp-uglify-babel/test02/node_modules/babel-preset-es2015/lib/index.js
+```
+なんだかよくわかんない感じのエラーが発生しました。
+ググった感じだとbabel-preset-es2015のバージョンがgulp-babelとあってないっぽいようです。
+babel-preset-es2015をインストールした時に、
+`babel-preset-env`がおすすめですよと書いていましたが、それでもだめだったので、
+`@babel/preset-env`を入れてみます。
+
+```bash
+# yarn remove babel-preset-es2015
+# yarn add --dev @babel/preset-env
+```
+
+```javascript:gulpfile.js
+const gulp = require('gulp');
+const uglify = require('gulp-uglify');
+const rename = require('gulp-rename');
+const babel = require('gulp-babel');
+
+gulp.task("default", function () {
+ return gulp.src('src/sample_es6.js')
+ .pipe(babel({
+ "presets": ["@babel/preset-env"]
+ }))
+ .pipe(uglify())
+ .pipe(rename({
+ extname: '.min.js'
+ }))
+ .pipe(gulp.dest('dest/'));
+});
+```
+
+`gulp`を実行しましょう。
+
+```bash
+# gulp
+[19:40:22] Using gulpfile /mnt/d/work/_study/gulp-uglify-babel/test02/gulpfile.js
+[19:40:25] Starting 'default'...
+[19:40:28] Finished 'default' after 2.71 s
+```
+
+ようやくビルドできるようになりました!!
+
+それではまた。