흔히 프론트엔드 프레임워크(+ 라이브러리) 3대장으로 일컫어지는 것들이 있죠. 프론트엔드 생태계에 큰 관심은 없더라도 한 번쯤은 들어봤을 이름들인데요, 바로 Angular, React, 그리고 Vue 입니다. 저는 Vue를 주력으로 사용하고 있고, React와 Angular를 겉핥기 수준으로 하는 정도입니다.
그러다가 작년 쯤에 프론트엔드 프레임워크 트렌드를 살펴보다가 낮선 이름을 발견하게 되었습니다. Svelte(스벨트)라고 불리는 프레임워크였습니다. 실질적인 첫 릴리즈는 2016년이지만, 2019년에 통계에 처음 등장했음에도 불구하고 인지도나 만족도 면에서 Vue를 제쳤다는 통계를 보니 어떤 이유에서 그런 건지 궁금하더군요.
그래서 언제 한 번 공부해봐야겠다는 생각을 갖고 있었지만, 행동력의 부족으로 미루고 또 미루다가(…) 오늘 이렇게 포스트를 작성해봅니다. 기존에 프론트엔드 프레임워크를 공부해봤던 분들이시라면 아주 쉽게 이해하실 수 있을 것 같습니다. 저는 로컬에 이것저것 개발 환경 세팅을 하고 개발을 시작하느라 이틀 정도 걸렸던 것 같습니다.
이번 포스트를 통해 Svelte 프레임워크 또는 Rollup 자바스크립트 번들러에 관심을 갖고 계신 분들께 도움이 되길 바랍니다.
Svelte란
Svelte, 스벨트는 스스로를 진보적인 웹앱 프레임워크라고 소개합니다. Svelte의 특징을 몇 가지 꼽아보자면…
- 훨씬 적은 양의 코드
- 가상 DOM을 사용하지 않음
- 변경된 값이 자동으로 DOM에 반영되는 반응성
- 빌드 타임에 순수 자바스크립트로 컴파일됨
이런 특징으로 인해 컴파일된 결과물의 크기가 Vue나 React로 만들어진 어플리케이션에 비해 작다는 특징을 갖고 있습니다. 또한 후발 주자인 만큼 공식 홈페이지에 튜토리얼과 문서가 매우 친절하고 자세하게 적혀져 있습니다. 문법과 예제 코드 등을 확인할 수 있으니 관심 가시는 분은 확인해보셔도 좋을 것 같아요.
개발 환경 세팅
자, 그럼 이제 본격적으로 로컬 컴퓨터에서 개발할 수 있도록 환경을 세팅해보도록 하겠습니다.
Svelte에도 공식 CLI가 있긴 했는데 지금은 더 이상 사용하지 않습니다. 그래서 공식 홈페이지에서도 예시로 주어진 템플릿 코드를 클론하여 사용하라고 설명하고 있습니다.
npx degit sveltejs/template my-svelte-project
# or download and extract
cd my-svelte-project
npm install
# or yarn
npm run dev
# or yarn dev
이렇게 하면 아래 사진처럼 localhost:5000
에 Svelte 앱이 열리게 됩니다.
첫 시작이 너무나도 쉽게 끝났습니다.
구조 살펴보기
파일 구조를 살펴보면 아래와 같습니다.
.
├── README.md
├── package.json
├── public
│ ├── build
│ │ ├── bundle.css
│ │ ├── bundle.css.map
│ │ ├── bundle.js
│ │ └── bundle.js.map
│ ├── favicon.png
│ ├── global.css
│ └── index.html
├── rollup.config.js
├── src
│ ├── App.svelte
│ └── main.js
└── yarn.lock
구조는 정말 심플하기 그지 없습니다. /src
디렉토리에서는 사용자 정의의 컴포넌트와 기본 프로젝트 세팅을 관리하고 있죠. /public
안에 index.html
가 이 웹앱의 진입점이 될 테고, 해당 HTML 파일은 /build
디렉토리 내에 빌드 & 번들링된 스크립트와 스타일링 파일을 참조하고 있죠.
조금 특이한 점이 있다면 기본 예시로 제공되는 템플릿에서 기본 자바스크립트 번들러로 웹팩을 쓰는 것이 아니라 Rollup이라는 라이브러리를 쓰고 있다는 점입니다. 웹팩과 역할은 비슷하지만 성능 상에서 조금 차이가 있다고 하더군요. 각각의 장단점을 비교해 놓은 좋은 글이 있으니 궁금하다면 저 글을 참고하시면 될 거 같습니다. 물론 웹팩을 이용한 템플릿도 존재하니 필요에 따라 취사 선택하면 될 것 같습니다.
<script>
// 스크립트
</script>
<style>
/* 스타일 */
</style>
<!-- 마크업 -->
<main>
<h1>Hello World!</h1>
</main>
그리고 Svelte의 기본 파일은 .svelte
확장자를 가지는데, 마치 Vue 처럼 하나의 파일 안에서 템플릿과 스타일, 스크립트를 컴포넌트 단위로 작성할 수 있습니다. 정해진 순서는 없지만, 조금 있다 살펴볼 Prettier에서 순서를 커스터마이징할 수 있습니다.
또한 style
태그는 기본적으로 scoped
옵션을 갖습니다. 즉, 특정 컴포넌트 내에 있는 스타일은 다른 컴포넌트에 영향을 끼치지 않는다는 이야기죠.
여기까지가 Svelte 파일에 대한 간략한 소개였습니다. 지금부터는 생산성 향상을 위해 프로젝트에 몇 가지 도구를 추가적으로 설치해 볼 예정입니다.
전처리기 설정
우선 기본 CSS만으로는 스타일링이나 최적화가 쉽지 않으니, CSS 전처리기인 SCSS를 이용해보도록 하겠습니다. svelte-preprocess는 이런 Svelte 앱에서 PostCSS, SCSS, Less, Stylus, CoffeeScript, TypeScript, Pug 같은 전처리가 필요한 디펜던시의 컴파일을 지원하는 모듈입니다.
npm i node-sass svelte-preprocess
# or yarn add node-sass svelte-preprocess -D
그 후 rollup.config.js
파일에 플러그인 옵션을 추가해줍니다.
// rollup.config.js
import autoPreprocess from 'svelte-preprocess';
export default {
// ...
plugins: [
svelte({
// ...
preprocess: autoPreprocess(),
}),
],
};
그러면 간단하게 SCSS 설정을 완료할 수 있습니다.
<style lang="scss">
main {
text-align: center;
& > h1 {
color: #ff3e00;
}
}
</style>
Prettier
Svelte 코드 컨벤션을 지키기 위해 Prettier를 적용해보고자 합니다. prettier-plugin-svelte를 디펜던시로 받아줍니다.
npm i --save-dev prettier-plugin-svelte prettier
# or yarn add prettier-plugin-svelte prettier -D
그 후 *.svelte
확장자 파일에서 저장을 하게 되면 자동으로 코드 컨벤션이 맞춰지는 것을 확인하실 수 있습니다.
Prettier에도 기본 설정이 있는데, 프로젝트의 루트 디렉토리에 .prettierrc
파일을 생성해서 설정을 변경할 수 있습니다.
{
"svelteSortOrder": "scripts-styles-markup",
"svelteStrictMode": true,
"svelteBracketNewLine": true,
"svelteAllowShorthand": false
// ... 기타 커스텀 옵션
}
Babel
개발 시에 옵셔널 체이닝(Optional Chaining)과 같은 JavaScript 최신 문법을 사용하면서도 빌드된 결과물을 구형 브라우저에서도 호환되게 보여주기 위해서는 Babel 설정이 필요합니다.
npm i --save-dev @babel/core @babel/preset-env @babel/plugin-proposal-optional-chaining
# or yarn add @babel/core @babel/preset-env @babel/plugin-proposal-optional-chaining -D
Babel 설정은 아까 SCSS를 설정했던 것처럼, rollup.config.js
에 있는 autoPreprocess
의 설정으로 관리할 수 있습니다.
// rollup.config.js
import autoPreprocess from 'svelte-preprocess';
export default {
// ...
plugins: [
svelte({
// ...
preprocess: autoPreprocess({
babel: {
presets: [
[
'@babel/preset-env',
{
loose: true,
modules: false,
targets: {
esmodules: true,
},
},
],
],
},
plugins: ['@babel/plugin-proposal-optional-chaining'],
}),
}),
],
// ...
};
이렇게 하면 .svelte
코드 내에서도 옵셔널 체이닝을 사용할 수 있습니다.
VSCode Extension
그리고 VSCode에서 코드 에디터의 도움을 받을 수 있게 도와주는 확장 프로그램도 설치해줍니다.
저는 첫 번째 것(Svelte
)을 썼는데 두 번째 것(Svelte Beta
)이 더 최신 버전의 확장프로그램입니다.
Svelte Devtools
Svelte 개발자 도구 크롬 확장프로그램
Vue나 React처럼 Svelte 역시 브라우저 확장 프로그램으로 개발자 도구를 지원합니다. 이 개발자 도구를 이용해 브라우저 단에서 컴포넌트간의 계층 관계와 데이터 등을 쉽게 파악할 수 있습니다.
CSS 프레임워크
사실 요 정도면 기초적인 환경 세팅은 끝났습니다. 하지만 본격적인 시작에 앞서 스타일링 작업을 신경쓰지 않을 수가 없겠죠. 그래서 레퍼런스를 찾아보다가 Bulma 라는 CSS 프레임워크를 사용하기로 했습니다.
npm install bulma
# or yarn add bulma
하지만 Rollup은 자바스크립트 번들러이기 때문에 CSS 파일을 직접 로드할 수는 없습니다. 때문에 Rollup 에서 CSS 파일을 읽을 수 있게 해 주는 플러그인인 rollup-plugin-postcss를 설치해야 합니다.
npm install rollup-plugin-postcss -D
# or yarn add rollup-plugin-postcss -D
그 후 rollup.config.js
파일에 플러그인 옵션을 추가해줍니다.
// rollup.config.js
import postcss from 'rollup-plugin-postcss';
export default {
// ...
plugins: [
// ...
postcss(),
],
};
이렇게 하면 스크립트 태그 내에서 CSS 파일을 읽을 수 있습니다. 우리는 프레임워크를 활용하는 경우이므로 /src/main.js
에서 Bulma CSS 전체를 직접 임포트 하면 됩니다.
import App from './App.svelte';
import 'bulma/css/bulma.css';
CSS 파일이 잘 로드되는지 확인해봐야겠죠? 우선 Bulma 의 예제 문서에 적혀있는대로 App.svelte
파일의 템플릿 부분을 수정해봅니다.
<section class="hero is-primary is-fullheight">
<div class="hero-body">
<div class="container">
<h1 class="title">Hello {name}!</h1>
<h2 class="subtitle">
Visit the
<a href="https://svelte.dev/tutorial">Svelte tutorial</a>
to learn how to build Svelte apps.
</h2>
</div>
</div>
</section>
다행히도 잘 되는 듯 합니다. 이제 환경 준비는 마무리가 되었으니, 다음 편에서 본격적으로 Todo List를 만들어보도록 하겠습니다.