webpackの設定をちょっと変更して起動したいとき、webpack.config.js
を直接書き換えるか、それ用のwebpack.config.hoge.js
とかを用意したりすればいいよね。
なんだけど、yarn hogehoge
ってしたらCLIツールが立ち上がって、対話形式で設定を変更できたらすこしおしゃれじゃないですか。
ということで、試してみた。
参考にさせていただいた記事は以下の通り。
https://codeburst.io/building-a-node-js-interactive-cli-3cb80ed76c86
まずは下準備
おもむろにindex.js
を作成しよう。
index.js
const init = () => {
console.log('Ohanky');
};
const run = async () => {
init();
};
run()
早速実行してみよう。コンソールにOhanky
がでるはずだ。
実行
$ node index.js
Ohanky
かっこよくする
このままだと味気ないで、コンソールに表示される文字に色をつけよう。
chalk
というパッケージを使うみたい。
githubのページもカラフルで綺麗な感じになってる。
github.com
$ yarn add --dev chalk
使い方は、ものすごくシンプルで、以下にようにconsole.log()
内にchalk
の関数を実行しているだけ。
index.js
const chalk = require('chalk');
const init = () => {
console.log(chalk.blue('Ohanky'));
};
const run = async () => {
init();
};
run();
さきほどと同様に実行してみれば、青色のOhanky
がコンソールに表示されたはず。
もっとかっこよくする
いけてるCLIツールはかっこいいアスキーアートが起動すると表示されているよね。
自分でつくるのは大変だけど、figlet
というパッケージをつかうと簡単にできるみたい。
$ yarn add --dev figlet
github.com
いろんなオプションがあるけと、アスキーアートを作成はデフォルト非同期とのことなので、同期的に実行できるtextSync
だけを使うことにしてみる。
index.js
const chalk = require('chalk');
const figlet = require('figlet');
const init = () => {
console.log(chalk.blue(figlet.textSync('Ohanky')));
};
const run = async () => {
init();
};
run();
実行してみると、もうかっこいい!
※ブラウザでみるとフォントの違いか、とても見にくい😇
$ node index.js
___ _ _
/ _ \| |__ __ _ _ __ | | ___ _
| | | | '_ \ / _` | '_ \| |/ / | | |
| |_| | | | | (_| | | | | <| |_| |
\___/|_| |_|\__,_|_| |_|_|\_\\__, |
|___/
対話できるようにする
ようやく本題。
といってもパッケージ、inquirer
を使うだけでシンプルに作ることができるとのこと。
$ yarn add --dev inquirer
github.com
ひとまず、webpackの設定という方針は忘れて、適当に選択肢を作って選ぶことにしてみる。
index.js
const chalk = require('chalk');
const figlet = require('figlet');
const inquirer = require('inquirer');
const askQuestions = () => {
const questions = [
{
type: 'list',
name: 'member',
message: "Please choose which one you like from",
choices: ['ayane', 'mirin']
}
];
return inquirer.prompt(questions);
};
const init = async () => {
console.log(chalk.blue(figlet.textSync('Ohanky')));
const result = await askQuestions();
console.log(result);
};
const run = async () => {
init();
};
run();
これを実行すると、以下ように選択肢に設定した項目が選べるようになる!
___ _ _
/ _ \| |__ __ _ _ __ | | ___ _
| | | | '_ \ / _` | '_ \| |/ / | | |
| |_| | | | | (_| | | | | <| |_| |
\___/|_| |_|\__,_|_| |_|_|\_\\__, |
|___/
? Please choose which one you like from (Use arrow keys)
❯ ayane
mirin
// 選んでEnterを押下すると以下のオブジェクトが出力される
{ member: 'ayane' }
もっと便利に対話できるようにする
リストから選択肢を選ぶのもいいけれども、選択肢がたくさんあったら面倒だよね、ということで、ユーザー入力値を設けて、フィルターできる機能を追加することにする。
これは、さきほどのinquirer
のプラグインという形ですでに用意されている。
$ yarn add --dev inquirer-autocomplete-prompt
github.com
こちらがinquirer-autocomplete-prompt
を使ったサンプルは以下の通り。
githubをみると、絞り込みにはさらにfuzzy
なるパッケージがおすすめというとでしたが、ひとまずシンプルにarray.filterを使うことにします。
index.js
const chalk = require('chalk')
const figlet = require('figlet')
const inquirer = require('inquirer')
inquirer.registerPrompt('autocomplete', require('inquirer-autocomplete-prompt'))
const members = ['ayane', 'mirin', 'eitaso', 'risa', 'nemo', 'perorin']
const getMember = (answer, input) => {
const member = members.filter(item => item.indexOf(input) !== -1)
const result = member.length > 0 ? member : members
return Promise.resolve(result)
}
const askQuestions = () => {
const questions = [
{
type: 'autocomplete',
name: 'member',
message: 'Please choose which one you like from ',
source: getMember,
},
]
return inquirer.prompt(questions)
}
こうすることでいい感じに絞り込みを行うことができた。
/ _ \| |__ __ _ _ __ | | ___ _
| | | | '_ \ / _` | '_ \| |/ / | | |
| |_| | | | | (_| | | | | <| |_| |
\___/|_| |_|\__,_|_| |_|_|\_\\__, |
|___/
? Please choose which one you like from ne
❯ ayane
nemo
本題という名の蛇足
あ、webpackの設定だったね、ということで、この対話ツールをwebpack起動時に呼び出すようにする。
試しにマルチページアプリケーションでエントリーポイントがページごとにあるという設定で考えてみる。
さきほどindex.js
でつくっていたファイルをselectEntry.js
に変更して、webpack.config.js
の設定を書いてみる。
対話ツールは、ユーザーが操作して値が決まるので、それを待ってからwebpackを起動する必要がある。
これについては、公式サイトをみるとPromiseを返す設定もできるとのこと。
webpack.js.org
なので、以下のように設定を行う。
webpack.config.js
const selectEntry = require('./selectEntry')
module.exports = async () => {
const entry = await selectEntry()
return {
mode: 'development',
entry
}
}
ここまできたら、selectEntry.js
をwepback.config.js
から呼び出せるように修正を行うだけ。
index.js
const chalk = require('chalk')
const figlet = require('figlet')
const inquirer = require('inquirer')
const parsePath = require('parse-filepath')
inquirer.registerPrompt('autocomplete', require('inquirer-autocomplete-prompt'))
const entryPaths = ['./src/index.js', './src/other.js']
const getEntryPoint = (answer, input) => {
const target = entryPaths.filter(item => item.indexOf(input) !== -1)
const result = target.length > 0 ? target : entryPaths
return Promise.resolve(result)
}
const askQuestions = () => {
const questions = [
{
type: 'autocomplete',
name: 'ENTRY',
message: "select webpack's entry point",
source: getEntryPoint,
},
]
return inquirer.prompt(questions)
}
const init = async () => {
console.log(chalk.blue(figlet.textSync('Ohanky')))
return await askQuestions()
}
const run = async () => {
const answer = await init()
const name = parsePath(answer.ENTRY).name
return {
[name]: answer.ENTRY,
}
}
module.exports = run
これで、webpack起動時に、対話ツールが起動し、対話ツールで選択した結果がconfigに反映することができた。