gulpfile.jsにパッケージを追加する際、ES Modulesで作成されているため追加できないということがたまにあるので、gulpfile.jsをES Modulesでの記述に移行する方法を試してみました。
対応前
まずは移行前のpackage.jsonとgulpfile.jsの内容を確認しておきます。
package.jsonは以下の内容になっています。
{ "name": "", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC", "devDependencies": { "browser-sync": "^2.27.10", "gulp": "^4.0.2", "gulp-plumber": "^1.2.1", "gulp-pug": "^5.0.0", "gulp-sass": "^5.1.0", "sass": "^1.53.0" } }
gulpfile.jsは以下の内容です。
const gulp = require('gulp'); const plumber = require('gulp-plumber'); const pug = require('gulp-pug'); const sass = require('gulp-sass')(require('sass')); const browserSync = require('browser-sync'); const src = { root: 'src/', pug: ['src/pug/**/*.pug', '!src/pug/**/_*.pug'], pugbase: './src/pug', pugwatch: 'src/pug/**/*.pug', sass: ['./src/sass/**/*.scss', '!./src/sass/**/_*.scss'], sasswatch: './src/sass/**/*.scss' }; const dest = { root: './htdocs/', pug: './htdocs/', css: 'htdocs/assets/css/' }; gulp.task('pug', function() { return gulp.src(src.pug) .pipe(plumber()) .pipe(pug({ pretty: true, basedir: src.pugbase })) .pipe(gulp.dest(dest.pug)) .pipe(browserSync.reload({stream:true})); }); gulp.task('sass', function () { return gulp.src(src.sass) .pipe(plumber()) .pipe(sass.sync({ outputStyle : 'expanded' })) .pipe(gulp.dest(dest.css)) .pipe(browserSync.reload({stream:true})); }); gulp.task('server', function() { browserSync({ server: { baseDir: dest.root, }, startPath: '/', }); }); gulp.task('watch', function() { gulp.watch(src.pugwatch, gulp.task('pug')); gulp.watch(src.sasswatch, gulp.task('sass')); }); gulp.task('default', gulp.parallel('watch', 'server'));
srcディレクトリ内で開発用のコードを管理、htdocsディレクトリにコンパイル後のHTMLやCSSを出力する構成になっています。
設定方法
まずはgulpfile.jsをgulpfile.mjsにリネームして、require()をimportに書き換えます。
import gulp from 'gulp'; import plumber from 'gulp-plumber'; import pug from 'gulp-pug'; import dartSass from 'sass'; import gulpSass from 'gulp-sass'; const sass = gulpSass(dartSass); import browserSync from 'browser-sync'; 〜 略 〜
次に、task()を使わない形に変更します。
〜 略 〜 const pug_task = () => { return gulp.src(src.pug) .pipe(plumber()) .pipe(pug({ pretty: true, basedir: src.pugbase })) .pipe(gulp.dest(dest.pug)) .pipe(browserSync.reload({stream:true})); } const sass_task = () => { return gulp.src(src.sass) .pipe(plumber()) .pipe(sass.sync({ outputStyle : 'expanded' })) .pipe(gulp.dest(dest.css)) .pipe(browserSync.reload({stream:true})); } const server_task = () => { browserSync({ server: { baseDir: dest.root, }, startPath: '/', }); } const watch_task = () => { gulp.watch(src.pugwatch, pug_task); gulp.watch(src.sasswatch, sass_task); } export default gulp.parallel(watch_task, server_task); export {pug_task as pug}; export {sass_task as sass}; export {server_task as server}; export {watch_task as watch};
次に、タスク単位で別ファイルに分割します。
taskディレクトリ内に各タスクファイルを設置する想定で、まずはパスなど共通で使用する値を格納する_config.ejsをtaskディレクトリ内に作成します。
export const src = { root: 'src/', pug: ['src/pug/**/*.pug', '!src/pug/**/_*.pug'], pugbase: './src/pug', pugwatch: 'src/pug/**/*.pug', sass: ['./src/sass/**/*.scss', '!./src/sass/**/_*.scss'], sasswatch: './src/sass/**/*.scss' }; export const dest = { root: './htdocs/', pug: './htdocs/', css: 'htdocs/assets/css/' };
taskディレクトリにpug.mjs、sass.mjs、server.mjs、watch.mjsというファイルを作成して、それぞれのタスクを移行します。
pug.mjs
import gulp from 'gulp'; import plumber from 'gulp-plumber'; import pug from 'gulp-pug'; import browserSync from 'browser-sync'; import { src, dest } from "./_config.mjs"; export const pug_task = () => { return gulp.src(src.pug) .pipe(plumber()) .pipe(pug({ pretty: true, basedir: src.pugbase })) .pipe(gulp.dest(dest.pug)) .pipe(browserSync.reload({stream:true})); }
sass.mjs
import gulp from 'gulp'; import plumber from 'gulp-plumber'; import dartSass from 'sass'; import gulpSass from 'gulp-sass'; const sass = gulpSass(dartSass); import browserSync from 'browser-sync'; import { src, dest } from "./_config.mjs"; export const sass_task = () => { return gulp.src(src.sass) .pipe(plumber()) .pipe(sass.sync({ outputStyle : 'expanded' })) .pipe(gulp.dest(dest.css)) .pipe(browserSync.reload({stream:true})); }
server.mjs
import browserSync from 'browser-sync'; import { src, dest } from "./_config.mjs"; export const server_task = () => { browserSync({ server: { baseDir: dest.root, }, startPath: '/', }); }
watch.mjs
import gulp from 'gulp'; import { src, dest } from "./_config.mjs"; import { pug_task } from "./pug.mjs"; import { sass_task } from "./sass.mjs"; export const watch_task = () => { gulp.watch(src.pugwatch, pug_task); gulp.watch(src.sasswatch, sass_task); }
最後に、各ファイルに移行したタスクをgulpfile.ejsにインポートして、タスクを実行できるようにします。
import gulp from 'gulp'; import { pug_task } from "./task/pug.mjs"; import { sass_task } from "./task/sass.mjs"; import { server_task } from "./task/server.mjs"; import { watch_task } from "./task/watch.mjs"; export default gulp.parallel(watch_task, server_task); export {pug_task as pug}; export {sass_task as sass}; export {server_task as server}; export {watch_task as watch};
これでタスクの実行を試して、正しく動作することが確認できました。
うまくいかなかった例
試していてうまくいかなかった例を備忘録として残しておきます。
公式ドキュメントの情報を参考に、esmのパッケージを追加して、gulpfile.jsに前述と同じ変更を行った上でgulpfile.esm.jsとリネームして試したところ、問題なく動作しました。
ただ、その後gulp-imageminを追加してみた際、以下のようなエラーになりました。
TypeError: Invalid host defined options
調べてみるとesmのパッケージの機能サポートが部分的(import/exportのみサポート?)のようで、追加するパッケージによってはエラーが出ることもありそうだったので、今回はgulpfile.jsをgulpfile.mjsにリネームする形で対応しました。
コメントが承認されるまで時間がかかります。