PDFのファイルサイズを表示する際、ファイルサイズ確認して手入力で対応するのは数が多かったりすると面倒ですよね。
JSで取得しても良いのですが、HTMLにベタ書き出来るならその方が色々良いと思います。
って事で、Gulp4+Pugな環境でファイルサイズを自動的に取得して表示するようにした案件が有ったので、その方法の紹介です。
なお、この記事ではGulp4+Pugの開発環境は既に用意されており、GulpやPugに関してある程度理解している前提で書いています。
gulp-data をインストール
まずは、黒い画面からファイルサイズを所得して表示するのに必要なパッケージをインストールします。
npm i gulp-data -D
無事にインストールされれば、package.json に
"gulp-data": "^1.3.1",
が追加されていると思います。
gulpfile.js に追記
インストールが完了したら、gulpfile.jsの最初の方に以下を追記します。
const gulpData = require('gulp-data');
const fs = require('fs');
fsはもとから入ってるはずなので、特にインストールの必要はありません。
そうしたら次に、pugをhtmlにコンパイルするタスク部分にファイルサイズを取得する処理を追記します。
追記するのはハイライトしている、3-29行目になります。
このソースコードはボクが使ってるgulpfile.jsのやつなので、それ以外の箇所は適所自身の環境に合わせて変更してください。
const pug2html = () => {
return src([paths.src + '/**/*.pug', '!' + paths.src + '/**/_*.pug', '!' + paths.inc.src + '/**/*.pug'])
.pipe(
gulpData((file) => {
return {
getFileSize: function(src) {
try {
const stat = fs.statSync(paths.src + src);
const sizeUnit = ['B', 'KB', 'MB', 'GB', 'TB'];
let tmpSize = stat.size;
let filesize = 0;
let sizeNo = 0;
function sizeChange(num) {
const magnification = (sizeNo > 1) ? 100 : 1;
return (Math.ceil((num * magnification) / 1024)) / magnification
}
while(tmpSize >= 1000) {
sizeNo++;
tmpSize = sizeChange(tmpSize);
}
filesize = tmpSize;
return filesize + sizeUnit[sizeNo];
} catch(err) {
if(err.code === 'ENOENT') return 'not found';
}
}
}
})
)
.pipe(
plumber({ errorHandler: notify.onError('Error: <%= error.message %>') })
)
.pipe(
pug({
basedir: paths.src + '/',
pretty: true
})
)
.pipe(
prettier({
printWidth: 240,
})
)
.pipe(using())
.pipe(dest(paths.dist))
}
8行目の
const stat = fs.statSync(paths.src + src);
部分の「paths.src
」は開発環境のディレクトリを指定していますので、ココだけご自身の環境に合わせて書き換えて下さい。
getFileSizeでファイルサイズを取得
これで事前準備は終わったので、後はファイルサイズを取得したいPugファイルに先程追記したgetFileSizeって関数を使ってファイルサイズを取得します。
ul
li
a(href="/filename.pdf" target="_blank")
| なんかのパンフレット(PDF:#{getFileSize(`/filename.pdf`)})
これがコンパイルされると次のような感じのHTMLが生成されます。
<ul>
<li>
<a href="/filename.pdf" target="_blank">なんかのパンフレット(PDF:321KB)</a>
</li>
</ul>
これで、都度ファイルサイズを確認して手入力する必要がなくなるので、数が多い時には便利かと思います。
今回PDF限定で話してますが、zipとかxlsxとかファイルサイズ取得できそうなのなら問題なく使えます。
ちなみに、ファイルが存在しない場合は、下記のように not found と表示されます。
<ul>
<li>
<a href="/filename.pdf" target="_blank">なんかのパンフレット(PDF:not found)</a>
</li>
</ul>
ミックスインにしてみる
先の方法だと同じパスを2回書く必要があるので、それも面倒な場合はミックスインにしておくともう少し使い勝手が良くなるかなと思います。
例えば、
mixin filesize(text, src)
a(href=src target="_blank") #{text}(PDF:#{getFileSize(src)})
みたいにミックスインを作って、使いたい部分で呼び出します。
+filesize('なんかのパンフレット', '/filename.pdf')
これで、パスを2回書かずに済むのでちょっと便利ですね。