この記事はBASE Advent Calendar 2019の6日目の記事です
どうもこんにちは、Frontend Groupの青木です
BASEではVue.js+TypeScriptを採用したフロントエンド開発を行っています
今回のブログでは、私が業務で直面したちょっとした課題を、Vue.jsのカスタムディレクティブを実装して解決し、npmのパッケージとして公開した話をします
何を作ったか
spanやaなどのinline要素内での改行による意図しないスペースを削除するVue.jsのカスタムディレクティブを作りました
挙動としては
<p v-remove-whitespace> お問い合わせは <a href="#">こちらから</a> お願いします </p>
というvueのtemplateが、レンダリングされる際には
<p>お問い合わせは<a href="#">こちらから</a>お願いします</p>
となります
ディレクティブの指定がある場合と無い場合では、
お問い合わせはこちらからお願いします お問い合わせは こちらから お願いします
のような見かけ上の違いが生じます
この程度の文字数であれば、最初から改行を含めなければいいのでは?と思うところですが、各要素のattribute属性やイベント修飾子、propsなど入力するものが増えたりすると、改行したくなったりすることもあり、解決できるものを作ろうと思いました
npmのpackageとして公開するまでにしたこと
- 公式のカスタムディレクティブのドキュメントを読む
- 使っているライブラリのソースコードを読む
- 現在公開されているnpmのカスタムディレクティブを探し、ソースコードを読む
調べている過程で、vue-focusというライブラリの開発構成がシンプルそうでいいなと思い、構成をforkして、機能実装を済ませ、初回のリリースを終えました
テストの実装と、TypeScriptの開発環境で使いやすくする
公開して満足してしまい、追加で開発しようと思っていたことができていなかったのですが、今回のアドベントカレンダーを機会に、テストの実装とTypeScriptの開発環境で使いやすくしてみました
テストを実装するまでにしたこと
公式の単体テストのドキュメントを読む
デモリポジトリをクローンし、テストを体験する
実際にテストを書いてみる
import { removeWhitespace } from '../index' export default { directives: { removeWhitespace }, template: ` <div v-remove-whitespace> <span>1</span> <span>2</span> <span>3</span> <span>4</span> <span>5</span> </div> `, }
import { mount } from '@vue/test-utils' import InlineElementWithLineBreak from './InlineElementWithLineBreak' describe('InlineElementWithLineBreak', () => { const wrapper = mount(InlineElementWithLineBreak) it('renders the correct markup', () => { expect(wrapper.html()).toBe('<div><span>1</span><span>2</span><span>3</span><span>4</span><span>5</span></div>') }) })
簡単なテストですが、期待通りに動いていることが確認できました🎉
TypeScriptの開発環境で使いやすくするためにしたこと
- index.d.tsを書く
https://github.com/aokiken/vue-remove-whitespace/blob/master/index.d.ts
import { DirectiveOptions } from 'vue' export const version: string export const removeWhitespace: DirectiveOptions export const mixin: { directives: { [key: string]: DirectiveOptions, }, }
- package.jsonにtypesを追記する
https://github.com/aokiken/vue-remove-whitespace/blob/master/package.json#L61
これらを追記したおかげで、TypeScriptのプロジェクトでも、型情報が参照できるようになりました🎉
最後に
今回のnpm公開は、実装の過程でコンパクトな機能が出来たので、これなら公開できそうと思ったことと、 まずはやってみよう という思いから挑戦してみました
おまけ1: いくつか対応策はあった
閉じタグの>を改行すればスペースは入らない
<div> <span>1</span ><span>2</span ><span>3</span ><span>4</span ><span>5</span> </div>
開始タグの<tag以下を改行すればスペースは入らない
<div> <span >1</span><span >2</span><span >3</span><span >4</span ><span >5</span> </div>
コメントアウトを挟めばスペースは入らない
<div> <span>1</span><!-- --><span>2</span><!-- --><span>3</span><!-- --><span>4</span><!-- --><span>5</span> </div>
おまけ2: cssで工夫するとスペースや改行が入り込む
https://codepen.io/aokiken/pen/vYBLMyv 気にならなければ良い気もしている
おまけ3: 英語では困らない
そもそも単語区切りでスペースが入るので、困らないのか、と実装してて気がつきました 逆に、日本語、中国語、タイ語などの言語では有効そう
明日はService Devマネージャーの菊地さんと人事の米田さんです!