-
Vue application with React componentFrameworks, Platforms and Libraries/Vue.js 2023. 10. 8. 16:09
현재 회사에서 운영 중인 세 개의 application 중 두 개의 application의 경우 React, 남은 하나의 application는 Vue.js 기반이었습니다. 운영 중인 Vue.js 기반의 application을 React로 포팅할려는 니즈가 있었지만 한 번에 빅뱅 하기엔 시간이 부족하여 점진적으로 React로 포팅하고 신규 기능 페이지의 경우는 미리 React로 구성하기로 했습니다. 그렇다 보니 기존 Vue.js 기반의 application에 React component를 띄워야 했고 이때 사용한 방식을 포스팅하고자 합니다.
react → vue 변환 모듈
※ Vue는 Class Component 형태로 작성되었습니다.
ReactDOMClient의 createRoot()를 통해 렌더링 되는 DOM의 위치를 Vue.js 기반의 application으로 향하게 합니다.
// glue.tsx import React from 'react'; import { createRoot } from 'react-dom/client'; // import { Provider } from 'react-redux'; // import { store } from './store'; import './styles/index.scss'; export function mount( targetNode: HTMLElement, component: React.FunctionComponent, ) { const reactElement = React.createElement(component); const root = createRoot(targetNode!); root.render(reactElement); // 필요에 따라 store도 임시로 연결할 수 있습니다. // root.render(<Provider store={store}>{reactElement}</Provider>); return root; }
// Bridge.ts // react => vue import { Component, Vue } from 'vue-property-decorator'; import { Root } from 'react-dom/client'; import { mount } from './glue'; @Component({ name: 'Bridge', }) export default class extends Vue { reactRoot: Root | null = null; setComponent(component: React.FunctionComponent) { this.reactRoot = mount(this.$el as HTMLElement, component); } beforeDestroy() { this.reactRoot?.unmount(); } }
적용
// Component.tsx function Component() { return <div>Vue application with React component</div>; } export default Component;
// ComponentBridge.vue <template> <div></div> </template> <script lang="ts"> import { Component } from 'vue-property-decorator'; import Component from './Component'; import Bridge from './Bridge'; @Component({ name: 'ComponentBridge', }) export default class extends Bridge { mounted() { this.setComponent(Component); } } </script>
router를 통해 ComponentBridge 페이지를 보면 정상적으로 출력이 됩니다.
후기
Vue.js 기반의 application을 당장 React로 빅뱅 할 시간이 부족하여 신규 기능 페이지만이라도 미리 React로 구성하기 위해 사용한 방식이었습니다. 하나의 application에서 두 개의 프론트엔드 프레임워크가 공존하는 건 좋지 않지만 이러한 방식을 통해 점진적으로 포팅할 수 있었습니다. 그래도 역시나 빠른 시일 내에 완전히 포팅을 완료해야겠습니다.
'Frameworks, Platforms and Libraries > Vue.js' 카테고리의 다른 글
Vue Class Component with Decorator (0) 2023.09.16