1. ホーム
  2. json

Gulpがデモ用ライティングウィジェットを作成

2022-03-17 12:09:29

Gulpを勉強し直したので、Gulpで書いたものをもう一度書き直します。今回は、要点を書いておかないと、後で忘れたときに思い出せません。

Gulpは以前ほど使われていないので、複雑なアプリは書かないことにしています。今回は、PSDをHTMLに変換する際に、少しでも繰り返しを減らすためだけの簡単なデモ処理ツールを書きました。

デモを書くときは、ページ構成とそれに対応するスタイルしか気にしないので、js関連のコンテンツは考えません。主な機能は次のとおりです。

  • Gulpの設定ファイルにES6構文でコードを記述する
  • 各htmlファイルのヘッダーにflexible.jsとreset.cssを挿入する。
  • SASSを使ったスタイルの書き方
  • ブラウザのプレフィックスを自動的に追加し、スタイルの互換性を処理する
  • pxからremへの自動変換
  • スタイルファイルの圧縮
  • 画像の圧縮
  • .htmlファイルからコメントを削除する
  • ブラウザのライブリフレッシュ
  • ページからの無駄なスタイルの削除
  • 各パッケージの前に、既存のターゲットディレクトリを削除する

このような小さな目標に対して、これらの特徴点を段階的に実装していく方法を紹介します。

使用したGulpのバージョンは 3.9.1 .

仕事の準備

package.jsonを作成します。

$ npm init -y

Gulp をプロジェクトの開発依存事項としてインストールします。

$ yarn add gulp -D

プロジェクトを開始する前に、まず、ディレクトリ構造を構築する必要があります。

.
├── gulpfile.babel.js gulp's configuration file
├── package.json
├── src Demo directory for source code
│ ├── common The directory where public files are stored for future injection into html files
│ │ ├── flexible.min.js
│ │ └── reset.css
│ ├── css
│ │ ├── _none.scss
│ │ └── useful.scss
│ ├── html
│ │ └── index.html
│ └── imgs
│ └── test.png
├─ task Task folder
│ ├── task-clean.js Delete the dist directory
│ ├── task-css.js Handle css tasks
│ ├── task-default.js default task
│ ├── task-html.js Handle html tasks
│ └── task-img.js Handle image tasks
└── yarn.lock

gulpfile.jsのES6サポート

gulpfile.jsでES6関連の構文を使用する必要がある場合、gulpfile.jsをgulpfile.babel.jsに変更する必要があります。ファイル名を変更したら、そのファイルにES6コードを記述します。

import gulp from 'gulp';

gulp.task('default', () => console.log(123));

コマンドを実行した結果、エラーが報告されていることがわかりました。

$ . /node_modules/.bin/gulp

[14:15:34] Failed to load external module @babel/register
[14:15:34] Failed to load external module babel-register
[14:15:34] Failed to load external module babel-core/register
[14:15:34] Failed to load external module babel/register

ES6構文を使用する場合、タスクを正しく実行する前にbabelでトランスコードする必要があるため、babel関連の内容を設定することでこのエラーが発生します。

まず最初に必要なのは、babelの依存関係をインストールすることです。

$ yarn add babel-cli babel-preset-env -D

babelが実行されるとき、設定ファイルの情報を読み込んで、対応するコードを翻訳する必要があります。そのため .babelrc ファイルは必要不可欠です。

{
  "presets": ["env"]
}

もう一度Gulpコマンドを実行すると、やはりエラーが見つかります。

$ . /node_modules/.bin/gulp

[14:20:33] Failed to load external module @babel/register

これは奇妙なエラーです。babelの依存関係がすでにインストールされているのに、なぜエラーになるのでしょうか?これは .babel.js babel-core/registerは非推奨で、現在は代わりにbabel-registerが使用されています。この問題を解決するために index.js を node_modules に追加してください。

module: '@babel/register' から module: 'babel-register' . 正確な変更箇所は、以下のコードの3行目です。

  '.babel.js': [
    {
      module: '@babel/register',

gulpfile.babel.jsでは、この設定ファイルにtaskディレクトリのファイルを読み込んでいますが、この時に使うべきモジュールは require-dir .

をインストールします。 require-dir モジュールです。

$ yarn add require-dir -D

モジュールが終了したら、gulpfile.babel.jsをtransformします。

import requireDir from 'require-dir';

requireDir('. /task');

対象ディレクトリの削除

通常、最終的に生成されたファイルはdistディレクトリに置かれるため、ターゲットディレクトリはdistとなります。

フォルダやファイルの削除は、通常 del モジュールは、Promise オブジェクトを返す非同期メソッドです。

// . /task/task-clean.js

gulp.task('clean', () => {
  return del('. /dist').then(paths => {
    // If paths length is 0, the folder does not exist
    if (paths.length) {
      console.log(paths + ' deleted successfully')
    } else {
      console.log('Folder does not exist');
    }
  });
});

上記のコードで作成したcleanタスクは、cleanタスクの実行時にdistディレクトリを削除します。

画像の処理

画像の取り扱いは比較的簡単で、画像を圧縮して対応するディレクトリにコピーするだけです。画像を圧縮するために使用するモジュールは gulp-imagemin .

gulp.task('imgs', () => {
  return gulp.src([
      '. /src/imgs/*.jpg',
      '. /src/imgs/*.png',
      '. /src/imgs/*.gif',
      '. /src/imgs/*.svg'
    ], {
      base: 'src'
    })
    .pipe(imagemin())
    .pipe(gulp.dest('. /dist'));
});

上記のコードで作成したimgsタスクで、タスクimgsが実行されると . /src/imgs の内容をコピーし . /dist/imgs の中にある

htmlの取り扱い

htmlファイルの扱いは少し複雑です。圧縮と置換が関係するのです。htmlの内容を置き換える場合、使用するモジュールは gulp-replace ; html ファイルを圧縮する必要がある場合は gulp-htmlmin .

ここで、flexible.jsを導入したhtmlを対応する内容に置き換える必要があるので、以下のように記述します。

    .pipe(replace('<script type="text/javascript" src=". /common/flexible.min.js"></script>', () => {
      // Get the contents of the flexible.min.js file
      let flexibleData = fs.readFileSync(path.resolve(__dirname, '. /src/common/flexible.min.js'));
      // return a stream to write to and use for the next content
      return `<script type="text/javascript">\n${flexibleData}</script>`;
    }))

また、初期化されたCSSスタイルはhtmlファイルに注入され、html内の対応するパスは対応するファイルのコンテンツに置き換えられる必要があります。

    .pipe(replace('<link rel="stylesheet" type="text/css" href=". /common/reset.css">', () => {
      // Get the contents of the reset.css file
      let flexibleData = fs.readFileSync(path.resolve(__dirname, '. /src/common/reset.css'));
      // return a stream to write the next content to use
      return `<style type="text/css">\n${flexibleData}</style>`;
    }))

対応するファイルを置き換えたら、htmlファイルからすべてのコメントを削除する必要があります。

    .pipe(htmlmin({
      collapseWhitespace: false, // remove spaces and newlines from the document, default is false, do not remove
      removeComments: true // clear the content of comments
    }))

最後に、対応するhtmlファイルを対応するフォルダにコピーすることです。完全なタスクコードは以下の通りです。

gulp.task('html', () => {
  return gulp.src('. /src/html/*.html', {
      base: 'src'
    })
    .pipe(replace('<script type="text/javascript" src=". /common/flexible.min.js"></script>', () => {
      // Get the contents of the flexible.min.js file
      let flexibleData = fs.readFileSync(path.resolve(__dirname, '. /src/common/flexible.min.js'));
      // return a stream to write to and use for the next content
      return `<script type="text/javascript">\n${flexibleData}</script>`;
    }))
    .pipe(replace('<link rel="stylesheet" type="text/css" href=". /common/reset.css">', () => {
      // Get the contents of the reset.css file
      let flexibleData = fs.readFileSync(path.resolve(__dirname, '. /src/common/reset.css'));
      // return a stream to write the next content to use
      return `<style type="text/css">\n${flexibleData}</style>`;
    }))
    .pipe(htmlmin({
      collapseWhitespace: false, // remove spaces and newlines from the document, the default is false, do not remove
      removeComments: true // clear the content of comments
    }))
    .pipe(gulp.dest('. /dist'));
});

スタイルの取り扱い

スタイル・ファイルの扱いは、もう少し複雑です。実装しなければならないことがいくつかあります。

  1. sassファイルをcssに変換する
  2. pxをremに変換する
  3. ブラウザのプレフィックスを自動で追加する
  4. css属性のソート
  5. cssコードの圧縮

まず、アンダースコアで始まる.scssファイルを変換しないルールを定義します。publicメソッドを提供するファイルとして、アンダースコアで始まる.scssファイルを使用します。

  gulp.src(['. /src/css/*.scss', '! /src/css/_*.scss'], {
      base: 'src'
    })

.scss ファイルは翻訳され、結果の css ファイルはコメントアウトされません。コメント情報は px から rem に変換するときに使用されるからです。変換に使用されるモジュールは gulp-sass .

    .pipe(sass({
      outputStyle: 'compact' // output style for sass files, preserving comments
    }))

px を対応する rem に変換するには、2 つのモジュールの依存関係が必要です。 gulp-postcss postcss-px2rem . postcss-px2rem は、コアとなる変換モジュールです。

    .pipe(postcss([px2rem({
      remUnitpx2rem: 75 // // Converts px to rem with a base value of 75, which means using 75px/75=1rem
    })]))

次に、CSSの互換性を確保するために、ブラウザのプレフィックスをプロパティに追加します。ブラウザのプレフィックスを自動的に追加するために使用するモジュールは gulp-autoprefixer .

    .pipe(autoprefixer({
      browsers: ['last 2 versions', 'Android >= 4.0'] // control the version that adds the prefix
    }))

ページ内のタグとタグ内のセレクタ属性に基づいてスタイルを絞り込みます。主に、postcssプラグインを使用します。 postcss-uncss を使用してスタイルを効率化しますが postcss-uncss モジュールは、順番に uncss モジュールの両方がインストールされている必要があります。インストールが完了したら、流線型のスタイルのコードを設定します。

    .pipe(postcss([uncss({ // remove redundant styles
      html: ['. /src/**/*.html']
    })]))

次に行うことは、CSSのソートと圧縮です。cssの属性の並べ替えに使うモジュールは gulp-csscomb で、CSSを圧縮するためのモジュールは gulp-cssnano .

    .pipe(csscomb()) // Sort CSS properties
    .pipe(cssnano()) // compress CSS code
    .pipe(gulp.dest('. /dist'));

デフォルトのタスク

デフォルトのタスクでは、まずタスクの実行順序がシリアライズされます。各タスクが実行される前に、distディレクトリが削除され、その後、html css imgsタスクが実行されます。今回は gulp-sequence モジュールで、タスク実行の順序を定義します。タスクの連続実行を実現するために、各タスクでストリームを返すか、コールバック関数を呼び出すかしないと、実行順序が正しくありません。

gulp.task('build', gulpSequence('clean', ['html', 'css', 'imgs']));

ブラウザを自動的にリフレッシュするようなコード変更を実装したい場合は browser-sync モジュールになりました。

gulp.task('default', ['build'], () => {
  // Start the browser
  browserSync({
    server: {
      baseDir: '. /dist'
    },
  }, (err, bs) => {
    console.log(bs.options.getIn(["urls", "local"]));
  });
  // Monitor the file for changes and perform the corresponding tasks
  gulp.watch('src/html/*. *', ['html']);
  gulp.watch('src/css/*. *', ['css']);
  gulp.watch('src/imgs/*. *', ['imgs']);
});

デフォルトのタスクを実行した後にコードを修正すると、リフレッシュに続いてブラウザが見つかりません。

$ . /node_modules/.bin/gulp

これは、各タスクでブラウザにリフレッシュが通知されないためで、各タスクにリフレッシュを通知するストリーム変更を追加します。

    .pipe(browserSync.reload({ // pipe refresh
      stream: true
    }))
    .pipe(gulp.dest('. /dist'));

使用方法

  1. src/htmlにhtmlファイルを書き込む
  2. ページのヘッダーに <script type="text/javascript" src=". /common/flexible.min.js"></script> <link rel="stylesheet" type="text/css" href=". /common/reset.css">
  3. .scss スタイルを src/css に記述する。
  4. imgsフォルダに画像を配置する
  5. コマンドを実行します。 . /node_modules/.bin/gulp

もちろん、package.jsonで設定することでコマンドを簡略化することも可能です。

  "scripts": {
    "gulp": "gulp"
  }

この時点で、コマンドラインからコマンドを実行すると、次のようになります。

$ npm run gulp