JSX를 사용하면 반응이 필요 없어요.


이 문서에서 우리는 새로운 JSX 변환과 React 없이 JSX를 어떻게 사용하는지 설명할 것이다.
공식 React 블로그는 업데이트가 많지 않기 때문에 새로운 게시물은 항상 주목할 만하지만 이번 주 게시물Introducing the New JSX Transform은 겉으로 보기보다 훨씬 클 것이다.
이 글은 새로운 JSX 변환을 발표했는데, 그 장점 중 하나는 "React를 가져오지 않고 JSX를 사용할 수 있다"는 것이다.
모르는 사람에게 JSX는 React 구성 요소가 브라우저에 나타날 때 사용하는 HTML과 유사한 문법입니다.
import React from 'react';
function MyComponent() {
  return <div>This is JSX</div>;
}
JSX를 사용할 때 컴파일러는 브라우저가 이해할 수 있는 React 함수 호출로 변환하여 다음과 같은 코드가 됩니다.
import React from 'react';
function MyComponent() {
  return React.createElement('div', null, 'This is JSX');
}
이것은 @babel/plugin-transform-react-jsx라는 바베타 플러그인을 통해 이루어진 것이다.
지금 주의하세요import React from 'react';.이 줄은 플러그인이 삽입된 것이 아니라, React 구성 요소에서 복사된 것입니다. 이것은 JSX를 포함하는 모든 파일에 React가 필요한 이유입니다.원본 파일에 React 패키지에 대한 인용이 없어도 전송 결과에 React가 필요한 이유입니다.
하지만 v7부터.JSX transform 플러그인은 다음을 출력하는 자동화라는 새로운 모드를 제공합니다.
// Inserted by a compiler (don't import it yourself!)
import {jsx as _jsx} from 'react/jsx-runtime';

function MyComponent() {
  return _jsx('div', { children: 'This is JSX' });
}
즉, JSX를 사용하는 파일에서 React를 가져올 필요가 없습니다. 가져오기는 컴파일러가 삽입하기 때문에 이제 구성 요소를 이렇게 작성할 수 있습니다.
function MyComponent(){
  return <div>This is JSX</div>;
}
그 자체로 편리하지만 나를 놀라게 한 이유는 아니다.만약 우리가 공고에서 좀 더 깊이 파고들면 우리는 다음과 같은 것을 발견할 수 있을 것이다.
|JSX를 React 이외의 라이브러리와 함께 사용하면 importSource 옵션을 사용하여 라이브러리에서 가져올 수 있습니다
그래서... 이게 바로 우리가 해야 할 일이야!
JSX를 포함하는 파일을 작성하고, 실행 중인 파일을 작성할 때, 노드 프로그램에서 HTML로 변환합니다.React와 브라우저가 없는 JSX!
우선 프로젝트를 초기화하려면 의존항이 필요합니다.Babel과 플러그인 변환으로 jsx는 파일을 컴파일할 수 있고 esm는 문장을 가져오거나 내보낼 수 있습니다. 물론 jsdom는 노드에서 HTML을 생성할 수 있습니다.
우리가 어떻게 가져오지 않는지 주의해라.
$ npm init -y
$ npm install @babel/cli @babel/core @babel/plugin-transform-react-jsx esm jsdom
모든 버전이 정확한지 확인하기 위해서, 이것은 나의 소프트웨어 패키지입니다.json
"dependencies": {
    "@babel/cli": "^7.11.6",
    "@babel/core": "^7.11.6",
    "@babel/plugin-transform-react-jsx": "^7.10.4",
    "esm": "^3.2.25",
    "jsdom": "^16.4.0"
  }
다음은 바벨에게 어떻게 해야 하는지 알려주는 .babelrc 서류가 필요합니다.
이 블로그에서 우리는 새로운 자동 실행을 사용할 때와 importSource 옵션을 사용하여 우리의 실행을 지정할 때 두 가지 일을 해야 한다는 것을 안다.
// .babelrc
{
  "plugins": [
    [
      "@babel/plugin-transform-react-jsx",
      {
        "runtime": "automatic",
        "importSource": "../runtime"
      }
    ]
  ]
}
우리는 또한 몇 개의 디렉터리를 만들어야 한다. 하나는 우리의 원본 코드를 포함하고, 하나는 우리가 구축하고자 하는 운행을 포함할 때, 하나는 컴파일된 원본 코드를 포함한다.
$ mkdir src lib runtime
우리의 예시 응용 프로그램은 간단한 항목 목록이 될 것입니다.
// src/App.js
function List({ items }) {
  return (
    <ul>
      {items.map((item, i) => (
        <ListItem id={i}>
          <Anchor value={item} />
        </ListItem>
      ))}
    </ul>
  );
}
function ListItem({ children }) {
  return <li>{children}</li>;
}
function Anchor({ value }) {
  return <a href="#">{value}</a>;
}
function App() {
  return <List items={[1, 2, 3, 4, 5]} />;
}
export default App;
코드가 컴파일되면 실행할 수 있는 입구점이 필요합니다.일반 색인처럼.js는React 프로그램에서 사용자가 실행할 때 제공하는 렌더링 함수를 호출합니다. 이 함수는 두 개의 인자를 받아들이고, 맨 윗부분의 구성 요소와 프로그램이 렌더링하는 DOM 노드를 사용합니다.React 응용 프로그램에서 이 함수는 React dom 또는 React native에서 옵니다. 여기서 우리는 자신의 함수를 작성합니다.
// src/index.js
import { render } from "../runtime/jsx-runtime";
import App from "./App";
import { JSDOM } from "jsdom";
// our jsdom document
const dom = new JSDOM(`<!DOCTYPE html><body><div id='root'/></body>`);
const { document } = dom.window;
const rootElement = document.getElementById("root");
render(<App />, rootElement);
console.log(document.body.innerHTML);
npm 스크립트 두 개를 만듭니다. 하나는 코드를 구축하는 데 사용되고, 다른 하나는 실행 코드에 사용됩니다.
"scripts": {
    "build": "babel src -d lib",
    "start": "node -r esm lib"
  },
build 작업은 src의 모든 내용을 컴파일하여lib에서 출력하고 start 작업은lib 폴더의 컴파일 코드를 실행합니다.
실행할 때 코드를 작성하기 전에 코드를 만듭시다.말 그대로, 우리는 실행할 때 코드를 구축할 필요가 없고, 실행하기만 하면 된다.코드를 컴파일하기 위해서, 우리는 babel과 우리가 설정한 jsx 변환 플러그인을 사용합니다.babelrc 파일
$ npm run build
> babel src -d lib
Successfully compiled 2 files with Babel (239ms).
출력 파일의 한 부분을 살펴보겠습니다. 이것은 실행할 때 어떻게 호출하는지 알려 줍니다.
// lib/App.js
import { jsx as _jsx } from "../runtime/jsx-runtime";
function List({
  items
}) {
  return _jsx("ul", {
    children: items.map((item, i) => _jsx(ListItem, {
      id: i,
      children: _jsx(Anchor, {
        value: item
      })
    }))
  });
}
//...
function App() {
  return _jsx(List, {
    items: [1, 2, 3, 4, 5]
  });
}
export default App;
우리는 운행할 때의 경로를 볼 수 있다.babelrc와 우리는 실행할 때 jsx가 실행될 때 모듈에서 jsx 함수를 내보내야 한다는 것을 보았다.그것은 문자열이나 다른 구성 요소 (함수) 의 노드와 도구 두 개의 인자가 필요합니다.
우리는 기사 Rodrigo Pombo 에서 작성한 코드를 대량으로 다시 사용해서 실행할 때 작성할 것입니다.
// runtime/jsx-runtime.js
function jsx(type, config) {
  if (typeof type === "function") {
    return type(config);
  }
const { children = [], ...props } = config;
  const childrenProps = [].concat(children);
  return {
    type,
    props: {
      ...props,
      children: childrenProps.map((child) =>
        typeof child === "object" ? child : createTextElement(child)
      ),
    },
  };
}
function createTextElement(text) {
  return {
    type: "TEXT_ELEMENT",
    props: {
      nodeValue: text,
      children: [],
    },
  };
}
나는 여기에서 상세하게 소개하지 않을 것이다. 모든 함수를 하나의 문자열 ("il", "ul"등) 으로 해석될 때까지, HTML Element을 구축하는 대상을 만들 수 있을 때까지 반복적으로 실행할 수 있을 뿐이다.
편집된 색인을 보면js, 최초의 렌더링 호출이 다음과 같이 변환된 것을 보았습니다.
// lib/index.js
render(_jsx(App, {}), rootElement);
이것이 바로 우리가 렌더링 함수를 어떻게 작성하는지입니다. 마찬가지로 “Build your own React” 의 문장 Rodrigo Pombo 을 수정합니다.우리는 렌더 함수가 우리가 방금 작성한 jsx 함수의 결과를 받아들이는 것을 안다.
// runtime/jsx-runtime.js
function render(element, container) {
  const dom =
    element.type === "TEXT_ELEMENT"
      ? container.ownerDocument.createTextNode("")
      : container.ownerDocument.createElement(element.type);
  const isProperty = (key) => key !== "children";
  Object.keys(element.props)
    .filter(isProperty)
    .forEach((name) => {
      dom[name] = element.props[name];
    });
  element.props.children.forEach((child) => render(child, dom));
  container.appendChild(dom);
}
export { jsx, render };
마찬가지로, 여기서 우리는 너무 많은 세부 사항을 토론하고 싶지 않다. 우리는 전송된 jsx 코드에서 생성된 구조를 반복적으로 훑어보고, jsdom를 사용하여 모든 요소를 HTMLElement으로 전환한다.
이제 코드를 실행할 때 실행 결과를 볼 수 있습니다.
$ npm start
> node -r esm lib
<div id="root"><ul><li><a href="#">1</a></li><li><a href="#">2</a></li><li><a href="#">3</a></li><li><a href="#">4</a></li><li><a href="#">5</a></li></ul></div>
이렇게!
지금 우리가 방금 한 일을 돌이켜 보자.
  • 우리는 JSX를 사용하여 예시 프로그램을 작성했는데 다른 가져오기 (src/app.js)가 없습니다.
  • babel을 새로운 자동 모드로 컴파일하는 프로그램으로 설정하고 사용자 정의 실행 시간을 지정합니다.
  • 전송을 실행하기 위한 사용자 정의 실행 코드를 작성하여 콘솔에서 HTML로 출력했습니다.
  • 이게 뭐 대단한 일이야?이것은 어쨌든 큰 변화는 아니지, 그렇지?
    JSX를 반응 없이 사용할 수 있다는 의미여서 큰일이다.이것은 이전에 이미 사실이었다. (Rodrigo Pombo는 그의 글에서 Didact라는 React 클론을 만들었고, Preact도 JSX를 사용했다.) 그러나 지금은 매우 쉬워졌다. 이것은 많은 문을 열었다.우리는 React 이외의 다른 프레임에서 JSX를 볼 수 있다. 이것은 JSX가 HTML 이외의 다른 것을 나타낼 수 있다는 것을 의미한다.실행 시 코드와 분리함으로써 우리는 서로 다른 실행 시 같은 JSX를 사용하여 서로 다른 목표를 실현할 수 있다.이전에, 우리는 구성 요소의 모든 가져오기를 준수해야 했다.
    나는 앞으로 몇 주와 몇 달 동안 이런 변화가 무엇을 가져올지 궁금했다.마찬가지로 이것은 거품이 아니다. 바베타와 React 뒤에 있는 사람들이 함께 일하면 자동 모드가 바베타 8의 기본 옵션이 된다.TypeScript 뒤에 있는 관리자, React 응용 프로그램을 만들고 다음 단계.js, 게이츠비, 에스린트와 플로우도 이러한 변화에 참여하고 받아들였으며 RFC 과정은 지역 사회에 대한 피드백이 개방적이다.
    읽어 주셔서 감사합니다. 댓글에 문제가 있으면 저에게 알려 주십시오.

    좋은 웹페이지 즐겨찾기