사람들이 Vue3 에 화난 이유

업데이트: Link

사람들이 Vue 3 에 화난 이유

Written by Alex Kyriakidis

월요일(2019년 6월 22일)에 일어나서 Vue 3의 새로운 기능에 대해 트윗하는 수많은 사람들을 보았습니다! Vue의 창시자인 Evan You의 이 트윗을 보고 흥분됩니다.

twitter-vue3-vues-darkest-day

Vue의 가장 어두운 날? 재미있는 기사 같네요. 👀 링크를 열고 놀랍게도 이것이 농담이 아니라는 것을 깨달았습니다. Vue 커뮤니티는 이 _새로운 기능_에 대해 정말 화난 것 같습니다. Reddit과 HackerNews의 모든 사람들은 Vue가 복잡해지고, 나빠지거나, 심지어 비개발자에게 친숙해지는 것에 대해 씁니다.

나는 한 번에 놀랐습니다! 주말에 오프라인이었는데 이제 Vue가 갑자기 복잡해 졌나요? 😳

Function-based Component API RFC를 읽기 위해 컴퓨터로 달려갑니다. 가장 먼저 주목해야 할 것은 작성 당시 약 5:1의 긍정적/부정적 반응의 엄청난 비율입니다.

Function-based Component API RFC comments

그러나 그것은 의미가 없습니다. 어두운 날이 아닐 수 없습니다. 하지만 실제로 무엇이 달라지나요? 많은 사람들이 이야기하는 이 Function-based Component API는 무엇입니까?

첫 번째 코드 블록을 보면 잠시 마음이 멈춥니다.

<template>
  <div>
    <span>count is 8</span>
    <span>plusOne is </span>
    <button @click="increment">count++</button>
  </div>
</template>

<script>
  import { value, computed, watch, onMounted } from 'vue'

  export default {
    setup() {
      // reactive state
      const count = value(0)
      // computed state
      const plusOne = computed(() => count.value + 1)
      // method
      const increment = () => { count.value++ }
      // watch
      watch(() => count.value * 2, val => {
        console.log(`count * 2 is ${val}`)
      })
      // lifecycle
      onMounted(() => {
        console.log(`mounted`)
      })
      // expose bindings on render context
      return {
        count,
        plusOne,
        increment
      }
    }
  }
</script>

무슨 일이 생긴거죠? data는 어디에 정의되어 있나요?computed가 왜 function이 된거죠?

커피한잔 하면서 마음을 진정시켜 봅니다.

thinks-with-coffe

나는 컴퓨터로 돌아가서 이번에는 RFC의 렌더링된 버전 을 계속 읽습니다. 따라서 모든 것이 setup 기능에 있으며 바닐라 자바스크립트 애플리케이션을 작성하는 것과 같이 모든 항목(데이터, 메서드, 생명 주기 후크 등)을 순서에 관계없이 작성할 수 있습니다. 이것은 다소 혼란스러워 보이지만 유연성이 미친 것처럼 들립니다. 최대한 빨리 맛을 보기 위해 RFC 하단의 2.x API 코드 예제와 비교로 이동합니다.

Prop을 기반으로 데이터 가져오기

Standard API

<template>
    <div>
        <template v-if="isLoading">Loading...</template>
        <template v-else>
            <h3></h3>
            <p></p>
        </template>
    </div>
</template>

<script>
    import { fetchPost } from './api'

    export default {
      props: {
        id: Number
      },
      data() {
        return {
          isLoading: true,
          post: null
        }
      },
      mounted() {
        this.fetchPost()
      },
      watch: {
        id: 'fetchPost'
      },
      methods: {
        async fetchPost() {
          this.isLoading = true
          this.post = await fetchPost(this.id)
          this.isLoading = false
        }
      }
    }
</script>

Functions API

<template>
  <div>
    <template v-if="isLoading">Loading...</template>
    <template v-else>
      <h3></h3>
      <p></p>
    </template>
  </div>
</template>

<script>
import { value, watch } from 'vue'
import { fetchPost } from './api'

export default {
  setup(props) {
    const isLoading = value(true)
    const post = value(null)

    watch(() => props.id, async (id) => {
      isLoading.value = true
      post.value = await fetchPost(id)
      isLoading.value = false
    })

    return {
      isLoading,
      post
    }
  }
}
</script>

여기서 첫 번째 놀라움은 코드의 길이입니다. 나는 분명히 함수 기반 API가 기존의 Object API보다 더 많은 라인을 제공할 것으로 기대합니다. 객체 기반 40 대 기능 기반 32. 👌 여기의 두 가지 예는 게시물의 id를 소품으로 받아들이는 구성 요소의 기능을 구현하고 id가 변경되면 게시물을 가져옵니다.

무슨 일이 일어나고 있는지 진정으로 깨닫기 위해 setup 메소드를 분해하고 싶습니다. 따라서 함수 기반 컴포넌트 API에서 setup 메소드는 prop을 인수로 가져오고 vue에서 가져온 이 value 함수를 사용하여 데이터를 정의합니다.

import { value, watch } from 'vue'
import { fetchPost } from './api'

export default {
  setup(props) {
    const isLoading = value(true)
    const post = value(null)
        //....
    }
}

그런 다음 props.id의 변경 사항을 수신 대기하는 이 펑키한 watch 함수 호출이 있으며 id가 변경될 때마다 AJAX 호출을 수행합니다.

watch(() => props.id, async (id) => {
  isLoading.value = true
  post.value = await fetchPost(id)
  isLoading.value = false
})

마지막으로 setupdata 메서드와 마찬가지로 구성 요소의 반응 상태를 가진 객체를 반환합니다.

export default {
  setup(props) {
    const isLoading = value(true)
    const post = value(null)

    watch(() => props.id, async (id) => {
      isLoading.value = true
      post.value = await fetchPost(id)
      isLoading.value = false
    })

    return {
      isLoading,
      post
    }
  }
}

나쁘지 않죠? Motivation 섹션에 도달하기 위해 계속 읽습니다. 여기에 구성 요소를 기능으로 나누는 이 아름다운 예가 있습니다.

function useMouse() {
  const x = value(0)
  const y = value(0)
  const update = e => {
    x.value = e.pageX
    y.value = e.pageY
  }
  onMounted(() => {
    window.addEventListener('mousemove', update)
  })
  onUnmounted(() => {
    window.removeEventListener('mousemove', update)
  })
  return { x, y }
}

// in consuming component
const Component = {
  setup() {
    const { x, y } = useMouse()
    const { z } = useOtherLogic()
    return { x, y, z }
  },
  template: <div>  </div>
}

Oh my god! 이 시점에서 Function-based Component API가 천재 임을 깨달았습니다. 따라서 더 이상 엄청나게 긴 코드 구성 요소가 없습니다.

진실은 큰 응용 프로그램의 구성 요소가 정말 이상해질 수 있다는 것입니다. 저는 대규모 프로젝트에서 여러 팀과 함께 작업했으며 개체 API의 구성 요소 길이가 많은 사람들에게 문제가 되는 부분이라고 말해야 합니다. 나는 1000줄로 구성된 잘 쓰여진 components를 보았습니다. 아무도 그것을 리팩토링하고 싶어하지 않습니다. 🙈

또한 함수 기반 API는 자연스럽게 유형 친화적입니다. 소식을 들을 때 기쁨의 눈물을 흘리는 Typescript 사용자를 많이 알고 있습니다.

사람의 생각

Vue 팀은 프레임워크를 유지 관리하고 개선하는 데 엄청난 시간을 할애하고 있으며 제안서를 읽지 않고 여러 번 커뮤니티가 화를 내는 것을 보니 안타깝습니다. Reddit과 HN의 사람들은 때때로 독이 될 수 있지만 이것은 주제에 대한 교육 없이는 의견을 형성해서는 안됩니다.

인터넷과 TV에서 접하는 뉴스와 똑같습니다. 얼마나 자주 정확하거나 사실입니까? 알아내기 위해서는 조사를 해야 합니다.

대부분 정신 건강을 유지하기 위한 나의 권장 사항은 소프트웨어나 프레임워크를 악화시키는 것을 원하지 않는 사람이 없기 때문에 이러한 종류의 소식을 긍정적인 방식으로 받아들이는 것입니다. Vue 팀은 매일 연구하고, 새로운 전략을 개발하고, 새 문서를 작성하거나, “싫어 싫어 싫단말야”를 작성하지 않고도 Vue 2 API를 영원히 쉽게 고수할 수 있습니다. 일어나는 일은 처음에는 명확하지 않더라도 자신의 이익을 위한 것입니다.

무엇을 선호하시겠습니까? 팀이 제한적이라고 생각하는 API를 고수하고 Vue가 충분히 유연하지 않기 때문에 Facebook과 같은 다음 10억 달러 기업이 다른 프레임워크를 선택하는 것을 보고 있습니까?

RFC는 모두를 위한 것입니다

Vue.js는 오픈 소스 프로젝트입니다. 미래의 기능 및 변경 사항에 대한 토론에 참여하는 모든 사람을 환영하며 실제로 권장합니다. 따라서 이러한 토론을 RFC - 의견 요청이라고 합니다.

Function-based Component API에 대해 어떻게 생각하시는지 궁금합니다. 처음 들었을 땐 겁이 났지만 읽으면 읽을수록, 가지고 놀수록 들뜨게 되었어요. 마음에 드시면 RFC로 이동하고 👍를 눌러 팀과 다른 사람들이 커뮤니티의 생각을 알 수 있도록 하세요!

좋아요를 누르지 않아도 괜찮아요. 🙂 제안서를 읽고 의견을 주의 깊게 검토하여 다른 사람들이 말하는 내용을 확인하고 포함되지 않은 경우 우려 사항에 대해 의견을 남깁니다. Vue 팀은 피드백을 받고 Vue 개발자와 논의하게 되어 기쁩니다.

이것은 고정되어 있지 않습니다 🧗‍♀️

이것은 RFC(Request for Comments)입니다. 이 pull 요청이 아직 열려 있는 한 이것은 피드백을 요청하기 위한 제안일 뿐입니다. 의견을 제시할 것을 권장하지만, 임의의 Reddit/HN 스레드에서 얻은 정보가 불완전하거나 오래되었거나 완전히 오해의 소지가 있을 수 있으므로 댓글을 작성하기 전에 RFC 자체를 실제로 읽어보십시오.

마무리

기록을 위해 Object API는 사랑스러워서 왜 그렇게 많은 사람들이 화를 냈는지 알 수 있습니다. 그러나 주목해야 할 또 다른 사실은 많은 사람들이 전체 RFC를 읽거나 reddit의 헤드라인을 훑어보지 않고 Twitter에서 외치거나 GitHub에서 트롤하기에 충분하다는 것입니다. RFC에 따르면 개체 기반 API는 계속 존재합니다.

개인적으로 함수 기반 API가 완성되어 출시되고 모든 가능성이 실행되기를 기다릴 수 없습니다. 내가 컨설팅하는 모든 팀이 이 새로운 초강대국을 손에 들고 기뻐할 것이라고 확신합니다. 🦹‍♀️

댓글남기기