[PRESET] preact + snowpack + typescript

제이밍·2021년 12월 13일
2
post-thumbnail

⛄️ snowpack

The faster frontend build tool

SnowpackWebpack처럼 복잡하고 무거운 빌드 시스템의 대안으로 만들어졌다.
기존의 Webpack, Rollup 그리고 Parcel 같은 무겁고 복잡한 번들러의 번들 소요 시간을 획기적으로 절약할 수 있습니다.

snowpack 특징

  • 번들 없는 개발(Unbundled Development)
  • 개별 파일을 브라우저에 전달하는 아이디어
  • 파일이 변경되면 해당 단일 파일만 다시 빌드
  • 같은 파일을 두번 이상 빌드하지 않음
  • 소스가 변경되어도 브라우저 새로고침이 필요하지 않음
  • Babel, Sass, MDX 등 기능 확장을 위한 빌드 플러그인을 지원

이외의 번들러들의 특징

  • Webpack, Rollup 같은 번들러들은 번들 개발(Bundled Development)에 중점을 둡니다.
    번들러로 애플리케이션을 실행하면 개발에 추가 작업과 복잡성이 발생합니다.

Snowpack 사용해서 React 구조 세팅 ⛄️

package download

$ npm init

$ npm i --save-dev snowpack

$ npm i react react-dom

snowpack 하나도 복잡한 웹팩 설정 플러그인 설치과정을 생략 할 수 있습니다

생략 가능 플로그인들...
$npm i -D babel-loader @babel/core @babel/preset-env
$npm i -D webpack webpack-cli webpack-dev-server
$npm i -D html-webpack-plugin ts-loader

복잡한 번들링 과정은 과감하게 생략!

react에 snowpack 적용하는법

  1. 폴더 구조 잡기

일반적으로 webpack으로 번들링 한다면 webpack.config, babelrc 등과 같은 설정 파일이 필요하겠지만
snowpack을 사용하면 모두 불필요 ⚔️

2. index.html 에 script 추가하기

//index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Snow pack demo</title>
</head>
<body>
  <div id="root"></div>
  // snowpack으로 인해 jsx -> js 로 컴파일될 index.js를 추가해줍니다.
  <script type=module src="./src/index.js"></script>
</body>
</html>

ESM을 사용하려면 script 요소에 type="module" 속성을 추가해야 한다. 그러면 인라인 스크립트 안에서도 import 구문을 쓸 수 있게 된다.

3. index.jsx 구조 맞추기

// index.jsx
import React from 'react';
import ReactDom from 'react-dom';
import { App } from './App'

ReactDom.render(<App />, document.getElementById('root'));

4. 마지막으로 스크립트에 snowpack dev 명령을 추가해 서버를 켜기

// package.json
  "scripts": {
    "start": "snowpack dev",
  },

(options) snowpack 환경설정

// snowpack.config.js
module.exports = {
  devOptions: {
    port: 8080, // 개발 서버를 실행할 포트 번호
    fallback: 'index.html', // SPA인 경우 제공할 모든 사용자 경로
    open: 'default', // 새 브라우저 탭에 개발 서버를 열기, "default" | "none" | "BROWSER_NAME"
    output: 'dashboard', // 콘솔의 출력 모드를 지정, "stream" | "dashbaord"
    hostname: 'localhost', // 브라우저가 열리는 호스트 이름
    hmr: true, // Hot Module Replacement(HMR, 수정사항을 즉시 반영) 활성화
    hmrErrorOverlay: true, // HMR 활성화시 자바스크립트 오류 표시 여부
    secure: false, // HTTP2 활성화 상태에서 HTTPS 사용 여부
    // out: 'build' // Deprecated! 
  },
    buildOptions: {
    out: 'build', // 최종 빌드를 출력하는 로컬 디렉토리 이름
    baseUrl: '/', // 제품 모드의 기본 URL 지정, 현재 앱이 하위 디렉토리로 배포되는 경우 유용
    clean: false, // 빌드 전 기존 데이터 제거
    metaDir: '__snowpack__', // HMR 및 ENV 등의 정보를 출력할 디렉토리 이름
    sourceMap: false, // 소스 맵 사용 여부
    webModulesUrl: 'web_modules' // 사용하는 웹 모듈이 저장될 디렉토리 이름
  }
}

📖 typescript 세팅

$ npm i -g typescript
$ tsc --init

preact를 적용하기 위해 typescript에 설정을 추가해줍니다.

//tsconfig.json
  "compilerOptions": {
    "jsx": "react",
    "jsxFactory": "h"
    ...
  }

⚡️ what is Preact

단 몇 초 만에 초고속 Preact PWA 구축을 시작할 수 있도록 도와줍니다.

최소한의 쉬운 프로젝트 구조로 프로젝트 초기세팅을 쉽고 즉시 실행 할 수 있게 해줍니다.
webpack, babel, terser등의 구성없이 핫 리로딩, CSS 인라이닝에 이르기까지 모든 것이 최적으로 설정 됩니다

preact를 사용하면 좋은점 ✏️

  • Light house score 100 지원!
  • routes에 대한 자동 코드 분할
  • 비동기로 모든 구성 요소를 투명하게 코드 분할, prefix!
  • 차등 자바스크립트 제공.
  • Workbox에서 제공하는 오프라인 캐싱을 위해 자동 생성된 서비스 워커.
  • 효율적 로딩을 위한 PRPL 패턴 지원.
  • 구성이 필요없는 사전 SSR rendering 지원.
  • CSS 모듈, LESS, SASS, Stylus 지원
  • 내장된 추적 기능으로 bundle/chunk 크기 모니터링
  • 자동 앱 마운팅, 디버그 도우미 및 핫 모듈 지원
  • 1.5kb 조건부로 로드된 폴리필

snowpack에 preact를 적용시키는 법

package download

"preact": "^10.6.4"
"wouter-preact": "^2.8.0-alpha.2"
// A tiny routing solution for modern React and Preact apps

// package.json
  "snowpack": {
    "webDependencies": [
      "preact",
      "preact/compat",
      "wouter-preact"
    ]
  }

import { render } from 'preact';

before

// index.jsx
import React from 'react';
import ReactDom from 'react-dom';
import { App } from './App'

ReactDom.render(<App />, document.getElementById('root')); 

after

// index.tsx
import { h, render } from 'preact';
import  { App } from './App'

const dom = document.getElementById('root') as Document | Element | ShadowRoot | DocumentFragment;
render(<App />, dom);

import { h } from 'preact'

before

// Component.jsx
import React from 'react';

after

// Component.tsx
import { h } from 'preact'

suspense 사용하기

import { h } from 'preact'
import { Link, Route } from 'wouter-preact'
import {Suspense, lazy} from 'preact/compat'

const sleep = (ms:number) => new Promise(resolve => setTimeout(resolve,ms));

const Account = lazy(async() => {
  await sleep(3000);
  return import("./Account");
})

const App = () => {
  return(
    <div>
      <ul>
        <li><Link href="/account">Account</Link></li>
      </ul>
      <Suspense fallback={'loading...'}>    
        <Route path="/account">
          <Account />
        </Route>
      </Suspense>
    </div>
  )
}

끝-

Reference

https://heropy.blog/2020/10/31/snowpack/
https://blog.rhostem.com/posts/2020-12-16-migration-from-cra-to-snowpack

profile
모르는것은 그때그때 기록하기

0개의 댓글