はじめに
この記事はZOZOテクノロジーズ #3 Advent Calendar 2019 16日目の記事です。
昨日は、@zt_takumi_ito さんのPowerShellでサーバアクセスするときのパスワード入力で楽するでした。
HTMLメールを作成する機会があり、調べてみると通常のコーディングと異なり下記の制約の下で作成する必要があることがわかりました。
- メーラーによってCSSの各種プロパティの対応状況が異なる
- スタイルは要素にインラインで記述する(外部読み込みやstyleタグによる記述はメーラーにより非対応)
- 実際にメールを送信して表示を確認する必要がある
一度作成して終わりであれば、スタイルをタグに直接書いて作成するのもありだと思いますが、
今後も運用が予想されたためクラスを使用してスタイルを適用させることでなるべく楽をしたいと考えました。
機能
そこで下記の機能を持つツールを作成しました。
- 外部ファイルで記述したCSSをインラインに自動変換してくれる
- HTMLやCSSに変更があればブラウザを自動更新する
- 作成した内容をメールで送って確認できるようにする
- 送信する対象のHTMLを指定できる
- 送信時のタイトルを指定できる
また、SASSを使えるようにしました。
作成したツールの詳細
webpackでの作成も考えましたが個人的な慣れやJSは使用しないことからgulpベースで作成しました。
なお作成したツールはGithubに公開しています。
バージョン
- gulp
- CLI version: 2.2.0
- Local version: 4.0.2
- node
- 10.15.3
ディレクトリ構成
root
├ src
├ ├ index.html
├ ├ css
├ └ sass
├ .env-sample
├ .gitignore
├ gulpfile.js
└ package.json
使用モジュール
モジュール名 | 主な利用機能 |
---|---|
browser-sync | ファイルに変更があればブラウザを自動更新 |
gulp-sass | SASSを使えるように |
gulp-inline-css | 外部CSSをインラインに変更 |
gulp-mail | メール送信機構 |
minimist | コマンド引数を作成 |
node-env-file | 環境変数の設定 |
基本的な使い方
作成編
- リポジトリをクローンする
-
npm ci
で各種モジュールをインストールする -
npx gulp
でツールを起動する - src配下にhtmlファイルを設置しテーブルコーディングをする
- src/sass配下にscss記法でスタイルを記述
メール送信編
- .env-sampleを.envにリネームして送信先、送信元の情報を記述する
-
npx gulp mail
でメールを送信する
メールテンプレートとしてhtmlを複数作成している場合、npx gulp mail --file hoge
とするとhoge.htmlの内容を送信できます。(デフォルトではindex.html)
また、メールのタイトルを指定したい場合、npx gulp mail --subject fuga
とするとfugaがタイトルのメールとして送信されます。(デフォルトではhtml mail test)
設定ファイルの記述
.env-sampleの記述内容
Gmailのアカウントを使用することを前提としています。
# 送信先(複数はカンマ区切り、スペースを入れない)
mailTo=example@gmail.com,example_02@gmail.com
# 送信元
smtpUser=example_03@gmail.com
smtpPass=example_03_pass
smtpHost=smtp.gmail.com
smtpPort=465
gulpfile.jsの記述内容
/**
* ------------------------------------------------------------
* 読み込み
* ------------------------------------------------------------
*/
const gulp = require('gulp');
const sass = require('gulp-sass');
const inlineCss = require('gulp-inline-css');
const browserSync = require('browser-sync').create();
const mail = require('gulp-mail');
const env = require('node-env-file');
const minimist = require('minimist');
const src = './src/';
const dist = './dist/';
env('.env');
const mailTo = process.env.mailTo;
const smtpUser = process.env.smtpUser;
const smtpPass = process.env.smtpPass;
const smtpHost = process.env.smtpHost;
const smtpPort = process.env.smtpPort;
/**
* ------------------------------------------------------------
* 設定
* ------------------------------------------------------------
*/
const sassOption = {
outputStyle: 'expanded'
}
const inlineCssOption = {
applyStyleTags: false,
removeStyleTags: false,
applyTableAttributes: true,
removeHtmlSelectors: true
};
const browserSyncOption = {
server: dist
};
const smtpInfo = {
auth: {
user: smtpUser,
pass: smtpPass
},
host: smtpHost,
secureConnection: true,
port: smtpPort
};
const fileOptions = minimist(process.argv.slice(2), {
string: 'file',
default: {
file: 'index'
}
});
const file = fileOptions.file;
const subjectOptions = minimist(process.argv.slice(2), {
string: 'subject',
default: {
subject: 'html mail test'
}
});
const subject = subjectOptions.subject;
/**
* ------------------------------------------------------------
* タスク
* ------------------------------------------------------------
*/
gulp.task('sass', () => {
return gulp
.src(src + 'sass/**/*.scss')
.pipe(sass(sassOption))
.pipe(gulp.dest(src + 'css/'));
});
gulp.task('inlineCss', () => {
return gulp
.src(src + '**/*.html')
.pipe(inlineCss(inlineCssOption))
.pipe(gulp.dest(dist))
});
gulp.task('serve', (done) => {
browserSync.init(browserSyncOption);
done();
});
gulp.task('mail', () => {
return gulp
.src(dist + file + '.html')
.pipe(mail({
subject: subject,
to: [
mailTo
],
from: smtpUser,
smtp: smtpInfo
}));
});
/**
* ------------------------------------------------------------
* watchタスク
* ------------------------------------------------------------
*/
gulp.task('watch', (done) => {
const browserReload = (done) => {
browserSync.reload();
done();
};
gulp.watch(src + '**/*.scss', gulp.series('sass', 'inlineCss'));
gulp.watch(src + '**/*.html', gulp.task('inlineCss'));
gulp.watch(dist + '*', browserReload);
});
gulp.task('default', gulp.series('serve', 'watch'));
今後の課題
今後、ローカル環境にある画像を手軽に読み込ませる方法を模索しようと考えおります。
現状では画像のサイズのみを合わせてLorem Picsumで仮画像を配置する方法を取っております。
何かいい方法があれば教えていただけると幸いです。