Web Component publish 공개 하기

2021.08.14 - [Web] - Web component (Custom Elements, Shadow DOM, Template)

2021.08.14 - [Web] - Web Components Callback Methods & lifecycle

앞서서 Web Component를 만드는 방법에 대해서 알아 보았다.

간단한 Web Component를 만들고 공개하는 방법에 대해서 알아보자.

 

Profile information Component Design

    <profile-info
      name="이름을 여기에"
      designation="호칭 또는 소속"
      id-number="소속 사번"
      picture-src="./icon.png"
      employee-type="ft"
    >
    </profile-info>

Component 명은 profile-info이고 이름, 소속, 사번, 이미지, 그리고 고용형태를 표현한다.

고용형태는 ft = fulltime, pt = parttime, ct ? 로 나누어서 색을 바꿈으로써 표현을 달리한다.

 

web component 개발

export default class ProfileInfo extends HTMLElement {
  constructor() {
    super();
    this.name = "";
    this.desination = "";
    this.idNumber = "";
    this.pictureSrc = "";
    this.employeeType = undefined;

    //for shadowing
    this.shadowObj = this.attachShadow({mode:'open'});
  }

  getTemplate() {
    return `
        <div class="profile-info__container">
            <img class="profile-info__picture"
            src="${this.getAttribute("picture-src")}" />
            <div class="profile-info__text">
                <div class="profile-info__name">
                ${this.getAttribute("name")}
                </div>
                <div class="profile-info__designation">
                ${this.getAttribute("designation")}
                </div>
                <div class="profile-info__id-number">
                ${this.getAttribute("id-number")}
                </div>
            </div>
        </div>
        ${this.getStyle()}
        `;
  }

  getStyle(){
      return `
    <style>
        :host {
        display : block;
        font-family: sans-serif;
        }

        :host(.profile-info__emp-type-ft){
        background-color: #7bb57b;
        }
        :host(.profile-info__emp-type-pt){
        background-color: #ffc107;
        }
        :host(.profile-info__emp-type-ct){
        background-color: #03a9f4;
        }
        .profile-info__container {
        display: flex;
        flex-direction: column;
        align-items: center;
        text-align: center;
        }

        .profile-info__picture {
        border-radius: 50%;
        width: 80vw;
        height: 80vw;
        margin: 10px auto;
        }

        .profile-info__text {
        padding: 10px;
        flex : 1;
        }

        .profile-info__name {
        font-size: 22px;
        }

        .profile-info__designation {
        font-size: 22px;
        margin-top: 10px;
        }

        .profile-info__id-number {
        margin-top: 10px;
        }

        @media screen and (min-width: 650px) {
            .profile-info__container {
                flex-direction: row;
                text-align: left;
            }

            .profile-info__picture {
                width: 100px;
                height: 100px;
                margin: 10px;
            }
        }
    </style>
      `;
  }

  render() {


    this.clearEmployeetype();

    this.classList.add(`profile-info__emp-type-${this.employeeType?? 'pt'}`);
    // this.innerHTML = this.getTemplate();
    //for shadowing
    this.shadowObj.innerHTML = this.getTemplate();
  }

  clearEmployeetype(){
      this.classList.remove('profile-info__emp-type-ft');
      this.classList.remove('profile-info__emp-type-pt');
      this.classList.remove('profile-info__emp-type-ct');
  }

  connectedCallback() {}

  disconnectedCallback() {}

  adoptedCallback() {}

  static get observedAttributes() {
    return ["name", "designation", "id-number", "picture-src", "employee-type"];
  }

  attributeChangedCallback(name, oldValue, newValue) {
    let key = name
      .split("-")
      .map((item) => item.charAt(0).toUpperCase() + item.slice(1))
      .join('');
    key = key.charAt(0).toLowerCase() + key.slice(1);

    this[key] = newValue;
    this.render();
  }
}

customElements.define("profile-info", ProfileInfo);

대부분 앞서 만든 컴포넌트를 비슷하게 만든 것이라서 특별할 것은 없는데, attributes 업데이트 부분만 조금 설명을 남긴다.

Attributes 업데이트

  static get observedAttributes() {
    return ["name", "designation", "id-number", "picture-src", "employee-type"];
  }

  attributeChangedCallback(name, oldValue, newValue) {
    let key = name
      .split("-")
      .map((item) => item.charAt(0).toUpperCase() + item.slice(1))
      .join('');
    key = key.charAt(0).toLowerCase() + key.slice(1);

    this[key] = newValue;
    this.render();
  }

name, designation, id-number 등은 attribute가 업데이트 되면 observedAttributes method에 의해서 자동으로 attributeChangedCallback을 부르게 되는데, 이때 들어온 'employee-type'과 같은 naming의 형태를 'employeeType'으로 형태를 바꾸어서 자동으로 attributes를 업데이트하고 render를 실행 시키는 코드이다.

 

ReadMe.md 작성하기

npm init을 해줄 root 폴더에 다음과 같이 Markdown을 만들어 주자.

```html
    <profile-info
      name="이름을 여기에"
      designation="호칭 또는 소속"
      id-number="소속 사번"
      picture-src="./icon.png"
      employee-type="ft"
    >
```

 

Npm 등록하기

https://www.webcomponents.org/ 에 컴포넌트 등록을 위해서는 npm에 우선 등록이 필요 하다.

javascript가 있는 곳에 npm을 init 해주자.

$ npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help init` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (webcomponents) profile-info
version: (1.0.0) 0.0.1
description: for studying
entry point: (CompanyHeader.js) ProfileInfo.js
test command:
git repository: (https://github.com/theyoung/webcomponents.git)
keywords: webcomponent
author: prateek jadhwani
license: (ISC)
About to write to C:\Users\home\Desktop\javascript\webcomponents\package.json:

 

npm publish를 진행하자. (npm adduser를 통해서 user 등록이 먼저 되어있어야 한다.)

https://www.npmjs.com/

$ npm publish
npm notice 
npm notice 📦  profile-info-study@0.0.2
npm notice === Tarball Contents ===
npm notice 2.0kB CompanyHeader.js
npm notice 2.7kB CompanyLogin.js
npm notice 1.3kB CustomButton.js
npm notice 902B  Helloworld.js
npm notice 555B  InformationBanner.js
npm notice 3.8kB ProfileInfo.js
npm notice 353B  ReadMe.md
npm notice 1.3kB StudentAttendanceTable.js
npm notice 517B  TimeSlot.js
npm notice 547B  chapter3.html
npm notice 1.0kB chapter4.html
npm notice 4.8kB icon.png
npm notice 883B  index.html
npm notice 1.3kB information.html
npm notice 530B  package.json
npm notice 335B  student.json
npm notice 2.1kB style.css
npm notice === Tarball Details ===
npm notice name:          profile-info-study
npm notice version:       0.0.2
npm notice filename:      profile-info-study-0.0.2.tgz
npm notice package size:  10.0 kB
npm notice unpacked size: 25.1 kB
npm notice shasum:        78f854171eae39af0708c6260312ba5bb8bee2bf
npm notice integrity:     sha512-C4L0mpp/ckN/F[...]sZz8kahfwJVsg==
npm notice total files:   17
npm notice
+ profile-info-study@0.0.2

 

이와 같이 publish가 완료되면 아래와 같이 npm에 등록 된 것을 확인 할 수 있다.

 

Web component 사이트에 등록

https://www.webcomponents.org/

로 이동해서 

publish element를 클릭한다.

scroll을 내려서 하기 화면에서

앞서 만든 npm 프로젝트 name을 넣고 publish를 진행하자.

드디어 첫번째 컴포넌트를 등록하였다.

 

자세한 개발 내용은 'Getting Started with Web Components' 책을 참조하자.

https://github.com/PacktPublishing/Getting-Started-with-Web-Components

2021.08.14 - [Web] - Web Components Slot 사용하기

 

Web Components Slot 사용하기

내가 만든 webcomponent 사이에, 사용자 html tag가 customizing 되어 적용되게 하는 방법을 알아보자. 앞서 작성한 html의 Component 사용 형상은 아래와 같은 형태였다. tag name이 있고 attributes가 있으면 해..

enumclass.tistory.com

 

728x90
반응형