<문제점>
컴포넌트들을 만든 후 index.js에 각 Vue 컴포넌트를 "수기로 import" 해야하는 상황이 발생하여 자동화가 필요하여 추가
자동화할 대상들은 components 하위에 있는 1depth Directory에 index.js 생성이 필요
하지만 각 1dpeth Directory 밑에는 모듈별 컴포넌트들이 존재하여 아래 Depth에 컴포넌트들도 모두 스캔이 필요
<자동화 전 소스 예시>
/dialog/index.js
import ApprovalHistoryModal from './approval/ApprovalHistoryModal.vue';
import ApprovalLineModal from './approval/ApprovalLineModal.vue';
import ApprovalModal from './approval/ApprovalModal.vue';
import BasicAlert from './basic/BasicAlert.vue';
import BasicConfirm from './basic/BasicConfirm.vue';
import AddressSearchModal from './common/AddressSearchModal.vue';
import TypeContentModal from './common/TypeContentModal.vue';
import GroupModal from './group/GroupModal.vue';
import SingleSiteModal from './site/SingleSiteModal.vue';
import MultiUserModal from './user/MultiUserModal.vue';
import SingleUserModal from './user/SingleUserModal.vue';
export default {
install(Vue) {
Vue.component('ApprovalHistoryModal', ApprovalHistoryModal);
Vue.component('ApprovalLineModal', ApprovalLineModal);
Vue.component('ApprovalModal', ApprovalModal);
Vue.component('BasicAlert', BasicAlert);
Vue.component('BasicConfirm', BasicConfirm);
Vue.component('AddressSearchModal', AddressSearchModal);
Vue.component('TypeContentModal', TypeContentModal);
Vue.component('GroupModal', GroupModal);
Vue.component('SingleSiteModal', SingleSiteModal);
Vue.component('MultiUserModal', MultiUserModal);
Vue.component('SingleUserModal', SingleUserModal);
},
};
/components/export.js
export { default as dialog } from './dialog';
export { default as file } from './file';
export { default as input } from './input';
export { default as table } from './table';
export { default as tree } from './tree';
/components/index.js
import * as components from './export';
export default function install(Vue) {
Object.values(components).forEach((component) => {
Vue.use(component);
});
}
src/index.js
import component from './common/components';
export default {
install(Vue) {
Vue.use(component);
},
};
<작업 내용>
/components/index.js는 수기로 작성할 일이 없어 자동화 대상에서 제외
공통 컴포넌트 1Depth Directory (/dialog/index.js, /file/index.js, 등) 와 최상위 디렉토리(export.js)를 대상으로 처리
공통 컴포넌트 경로는 './src/common/components' 으로 지정하고 처리
[ /script/fileGenerate.js ]
const fs = require('fs');
const rootFolder = './src/common/components';
const readDir = (path, filePaths = []) => {
const files = fs.readdirSync(path);
files.forEach((fileName) => {
const name = `${path}/${fileName}`;
if (fs.statSync(name).isDirectory()) {
return readDir(name, filePaths);
} else {
filePaths.push(name);
}
});
return filePaths;
};
const groupingDir = (files, moduleMap = {}) => {
files.forEach((file) => {
const filePathAndName = file.replace(rootFolder, '').substring(1);
if (filePathAndName.includes('/')) {
const dirName = filePathAndName.split('/')[0];
moduleMap[dirName] = [
...(moduleMap[dirName] || []),
...[`.${filePathAndName.replace(dirName, '')}`],
];
}
});
return moduleMap;
};
const writeIndexFile = (modulePathMap) => {
for (const [key, value] of Object.entries(modulePathMap)) {
const rootPath = `${rootFolder}/${key}/index.js`;
let content = '';
//import
value.forEach((modulePath) => {
// index.js인 경우 패스
if (modulePath.includes('index.js')) return true;
const moduleName = modulePath.substring(
modulePath.lastIndexOf('/') + 1,
modulePath.lastIndexOf('.'),
);
content += `import ${moduleName} from '${modulePath}';\n`;
});
content += '\nexport default {\n' + ' install(Vue) {\n';
// Vue.component
value.forEach((modulePath) => {
// index.js인 경우 패스
if (modulePath.includes('index.js')) return true;
const moduleName = modulePath.substring(
modulePath.lastIndexOf('/') + 1,
modulePath.lastIndexOf('.'),
);
content += ` Vue.component('${moduleName}', ${moduleName});\n`;
});
content += ' },\n' + '};';
fs.writeFileSync(rootPath, content);
}
};
const writeExportFile = (modulePathMap) => {
const rootPath = `${rootFolder}/export.js`;
let content = '';
for (const [key] of Object.entries(modulePathMap)) {
content += `export { default as ${key} } from './${key}';\n`;
}
fs.writeFileSync(rootPath, content);
};
const modulePathMap = groupingDir(readDir(rootFolder));
writeIndexFile(modulePathMap);
writeExportFile(modulePathMap);
- readDir() 함수를 통해 지정한 rootFolder에 하위 파일들을 모두 스캔 후 배열(filePaths) 에 저장
- Directory인 경우는 재귀호출을 하여 안에 있는 파일들을 조회
- groupingDir()을 통해 읽어드린 배열을 최상위 Directory 명으로 오브젝트를 생성
{
dialog: [파일path1, 파일path2],
input: [파일path1, 파일path2],
...
}
- writeIndexFile()을 통해 1depth Directory 밑에 index.js를 생성
- index.js에는 각 컴포넌트 모듈들을 import 및 Vue.component 등록 로직을 추가
- writeExportFile()을 통해 최상위 경로에 export.js를 생성
- export.js에는 1depth Directory에 있는 index.js를 등록하는 로직을 추가
[ /package.json ]
npm run serve 또는 npm run build:lib라는 명령어가 들어오는 경우
"node script/fileGenerate.js" 문구를 추가하여 fileGenerate.js가 실행되도록 추가
{
"name": "컴포넌트명",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "node script/fileGenerate.js && vue-cli-service serve",
"build:lib": "node script/fileGenerate.js && vue-cli-service build --target lib --name micro-portal-component ./src/index.js",
}
...
}
'프런트엔드 > javascript' 카테고리의 다른 글
[javascript] axios multi form 데이터 처리 (0) | 2023.10.12 |
---|