Gulp + Webpack+BabelでシンプルJQuery構成


目的

Gulp + WebpackでJQueryを書けるようにします。
ちょうどいいのでBabel(ES6)も使ってしまいます。
CSS/SCSSもまとめられるけど、ややこしいのでJSのみをwebpackに任せる方針で。

手順まとめ

  1. JQueryをローカルダウンロード
  2. JQueryに依存したライブラリの使用
  3. JQueryの実際の呼び出し
  4. JQueryライブラリの実際の呼び出し

WebpackはJSをまとめるツールなので、JQueryをローカルにもつ必要があります。
$で始まる関数をもつJQueryライブラリは、Webpack的には例外なのでJQueryを使っていることを教えてあげます。

具体的な手順へ

  1. JQueryをローカルダウンロード
    npm install --save-dev / npm i -D (npmでプロジェクトディレクトリにインストール)

  2. JQueryに依存したライブラリの使用
    → webpack.ProvidePluginをつかう(グローバル変数$を定義)

  3. JQueryの実際の呼び出し
    → webpack.ProvidePluginの設定でインポートしておけば不要、$で呼び出せる

  4. JQueryライブラリの実際の呼び出し(ライブラリのCSSは別で読み込む)
    npm install --save-dev と import で読み込み(かっこ良さげ)
    → もしくは、プラグインごとに webpack aliasを使って コンパイル時にインポート(読み込み順を指定できる)

webpackが元締めになってコンパイルしてくる環境では、
その他の便利ライブラリ(JQuery)を使用したときに干渉が起こるようです。
旧ツールと共存しつつ、新しい実りも享受していきたいです。

Vue.jsでJQueryの始め方

main.js
// ProvidePluginで$に入れているので
// import $ from 'jquery'; の指定は不要
import 'jquery.cookie';

$(function(){
  // $にjquery.cookie.jsの処理が入っているか試す
  $.cookie("name", "myname", { expires: 7 });
});

Gulp設定ファイル

<webpackのプラグイン>
webpack.optimize.DedupePlugin() : ライブラリ間で依存しているモジュールが重複している場合、二重に読み込まないようにする
webpack.optimize.AggressiveMergingPlugin() : ファイルを細かく分析し、まとめられるところはできるだけまとめてコードを圧縮する

注) example はテーマ(テーマディレクトリ)名とします。
注) paths は各々読み替えて!

gulpfile.js
const gulp = require('gulp'),
    plumber = require("gulp-plumber"),
    sass = require('gulp-sass'),
    cleancss = require('gulp-clean-css'),
    autoprefixer = require('gulp-autoprefixer'),
    notify = require('gulp-notify'),
    webpack = require('webpack'), // Let's use webpack.DefinePlugin
    webpackStream = require('webpack-stream'); // Let's use webpack3

const paths = {
    "url":"localhost:8802",
    "css": "./public/wp/wp-content/themes/example/assets/css/",
    "scss": "./public/wp/wp-content/themes/example/assets/scss/**/*.scss",
    "entry": "./public/wp/wp-content/themes/example/assets/js/src/main.js",
    "js": "./public/wp/wp-content/themes/example/assets/js/",
}

//Sass
gulp.task('sass',function(){
    return gulp.src(paths.scss)
    .pipe(plumber())
    .pipe(sass({outputStyle: 'expanded'}))
    .pipe(cleancss({debug: true}, function(details) {
            console.log(details.name + ': ' + details.stats.originalSize + ' > ' +  + details.stats.minifiedSize);
    }))
    .pipe(autoprefixer({
        browsers: ["last 2 versions", "ie >= 9", "Android >= 4","ios_saf >= 8"],
        cascade: false
    }))
    .pipe(gulp.dest(paths.css))
    .pipe(notify("Sass Compile Success!"));
});

//Webpack JS bundle
gulp.task('bundle', function(){
    return gulp.src( [ paths.entry ] )
        .pipe(plumber())
        .pipe(webpackStream({
            // watch: true, // webpack の watch ではなく gulp の watch を使う
            output: {
                filename: 'build/bundle.js',
            },
            module: {
                rules: [
                    {
                        test: /\.js$/,
                        resourceQuery: paths.js + 'src/',
                        loader: 'babel-loader',
                        options: {
                            presets: [ 'env' ],
                        }
                    }
                ],
            },
            resolve: {
                extensions: ['.js'],
                modules: [
                    "node_modules"
                ],
                alias: {
                }
            },
            //環境によってビルドする内容を分ける
            plugins: [
                new webpack.DefinePlugin({
                    'process.env': {
                        NODE_ENV: '"production"'
                    }
                }),
                new webpack.optimize.UglifyJsPlugin(),
                new webpack.optimize.DedupePlugin(),  // ライブラリ間で依存しているモジュールが重複している場合、二重に読み込まないようにする
                new webpack.optimize.AggressiveMergingPlugin(),  //ファイルを細かく分析し、まとめられるところはできるだけまとめてコードを圧縮する
                // JQuery / JQueryライブラリのための定義
                new webpack.ProvidePlugin({
                    jQuery: "jquery",
                    $: "jquery",
                    jquery: "jquery"
                })
            ]
        }, null, function(err, stats) {
            /* Use stats to do more things if needed */
            if (stats.compilation.errors.length) {
                notify.onError({
                    title: 'Webpack error',
                    message: stats.compilation.errors[0].error,
                    sound: 'Frog',
                });
            }
        }))
        .pipe(gulp.dest( paths.js ))
        .pipe(notify("Bundle JS Success!"));
})

gulp.task('default', ['sass','bundle'], function () {
    gulp.watch(paths.scss, ['sass']);
    gulp.watch( [paths.entry], ['bundle']);
});

おまけ

旧体制(Gulp + JS周りのライブラリ[uglifyなど])

最近書いた記事

Dockerで作るWordPressテーマローカル開発環境
Gulp + Webpack + Babel + Vue.js で作るWordPressテーマ開発環境
Gulp + yarn シンプルJQuery構成

参考

Webpack JQuery Plugin(公式)
webpackでjQueryを読み込む2つの方法
webpackでjQueryに依存したライブラリを含めてビルドする
webpackでjQueryの多重ロードを回避する方法