티스토리 뷰
배경
바닐라 자바스크립트 또는 타입스크립트로 라이브리리, 프레임 워크없이 꽤나 많은 프로젝트를 했다. 그리고 리액트와 비교했을 때 여러가지 어려운 점이 있었지만 jsx를 사용하지 못하는 것도 조금 아쉬웠다. 그런데 리액트없이 바벨 플러그인 하나를 설치하면 jsx를 사용할 수 있다는 것을 알게 되었다. 그래서 한번 적용해보려고 한다.(사실 리액트 없이 jsx 세팅하는 것 보다 그냥 만드는 게 편하다)
웹팩 설정
나는 바벨을 웹팩에서 같이 설정하는 것을 선호한다. 물론 나눠도 상관없다. yarn add -D @babel/plugin-transform-react-jsx
로 플러그인을 설치하고 바벨 플러그인에 @babel/plugin-transform-react-jsx
를 넣어주면 된다. 바벨을 따로 설정하는 분들이 헷갈릴지도 모른다고 생각해서 그냥 전체 코드를 올린다.
webpack.common.js
module: {
rules: [
{
test: /\.(ts|tsx|js|jsx)$/,
use: {
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-typescript',
[
'@babel/preset-env',
{
targets: '> 1%, not dead',
useBuiltIns: 'usage',
corejs: { version: '3' },
},
],
],
plugins: ['@babel/plugin-transform-react-jsx'],
},
},
exclude: /(node_modules)/,
},
jsx 함수 생성
jsx 함수를 만들어야 한다. 일단은 기본적으로 {type, props, children}을 리턴하면 된다. 리액트 코드를 바벨로 변환해본적이 있다면 쉽게 알 수 있다. 참고로 type은 htmlelement이고(button, div) props는 리액트에서 하위 컴포넌트에 넘겨주는 props 또는 attribute를 생각하면 된다. 그리고 children에는 jsx배열 혹은 any 배열(string, boolean, number 모두 가능)이 들어가게 된다.
조금더 생각해보자. 리액트에서는 문자열이 false나 undefined인 경우 문자열로 반환하지 않는다. 또한 props가 false거나 undefined이면 props를 제거한다. 지금 말한것을 바탕으로 코드를 짜면 다음과 같다.
/* eslint-disable no-param-reassign */
type TState = Record<string, any>;
export interface IJsx {
type: string;
props: TState;
children: any[] | IJsx[];
}
function jsx(type: string, props: TState, ...children: any[] | IJsx[]): IJsx {
const nextChildren: IJsx[] = [];
children.forEach((child) => {
if (child !== false && child !== undefined) nextChildren.push(child);
});
if (props) {
Object.keys(props).forEach((key) => {
if (props[key] === false || props[key] === undefined) delete props[key];
});
}
return { type, props, children: nextChildren.flat() };
}
export default jsx;
jsx 글로벌 타입 설정
자바스크립트에서는 그냥 동작하지만 타입 스크립트에서 그냥 사용하려고 하면 타입 오류가 발생한다. 다음과 같이 타입 설정을 해줘야한다.
jsx.d.ts
declare module JSX {
type Element = string;
interface IntrinsicElements {
[elemName: string]: any;
}
}
tsconfing 설정
compilerOptions에 "jsx": "react"
를 추가해줘야한다.
실제 사용하기
세팅이 끝났다. 이제 사용하면 된다. 다음 코드를 입력하면 jsx를 사용할 수 있다. 린트를 사용하지 않는다면 린트 코드는 지우면 된다.
/** @jsx jsx */
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import jsx from '@/core/jsx';
추가로 하고 싶은말
vscode의 es6-string-html 플러그인을 설치하면 string 코드를 html 코드처럼 보이게 만들 수 있다. 이렇게 사용하는게 훨씬 편하다. 사서 고생하고 싶은 나같은 사람만 시도해보길... 이걸로 인해서 조금 다른 문제점들이 생긴다. 그건 다음글에서....
'자바스크립트 > 자바스크립트 라이브러리' 카테고리의 다른 글
바닐라자바스크립트(ts)에서 컴포넌트 만들기1(diff 알고리즘) (0) | 2022.02.16 |
---|