TL;DR
Reactでコンポーネントを新しく作るとき、Storybookやテストも作成するのであれば、ディレクトリを作成してから、
index.ts
, Component.tsx
Component.stories.tsx
Component.spec.tsx
と4ファイルくらい作成することになると思いますが、
毎回これらを手動で作成して、他のコンポーネントからimport文とかをコピーしてくるのは面倒なので、CLIツールを作成して、コマンド一発で出来るようにします。
コードはこちら
作ったもの
ディレクトリ構成
AtomicDesign想定です。
.
├── package.json
├── src
│ └── components
│ └── atoms
│ └── Button
│ ├── Button.spec.tsx
│ ├── Button.stories.tsx
│ ├── Button.tsx
│ └── index.ts
└── tools
├── componentTemplates
│ ├── Component.tsx
│ ├── Spec.tsx
│ ├── Story.tsx
│ └── index.ts
└── createComponent.js
コード
テンプレート作成
まず、環境に合わせて ./tools/componentTemplates/
以下に、作成したいファイルのテンプレートを配置します。
このテンプレートをリネームして、必要な場所にコピーする感じです。
テンプレートはこちらを参照してください。
script作成
コマンドライン引数 オプション -C
で、コンポーネントの粒度とコンポーネント名を受け取ります。
以下はコマンドのhelpです。
Usage: create-component [options]
Options:
-C, --component [dir/Component] The name of the component to be created (ex) atoms/Button
-h, --help display help for command
- 引数が不正である場合はエラー(atoms, molecules, organismsしか許容しない)
- すでにコンポーネントが存在しているときはエラー(上書きしない)
- ディレクトリが存在しないとき(
/molecules/
など未作成の場合)は新規作成
します。
コードは以下です。
const { program } = require("commander");
const fs = require("fs");
program.option(
"-C, --component [component name]",
"The name of the component to be created (ex) atoms/Button"
);
program.parse(process.argv);
if (!program.component) {
program.help();
}
const argument = program.component.split("/");
const dir = argument[0];
const component = argument[1];
if (!["atoms", "molecules", "organisms"].includes(dir)) {
console.error(
"ERROR: Only 'atoms', 'molecules', and 'organisms' can be specified."
);
return;
}
// If the directory is not yet created, create it.
if (!fs.existsSync(`./src/components/${dir}`)) {
fs.mkdirSync(`./src/components/${dir}`);
}
const templates = [
"./tools/componentTemplates/index.ts",
"./tools/componentTemplates/Component.tsx",
"./tools/componentTemplates/Story.tsx",
"./tools/componentTemplates/Spec.tsx",
];
const dests = [
`./src/components/${dir}/${component}/index.ts`,
`./src/components/${dir}/${component}/${component}.tsx`,
`./src/components/${dir}/${component}/${component}.stories.tsx`,
`./src/components/${dir}/${component}/${component}.spec.tsx`,
];
fs.mkdirSync(`./src/components/${dir}/${component}`);
// Error when a component already exists
templates.forEach((template, index) => {
fs.copyFileSync(
template,
dests[index],
fs.constants.COPYFILE_EXCL,
(error) => {
if (error) {
throw error;
}
}
);
console.log(`✨ Create component template ${dests[index]}`);
});
package.jsonに追記
package.json
のscriptsに、
"create-component": "node ./tools/createComponent.js"
を追記して完了です。
使用例
$ yarn create-component -C atoms/Icon
✨ Create component ./src/components/atoms/Icon/index.ts
✨ Create component ./src/components/atoms/Icon/Icon.tsx
✨ Create component ./src/components/atoms/Icon/Icon.stories.tsx
✨ Create component ./src/components/atoms/Icon/Icon.spec.tsx
これでめんどくさい作業から開放されました!