LoginSignup
9

More than 5 years have passed since last update.

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

Last updated at Posted at 2019-01-12

はじめに

本記事では、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

ようやくビルドできるようになりました!!

それではまた。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9