質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
npm

npmは、Node Packaged Modulesの略。Node.jsのライブラリ・パッケージを管理できるツールです。様々なモジュールを簡単にインストールでき、自分でモジュールを作成し公開する際にも使用できます。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

gulp

gulpは、Node.jsをベースとしたタスク自動化ツールの一つ。ストリームでファイルを処理することが特徴です。CSSプリプロセッサの使用時のコンパイルや、CSS・JavaScriptファイルの圧縮・結合などを自動的に行うことができます。

Q&A

解決済

2回答

409閲覧

Gulpで2つのタスクを1タスクにまとめるには?

Bonito_Bonito

総合スコア67

npm

npmは、Node Packaged Modulesの略。Node.jsのライブラリ・パッケージを管理できるツールです。様々なモジュールを簡単にインストールでき、自分でモジュールを作成し公開する際にも使用できます。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

gulp

gulpは、Node.jsをベースとしたタスク自動化ツールの一つ。ストリームでファイルを処理することが特徴です。CSSプリプロセッサの使用時のコンパイルや、CSS・JavaScriptファイルの圧縮・結合などを自動的に行うことができます。

0グッド

0クリップ

投稿2018/05/11 11:15

編集2018/05/13 12:41

Gulpのタスクをグルーピングしたいです。
Gulpでファイルを生成し、生成したファイルの変数をもとにシンボリックリンクを作成する一連のタスクを作るにはどのようにすればよいでしょうか?
下記が詳細になります。
説明がかなり長くなってしまい恐縮ではありますが、目的から順序立てて説明してまいります。

01. 前提

Gulp を使用しています。開発はローカルで行っています。( browser-sync )

02. 目的・実現したいこと

大目標としては、異なる子プロジェクトへのシンボリックリンクの作成です。
まず、 prj_name/ という親プロジェクトがあり、その下層に _master_template という2つの子プロジェクトがあります。
ファイル構成は下記の様な構造になっております。
下記のように _template/ にも Gulp を入れてあり、目的としては _template/ で Gulp を実行する際に _master/ の共通アセット( AB )を参照したいのです。

prj_name/
├── _master/
│  ├── _development/
│  │  ├── _assets/
│  │  │  ├── css/
│  │  │  │  └── style.css ← A
│  │  │  └── js
│  │  │     └── bundle.js ← B
│  │  └── index.html
│  └ gulpfile.js

└── _template/
├── _development/
│  └── index.html
└ gulpfile.js

上記の prj_name/ は、丸ごとリモートリポジトリに置いてあり、複数人が各自でローカルにクローンし、 _template/ を更新したり、複製・リネームして新規プロジェクトを作成するのですが、 _master/ に入っている JS や CSS などの共通アセットを _template/ や、その派生版のプロジェクトで使用することになっています。共通アセットは _template/ へ(単純にコピーするのではなく)シンボリックリンクとして配置したいのです。

各自がクローンするディレクトリの構造や名称も異なるため、例えば私のローカルのシンボリックリンクをコミットしても他の作業者では当然処理されません。そこで、クローンしたらまず最初に各自でシンボリックリンクの生成を作業の前に行ってもらうことになり、また、そのための Gulp のタスクを用意することになりました。

現段階では Gulp の設定の途中であり、 _template/ へのシンボリックリンクの作成のタスクと、シンボリックリンク作成に必要なJSファイルを生成するタスク自体は用意出来ており、その2つのタスクを順番に実行すれば作業者各自の最初の準備が完了する、というところまで出来ているため大きな問題という訳ではないのですが、 Gulp コマンドを2回も叩かせたくないので、この2つのタスクを1つのタスクにまとめたいのです。

ご教示いただきたいのは1つのタスクにまとめる方法です。
以下、回りくどくなるかとは思いますが順を追って説明してまいります。
この方法以外の代替手段で実現できるのであれば、別の手段でも構いませんm(_ _)m

03. 現段階での Gulp の設定およびディレクトリの説明

_template/ でローカル作業をする際に localhost を立ち上げるので、 _master/
にある共通アセットは相対パスなどを駆使しても参照できません。(ホスト配下にないため…)
そのため、 _master/ にある共通アセットのシンボリックリンクを _template/ 内に作成する必要がありました。下記の A'B' のようなイメージです。
(※ _master が完成品であれば、共通アセットをコピーするだけでも良いのですが、 _master はスタイルの追加などの更新がされているため、シンボリックリンクにて同期させる必要があります。今までは毎回コピーして上書きしていましたが、ストレージや作業効率の観点からNGとなりました。)

prj_name/
├── _master/
│  ├── _development/
│  │  ├── _assets/
│  │  │  ├── css/
│  │  │  │  └── style.css ← A
│  │  │  └── js
│  │  │     └── bundle.js ← B
│  │  └── index.html
│  └ gulpfile.js

└── _template/
├── _development/
│  ├── _assets/
│  │  └── _symbolic/
│  │     ├── css/
│  │     │  └── style.css ← A'
│  │     └── js
│  │        └── bundle.js ← B'
│  └── index.html
└ gulpfile.js

03.01. タスク - $ gulp symlink

AB のシンボリックリンクを A'B' に作成する 」・・・
そのためには、シンボリックリンクの元となるファイル( = AB )へのファイルパスを使用して、Gulp によって処理させています。

03.01.01. ./symlink_config.js

シンボリックリンクの元となるファイルのファイルパスを記述した、 './symlink_config.js' ( = C' )を用意し、それを元にシンボリックリンクの作成を行うことにしました。
※なぜ C' なのか(なぜダッシュを付けているのか)は、後に C が出てくるためです。
一時的に分かりづらいですがご容赦下さい。

prj_name/
├── _master/
│  └── _development/
│     └── _assets/
│        ├── css/
│        │  └── style.css ← A
│        └── js
│          └── bundle.js ← B

├── _template/
│  └── _development/
│     └── _assets/
│       └── _symbolic/
│          ├── css/
│          │  └── style.css ← A'
│          └── js
│             └── bundle.js ← B'

├── gulpfile.js
└── symlink_config.js ← C'

./symlink_config.js

js

1 2module.exports = { 3 commonPath : [ 4 '/Users/u_name/prj/prj_name/_master/_development/_assets/**/**.css', 5 '/Users/u_name/prj/prj_name/_master/_development/_assets/**/**.js' 6 ] 7};

03.01.02. $ gulp symlink

./symlink_config.js ( = C' )に記載されている値をもとに vinyl-fs で生成する、symlink というタスクを用意しました。

./gulpfile.js

js

1var gulp = require('gulp'); 2var symlink = require('gulp-sym'); 3var vfs = require('vinyl-fs'); 4var symlink_config = require('./symlink_config'); 5 6gulp.task('symlink', function () { 7 return vfs.src(symlink_config.commonPath, {followSymlinks: false}) 8 .pipe(vfs.symlink('_template/_development/_assets/_symbolic/')); 9});

これにより( $ gulp symlink を実行することで) A'B' は正常に作成されました。

03.02. タスク - $ gulp symlink_config_create

しかし、 ./symlink_config.js ( = C' ) 内に記述している commonPath (クローンしたプロジェクトのあるローカルのファイルパスを入れている変数)は、作業者ごとにフォルダ構造やユーザー名が変わるため、作業する前に作業者ごとに ./symlink_config.js ( = C' ) を作成する必要があります。

03.02.01. ./.origin_files/symlink_config.js

これ(作業する前に作業者ごとに C を作成する作業)を手作業で行うのは手間なので、別のディレクトリに C' の元ファイルとなる
./.origin_files/symlink_config.js ( = C )を用意し、それをもとに C' を作成することにしました。

prj_name/
├── _master/
│  └── _development/
│     └── _assets/
│        ├── css/
│        │  └── style.css ← A
│        └── js
│          └── bundle.js ← B

├── _template/
│  └── _development/
│     └── _assets/
│       └── _symbolic/
│          ├── css/
│          │  └── style.css ← A'
│          └── js
│             └── bundle.js ← B'

├── .origin_files/
│  └── symlink_config.js ← C

├── gulpfile.js
└── symlink_config.js ← C'

./.origin_files/symlink_config.js

js

1 2module.exports = { 3 commonPath : [ 4 'FILEPATH/_master/_development/_assets/**/**.css', 5 'FILEPATH/_master/_development/_assets/**/**.js' 6 ] 7}; 8

文字列 FILEPATH の部分は仮のファイルパスであり、タスクの実行の際に正規のファイルパスで書き換えを行うという考えです。

03.02.02. $ gulp symlink_config_create

次に、このファイル( = C )を ./.origin_files/ から ./ へ dest し、その際に仮のファイルパスである文字列 FILEPATH が正規のファイルパスへ置換されるタスクとして、 symlink_config_create を用意しました。

./gulpfile.js

js

1gulp.task('symlink_config_create', function() { 2 return gulp 3 .src(['./.origin_files/symlink_config.js']) 4 .pipe(replace('FILEPATH', path.resolve())) 5 .pipe(gulp.dest('./')); 6});

これにより C' は正常に作成されました。

ここまでは正常に動作ています

  • $ gulp symlink_config_create
  • $ gulp symlink

いずれも、正常に動作します。
問題はここからとなります。

04. 問題

問題というほどの問題ではないのですが、この2つのタスクは作業者が最初にクローンして npm install してからまずたたいてもらうものなので、手間がかかると感じています。
なので、この2つのタスクを1つにまとめたタスクを用意したいのです。

04.01. この様にしたい

通常はタスクをグルーピングする場合、例えば、

./gulpfile.js

js

1// CSSを納品用フォルダへ持っていく 2gulp.task('css-dest', function () { 3 return gulp.src('./css/*.css') 4 .pipe(gulp.dest('./district/css')); 5}); 6 7// JSを圧縮して納品用フォルダへ持っていく 8gulp.task('js-dest', function () { 9 return gulp.src(paths.js + '/**/*.js') 10 .pipe(uglify()) 11 .pipe(gulp.dest('./district/js')); 12});

などのタスクがあるとした場合、

./gulpfile.js

js

1// いっぺんに納品用ファイルを生成する 2gulp.task('dest', function () { 3 gulp.run('css-dest'); 4 gulp.run('js-dest'); 5});

の様にして1つのタスクにできますよね?
これと同様に、前回用意してある2つのタスクをグルーピングした 'pj_init_1' というタスクを下記の様に用意しましたが…

04.02. 試したこと

下記の通り、 Gulp にて3つほど試しています。

04.02.01 試したこと その1 単純に

./gulpfile.js

js

1gulp.task('pj_init_1', function () { 2 gulp.run('symlink_config_create'); 3 gulp.run('symlink'); 4});

symlink_config_create までは正常に動作しています。
エラーの内容は下記のようなものです。

machine_name:prj_name u_name$ gulp pj_init_1 [18:09:42] Using gulpfile ~/prj/prj_name/gulpfile.js [18:09:42] Starting 'pj_init_1'... gulp.run() has been deprecated. Use task dependencies or gulp.watch task triggering instead. [18:09:42] Starting 'symlink_config_create'... [18:09:42] Starting 'symlink'... [18:09:42] 'symlink' errored after 430 μs [18:09:42] Error: Invalid glob argument: undefined at Object.src (/Users/u_name/prj/prj_name/node_modules/vinyl-fs/lib/src/index.js:20:11) at Gulp.<anonymous> (/Users/u_name/prj/prj_name/gulpfile.js:164:13) at module.exports (/Users/u_name/prj/prj_name/node_modules/orchestrator/lib/runTask.js:34:7) at Gulp.Orchestrator._runTask (/Users/u_name/prj/prj_name/node_modules/orchestrator/index.js:273:3) at Gulp.Orchestrator._runStep (/Users/u_name/prj/prj_name/node_modules/orchestrator/index.js:214:10) at Gulp.Orchestrator.start (/Users/u_name/prj/prj_name/node_modules/orchestrator/index.js:134:8) at Gulp.run (/Users/u_name/prj/prj_name/node_modules/gulp/index.js:22:14) at Gulp.run (/Users/u_name/prj/prj_name/node_modules/deprecated/index.js:9:17) at Gulp.<anonymous> (/Users/u_name/prj/prj_name/gulpfile.js:185:7) at module.exports (/Users/u_name/prj/prj_name/node_modules/orchestrator/lib/runTask.js:34:7) [18:09:42] Finished 'pj_init_1' after 8.08 ms [18:09:42] Finished 'symlink_config_create' after 18 ms machine_name:prj_name u_name$

これは勝手な予想になりますが、 Gulp のタスクが並列に処理されているため、 symlink が動作するために必要な symlink_config.js の作成が間に合っていないためなのでしょうか。

04.02.02 試したこと その2 タスクの直列処理

Gulp のタスクが並列に処理されている事が原因であると考え、単純に直列で動作するように下記の pj_init_2 というタスクを用意しました。

./gulpfile.js

js

1var runSequence = require('run-sequence'); 2gulp.task('pj_init_2', function () { 3 return runSequence( 4 'symlink_config_create', 5 'symlink' 6 ); 7});

しかし、これも結果は pj_init_1 の時と同様に、 symlink_config_create までしか処理されません。

04.02.03 試したこと その3 タスクの依存関係を考慮

他にも symlinksymlink_config_create に依存しているのではないかという理由で、第2引数に'symlink_config_create'を入れてみました。

./gulpfile.js

js

1gulp.task('pj_init_3', ['symlink_config_create'], function() { 2 gulp.run('symlink'); 3});

しかしながら、こちらもまた pj_init_1pj_init_2 と同様に、 symlink_config_create までしか処理されませんでした。

正常に処理させるためにはどうしたら良いでしょうか?
また、見落としやご指摘、アドバイスなどがあればご教示頂きたいです。
よろしくお願いいたしますm(_ _)m

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

自己解決

自己解決

半ば強引ではありますが、下記のコードで希望していた動作が可能になりました。
※ 前述の pj_init 及び 'symlink_config_create' のタスクについては割愛しております。

./gulpfile.js

js

1var child_process = require('child_process').exec; 2gulp.task('pj_init', ['symlink_config_create'], function () { 3 var cmd = "gulp symlink"; 4 child_process(cmd); 5});

Node.js の child_process を使用しています。

参考 : これ便利!gulpfile.js でLinuxコマンドを記述して実行できるプラグ...

上記のコードでは symlink_config_create を実行する際に、用意してある symlink というタスクを Linux コマンドで実行させるものになります。
本来やりたかったタスクのグルーピングという手段とは若干ニュアンスが異なりますので、もしこれ以外に良い方法をご存知の方は以降もぜひご教示いただければと思います。

なお、本投稿課題 04.02.01 及び 04.02.03 に記載の gulp.run は現在非推奨となっている様です。
処理はされますが、下記の様な警告が吐き出されます。

gulp.run() has been deprecated. Use task dependencies or gulp.watch task triggering instead.

そのため、 gulp.run ではなく gulp.task にタスク同士の依存関係を定義する方法があるので、そちらに書き換える必要がある様です。

参考 : gulpその0002 gulp.runが3.5からdeprecated(非推奨)...

gulp.run の代替手段として、 gulp.task の第二引数に依存関係にあるタスクを配列で記述します。
つまり、 04.02.01 及び 04.02.03 は同じ処理となります。
04.02.03 については知識が追いついておらず、新旧手段の入り交じったタスクを作成してしまっておりました。

もし、単純に並列処理をグルーピングしたタスクを作成するのであれば、現時点で推奨されている記述方法では下記のような記述になるでしょう。

js

1gulp.task('pj_init_1', ['symlink_config_create', 'symlink']);

投稿2018/05/13 12:34

Bonito_Bonito

総合スコア67

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

05. Gulp の該当の記述部分全体('18.05.11 20:46 追記)

Gulp の設定の記述がバラバラで見通しが悪いかと思いましたので、念の為 Gulp の該当の記述部分すべてを掲載しておきます。(なお、本文への追記が文字数の不足により出来なかったためこちらに掲載しております、ご了承ください。)

/.gulpfile.js

js

1var gulp = require('gulp'); 2var symlink = require('gulp-sym'); 3var vfs = require('vinyl-fs'); 4var symlink_config = require('./symlink_config'); 5var runSequence = require('run-sequence'); 6 7/** 8 * オリジンからシンボリック元のファイルパスを置換して生成 9 */ 10gulp.task('symlink_config_create', function() { 11 return gulp 12 .src(['./.origin_files/symlink_config.js']) 13 // .pipe(replace('FILEPATH', process.cwd())) 14 .pipe(replace('FILEPATH', path.resolve())) 15 .pipe(gulp.dest('./')); 16}); 17 18/** 19 * シンボリックリンクを生成させるためのタスク 20 */ 21gulp.task('symlink', function () { 22 return vfs.src(symlink_config.commonPath, {followSymlinks: false}) 23 .pipe(vfs.symlink('_template/_development/_assets/_symbolic/')); 24}); 25 26/** 27 * 一つのタスク化 28 * その1 単純にグルーピング 29 * 結果 30 * 'symlink_config_create'まではうまくいくが'symlink'でエラーに。 31 */ 32gulp.task('pj_init_1', function () { 33 gulp.run('symlink_config_create'); 34 gulp.run('symlink'); 35}); 36 37/** 38 * 一つのタスク化 39 * その2 直列処理 40 * 結果 41 * 'runSequence'によって直列処理にしてみたが、結果は同じ 42 */ 43gulp.task('pj_init_2', function () { 44 return runSequence( 45 'symlink_config_create', 46 'symlink' 47 ); 48}); 49 50/** 51 * 一つのタスク化 52 * その3 依存関係を考慮 53 * 結果 54 * 第2引数に'symlink_config_create'を入れてみたものの、、結果は同じ 55 */ 56gulp.task('pj_init_3', ['symlink_config_create'], function() { 57 gulp.run('symlink'); 58});

投稿2018/05/11 11:46

編集2018/05/11 11:49
Bonito_Bonito

総合スコア67

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問