[go-app/WASM] #4. Vite 사용하기

2021. 11. 22. 00:01Challenge/Go

728x90

[go-app/WASM] #1

[go-app/WASM] #2

[go-app/WASM] #3

 

go-app은 Frontend framework 지만 sass를 지원하지는 않습니다.

CSS만으로도 충분히 웹을 꾸미고 디자인하는데 큰 지장은 없지만, 유연하고 생산성이 뛰어난 방향을 위해서는 SASS를 도입하는 것이 정신건강에 이롭습니다.

 

 

SASS를 사용하는 방법은 여러방법이 있지만 대표적으로는 Libsass 가 대표적인 진영입니다.

하지만 go언어에서의 sass 사용은 조금 이 뭐 병ㅅ...

 

 

파일 입출력을 통한 제공을 하는데, 너무 별로입니다. 바로 보자마자 제외 했습니다. 그럼에도 사용하고 싶다면 ...

go-libsass를 참고하세요.

 

 

그럼 libsass를 사용하지 않으려면 번들러를 이용한 방법이 주를 이룹니다.

왜냐하면... 클라이언트의 응답을 빨리 하기 위해서는, minify나 uglify, tree shaking 등이 필요로 하기 때문이죠.

또 entry 분리도있고요!

 

번들러는 유명한 것으로는 Webpack, Rollup, Parcel 등이 있습니다.

가장 많은 커뮤니티(자료)를 보유하고 있는 webpack은 저에게도 익숙하고 편리하지만, 손도 많이가고 퍼포먼스가 그렇게 좋은 녀석은 아닙니다. (빌드 할 때 CPU 단일 코어만 쓰는데 CPU 성능딸리면... 100%까지 가버리는 제 정신 아닌)

 

이 웹 시장에서는 제정신이 아닌게 많습니다. (사실 고언어도 2018년도에 vscode CPU 100% 버그가 있었습니다.)

 

 

 

그래서 생각한게 2021년 요즘 뜨고있고 강세를 보이고 있는 Vite를 사용할 생각입니다.

Vite의 특징은 한마디로 개 빠릅니다. 설정도 단순하고 rollupOptions를 이용해서 유연한 융통성을 지니고 있습니다.

번역된 한글 문서도 존재합니다.  https://vitejs-kr.github.io/

 

Vite

 

vitejs-kr.github.io

위 6개 내용만 들어도 벌써... 

 

 

 

 

Vite 시작하기

# npm init vite@latest <폴더 명>
cd client
npm init vite@latest vite

저는 client 폴더 하위에 'vite' 라고 생성하였습니다. 이미 vite 폴더가 존재하시는 분이라면, 영어로 너 이폴더에 파일있는데 다 없애버린다?! ㅋㅋ루컨마? 라고 하니깐 잘 보시고 판단해서 클라이언트 폴더명을 생성합니다.

client 폴더에다가 만든 이유는 3편까지 따라 오신분들이라면, client 폴더에 go-app의 라우팅이 포함되기 때문입니다.

그냥 클라이언트 거기다가 다 짱박아두려고... frontend 라고 하시는 분들도 있을듯

 

 

각자 기호에 따라 다르겠지만, 저는 오직 SASS만을 사용하기 위해 이녀석을 설치하였습니다.

그렇기 때문에, 선택사항에서는 VanillaJS(그냥 javascript) 로만 선택을 했습니다.

 

 

 

 

 

SASS 설치하기

가장 핵심인 sass를 사용하기 위해서는 sass를 설치하여야 합니다.

npm install -D sass

끝입니다. (?) ㄹㅇ입니다. webpack 찐따 쉐끼랑 다르게 이친구는 그냥깔기만 하면 돼요!

 

 

 

 

 

Vite 설정하기

1. 먼저 저의 기준으로 client/vite 폴더내에 vite.config.js를 생성합니다.

2. 저 처럼 sass만 사용할 것이라면 "main.js", "index.html", "favicon.ico" 파일을 과감하게 삭제합니다.

3. app.css 파일을 지우거나 파일명을 변경합니다. 저는 main.css 라고 하였습니다.

(app.css는 go-app이 필수로 넣어놔서 ㅂㄷ...)

// vite.config.js

import path from 'path'
import {defineConfig} from 'vite'

const webStylesDir = path.resolve(__dirname, '../../web/styles')
const styleDir = path.resolve(__dirname, 'styles')

export default defineConfig({
    resolve: {
        alias: {
            '@': styleDir,
        },
    },
    css: { preprocessorOptions: { scss: { charset: false } } },
    build: {
        emptyOutDir: true,
        outDir: webStylesDir,
        rollupOptions: {
            input: 'main.scss',
            output: {
                // https://rollupjs.org/guide/en/#outputassetfilenames
                assetFileNames: '[name][extname]'
            }
        },
    },
})

 

emptyOutDir true 이면 output되는 디렉터리를 싹다 지워버리고 output 해버립니다.

outDir는 go-app이 web 폴더를 무적권 사용하다보니 그냥 하위에 styles를 만들고 다 쑤셔넣었습니다 ㅎ.ㅎ

 

output에 assetFileNames는 JS와 CSS의 파일명을 지정합니다. webpack과 유사한데 특이한점은 extname을 작성할 때

파일명.확장자가 아니라 파일명확장자 이렇게 마침표가 "." 이 없습니다. 기본값은 hashname이 포함되어 있는데

저는 개발중에 chrome/whale 브라우저 상에서 캐시 사용 중지를 하기 때문에 필요 없습니다.

또한, 나중에 S3나 R2나 Google Cloud Storage 같은거 쓰시면 hash chunkname 때문에 덮어쓰기도 안되서 나중에 용량 드럽게 많이 쳐먹습니다.

아니 그러면 프로덕션 배포시에 스타일 바뀌면 어떡하나요?

-> go-app은 기본적으로 서비스워커와 PWA가 붙어있으니 그냥 워커에서 변경사항 전파 받게 만들고 그 상태에서 날리고 새로 받아오세요!

 

 

 

 

 

 

Vite Watcher 실행하기

Webpack과 마찬가지로 JS나 CSS의 변경사항이 생길 때마다 매번 개귀찮게 build를 해줄 수 없으니

watch라는 옵션을 통해 바로바로 적용해서 서버에서 새로고침으로 즉각 확인할 수 있어야 합니다.

가뜩이나 WASM이라서 개발도 힘든데 이거라도 해야죠...

 

// client/vite/package.json
{
  "name": "vite",
  "version": "0.0.0",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "serve": "vite preview",
    "watch": "vite build --watch"
  },
  "devDependencies": {
    "sass": "^1.43.4",
    "vite": "^2.6.4"
  }
}

scripts에 watch 명령을 추가해주었습니다.

이제 npm run watch를 하면 실시간으로 감지를 시작하고 SCSS를 싸재껴도 바로바로 web/styles/main.css 로 만들어줍니다.

 

 

 

 

 

서버 라우팅 핸들러에 CSS 적용하기

// server.go

package main

import (
	"fmt"
        "<repository>/client"
	"github.com/gofiber/fiber/v2"
	"github.com/gofiber/fiber/v2/middleware/cors"
	"log"
)

func main()  {
	server := fiber.New()
        client.SetupClientRoute()
        indexHandler := &app.Handler{
		Name:        "Main Page",
		Title:       "테스트",
		Description: "An Hello World! example",
                Styles: []string{
			"/web/styles/main.css",
		},
	}

	GoAppServeHTTP(server, indexHandler)
        server.Get("/", adaptor.HTTPHandler(indexHandler))

	fmt.Println("Server Start 🚀 :3333")
	if err := server.Listen(":3333"); err != nil {
		log.Fatalln("서버 실행 도중 오류가 발생하였습니다.")
	}
}

indexHandler에 Styles 키를 추가하여 main.css를 가져옵니다.

왜 scss가 아니고 css냐고 물어보신다면.... scss는 전처리기 이므로, 결과물이 CSS로 출력되어야합니다.

vite는 개 똑똑하고 개 사기라서, 뭐 세팅 해준것도 없는데 처음부터 minify 해줍니다.

 

 

 

 

번외. Vite Entry Point 여러개 사용하기

// vite.config.js

import path from 'path'
import {defineConfig} from 'vite'

const webStylesDir = path.resolve(__dirname, '../../web/styles')
const styleDir = path.resolve(__dirname, 'styles')

export default defineConfig({
    resolve: {
        alias: {
            '@': styleDir,
        },
    },
    css: { preprocessorOptions: { scss: { charset: false } } },
    build: {
        emptyOutDir: true,
        outDir: webStylesDir,
        rollupOptions: {
            input: ['main.scss', 'pages/index.scss'],
            output: {
                // https://rollupjs.org/guide/en/#outputassetfilenames
                assetFileNames: '[name][extname]'
            }
        },
    },
})

위 처럼 배열로 하면 먹힙니다. 개꿀입니다

 

 

 

Webpack과 마찬가지로 아래와 같이 key:value 형태로도 가능합니다.

// vite.config.js

import path from 'path'
import {defineConfig} from 'vite'

const webStylesDir = path.resolve(__dirname, '../../web/styles')
const styleDir = path.resolve(__dirname, 'styles')

export default defineConfig({
    resolve: {
        alias: {
            '@': styleDir,
        },
    },
    css: { preprocessorOptions: { scss: { charset: false } } },
    build: {
        emptyOutDir: true,
        outDir: webStylesDir,
        rollupOptions: {
            input: {
              main: 'main.scss',
            },
            output: {
                // https://rollupjs.org/guide/en/#outputassetfilenames
                assetFileNames: '[name][extname]'
            }
        },
    },
})
728x90