gulp + babel7 + uglify 導入方法(2019年1月)

gulp + babel7 + uglify 導入方法(2019年1月):


はじめに

本記事では、gulp-uglifyを使ってJavasciptを圧縮する方法について記載します。

また、それに伴って、ES6(2015)のコードをES5に変換するがありましたので、それについても記載します。

意外とすんなりできなかったので、失敗例とうまく言ったやり方を書いておきます。


まとめ

  • uglifyはES6を圧縮できないからbabelを使う
  • 圧縮には@babel/core, @babel/preset-envを使う
  • そもそもuglifyじゃなくbabel-preset-minifyを使えばよかったかも?


うまく行ったやり方

ファイル構成
- src/sample_es6.js 
- gulpfile.js 
src/sample_es6.jsは今回の変換対象のJSです。

ES6で使えるconst、let、アロー関数式を含んでいます。

src/sample_es6.js
// ES6 
'use strict'; 
 
const MESSAGE = "Hello!"; 
 
let greet = () => { 
    console.log(MESSAGE); 
  }; 
 
greet(); 
gulpfile.jsには、babelによる変換および圧縮を行うタスクを記載します。
defaultタスクなので、gulpを実行するとそのタスクが実行されます。

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/')); 
}); 
必要なパッケージをインストールします。

# 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を実行しましょう。

# gulp 
destディレクトリに、圧縮されたJSファイルができます。

成功です。

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とかいうパッケージを見つけました。

もしかすると、uglifyではなくbabel関連パッケージを使った方がシンプルだったかもしれません。

そのうち試してみます。

以下、つまずいた点を記載しておきます。


失敗1 : ES6(ES2015)が圧縮できない。

結論:uglifyはES5しか圧縮できません!

https://qiita.com/ichigo_daifuku3/items/9f559b646d5b2508039d を参考に圧縮を試みました。

# yarn add --dev gulp 
# yarn add --dev gulp-uglify gulp-rename 
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/')); 
}); 
タスクの実行時に次のようなエラーが出て圧縮できませんでした。

[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

このあたりを参考にやってみました

# yarn add --dev babel-preset-es2015 gulp-babel babel-core 
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がおすすめですよ」とやんわり怒られました。

まあ警告なので、いったん無視します。

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/')); 
}); 
# 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-babelbabel-coreじゃなくて@babel/coreが必要みたいです。

(バージョアップでパッケージ名が変わったようです。)

ちなみに、@babelの部分は、スコープモジュール(scoped module)というらしいです。
https://docs.npmjs.com/about-scopes

というわけで、インストールするパッケージを変えてやり直してみましょう。

yarn remove babel-core 
yarn add --dev @babel/core 
これでもう一度gulpを実行します。

# 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を入れてみます。

# yarn remove babel-preset-es2015 
# yarn add --dev @babel/preset-env 
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を実行しましょう。

# 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 
ようやくビルドできるようになりました!!

それではまた。

コメント

このブログの人気の投稿

投稿時間:2021-06-17 05:05:34 RSSフィード2021-06-17 05:00 分まとめ(1274件)

投稿時間:2021-06-20 02:06:12 RSSフィード2021-06-20 02:00 分まとめ(3871件)

投稿時間:2020-12-01 09:41:49 RSSフィード2020-12-01 09:00 分まとめ(69件)