Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

はじめに

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

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

それではまた。

zackey2
スタートアップ企業でLaravel,Vue.jsをやったりAWSいじったり社内のWiFiいじったりしてます。
https://twitter.com/ytzk_
macloud
M&Aクラウドは「テクノロジーの力で、M&Aに流通革命を」をミッションにM&Aプラットフォーム「M&Aクラウド」を開発運営するスタートアップです。
https://macloud.jp
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした