๋ฆฌ์กํธ๋ฅผ ๊ณต๋ถํ๋ฉด์ CRA ๋๋ง๋ค ๋ฐ๋ณต์ ์ผ๋ก ๊ธฐ๋ณธ ํ์ผ์ ์์ฑํ๊ฑฐ๋ ํด๋๋ง ์์ ์ ํ๋ ๊ฒ์ด ์๊ฐ์ด ์๊น๋ค๋ ์๊ฐ์ด ๋ค์๋ค. ๋งค ๋ฒ component ๊ตฌ์กฐ๋ ํ์ผ์ด ๋ฐ๋์๊ธฐ ๋๋ฌธ์ ํ์ผ์ ๋ณต์ฌ ๋ถ์ฌ๋ฃ๊ธฐ๋ ์ ๋งคํ๋๋ฐ, ์ด ์์ ๋ค์ Node.js์ file system์ ์ด์ฉํด์ ์๋ํ๋ฅผ ํด๋ณด์๋ค.
file system ๋ชจ๋ import
Node.js์ ๋ด์ฅ๋์ด์๋ ํ์ผ์์คํ ์ ๋ถ๋ฌ์จ๋ค.
const fs = require('fs');
๋๋ ํ ๋ฆฌ ์ธํ
์์ฑํ ๋๋ ํ ๋ฆฌ ๊ฒฝ๋ก๋ฅผ array์ ๋ด์ ์์ฑํด์ค๋ค.
const arrDirectory = [
'src/apis',
'src/components/Shared/BtnLike',
'src/components/Shared/NotFound',
'src/components/Shared/FailLoadData',
'src/pages/CartPage',
'src/pages/HomePage',
'src/pages/ProductDetailPage',
];
์์ฑํ ํ์ผ์ ํ ํ๋ฆฟ ์ธํ
ํ์ผ์ด ์์ฑ๋์์ ๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ค์ด๊ฐ ์ฝ๋๋ฅผ ์์ฑํด์ฃผ๋ ํจ์๋ฅผ ์ถ๊ฐํ๋ค.
์๋์ ์ฝ๋๋ JSX ์ปดํฌ๋ํธ์ styled-component ํ์ผ์ ํ ํ๋ฆฟ์ ์์ฑํ๋ ํจ์๋ค.
const constComponent = title => `import React from 'react';
import {${title}Wrapper} from './styled.jsx'
const ${title} = () => {
return <p>${title}</p>;
};
export default ${title};
`;
const styledComponent = title => `import styled from 'styled-components';
export const ${title}Wrapper = styled.div\`\`;
`;
Util ํจ์ ์ถ๊ฐ
ํ์ค์นผ ์ผ์ด์ค๋ฅผ ์นด๋ฉ ์ผ์ด์ค๋ก ๋ณํํ๋ ํจ์๋ฅผ ์ถ๊ฐํ๋ค.
์ด ํจ์๋ ๋ค์ด๋ฐ ์ปจ๋ฒค์ ์ ๋ง์ถ๊ธฐ ์ํด ์ถ๊ฐํด์ค ๊ฒ์ผ๋ก ํ์์ ์ธ ๋ถ๋ถ์ ์๋๋ค.
const pascalToCamel = str => {
return str[0].toLowerCase() + str.slice(1);
};
ํ์ผ ์์ฑ ํจ์ ์ถ๊ฐ
ํ์ผ์ ์์ฑํ ๋๋ ํ ๋ฆฌ, ํ์ผ๋ช , ํ ํ๋ฆฟ์ ์ธ์๋ก ๋ฐ๋ ํจ์๋ฅผ ๋ง๋ค์ด์ฃผ์๋ค.
fs.writeFile
์ ํตํด ํ์ผ์ ์์ฑํ๋๋ฐ, ์ด๋ฏธ ์กด์ฌํ๋ค๋ฉด ํ์ผ์ด ์์ฑ๋์ง ์๊ณ ์๋ฌ๋ฅผ ๋ฐํํ๋๋ก ์ต์
์ ์ฃผ์๋ค.
const createFile = (dir, file, content) => {
fs.writeFile(
`${dir}/${file}`,
content,
{
flag: 'ax',
},
err => {
if (err === null) {
console.log(`${file} file successfully saved`);
} else if (err.code === 'EEXIST') {
console.log('File already exists');
}
}
);
};
๋๋ ํ ๋ฆฌ ๋ฐ ํ ํ๋ฆฟ ํ์ผ ์์ฑ
fs.mkdirSync
๋ฅผ ์ด์ฉํด์ ํด๋๋ฅผ ์์ฑํ๋ ํจ์๋ฅผ ์ถ๊ฐํ๋ค.
์์์ ์ ์ธํด ์ค ๋๋ ํ ๋ฆฌ array๋ฅผ ์ํํ๋ฉด์ ํด๋์ ํ์ผ์ ์์ฑํด์ฃผ์๋ค.
const createDirectory = path => {
path.split('/').reduce((directories, directory) => {
const category = directories;
directories += `${directory}/`;
if (!fs.existsSync(directories)) {
fs.mkdirSync(directories);
}
// components ์ pages ํ์ ๊ฒฝ๋ก์ ํ
ํ๋ฆฟ ์์ฑ
if (category.includes('components') || category.includes('pages')) {
createFile(directories, `styled.jsx`, styledComponent(directory));
createFile(
directories,
`${directory}.jsx`,
constComponent(directory)
);
}
return directories;
}, '');
};
arrDirectory.forEach(item => createDirectory(item));
scripts ์ถ๊ฐ
์กฐ๊ธ ๋ ์ง๊ด์ ์ผ๋ก ๋ช ๋ น์ด๋ฅผ ์์ฑํ ์ ์๋๋ก scripts๋ฅผ ์ถ๊ฐํด์ฃผ์๋ค.
์ด์ ์์ฑํ js ํ์ผ์ ํ๋ก์ ํธ์ ๋ฃจํธ ๋๋ ํ ๋ฆฌ์ ๋๊ณ ํฐ๋ฏธ๋์ node ํ์ผ๋ช
์ ์
๋ ฅํ๋ฉด ๊ธฐ๋ณธ ํด๋๊ฐ ์์ฑ๋๋ค.
// package.json
"scripts": {
"setDir": "node {ํ์ผ๋ช
}"
},
