vue-cli로 구성된 프로젝트를 vite 환경으로 옮기는 작업이다.
Vite는 EOL(End-of-life)에 도달한 Node v12를 더이상 지원하지 않는다. Node 버전 14.18+
이상을 사용해야한다. node v14의 마지막 버전은 14.19.3 이므로 이 버전을 사용하기로 생각했다. 기존 프로젝트들이 node v12를 사용하는 경우도 존재하므로, nvm을 사용하여 다중 노드 환경을 구성해준다.
프로덕션 버전으로 빌드 및 번들링 시 소스코드가 최신 JS를 지원하는 환경에서 동작한다고 가정하고 진행된다. 기본적으로 Vite는 Native ES Module, Native ESM의 동적 Import, import.meta를 지원하는 브라우저를 대상으로 하고 있다.
Chrome >= 87
Firefox >= 78
Safari >= 13
Edge >= 88
npm create vite@latest
npm install
npm run dev
정상적으로 프로젝트가 돌아가는 것을 확인한다.
package.json 파일에 필요한 라이브러리를 설치/삭제한다.
우선 폴더를 그대로 복붙한다. src/App.vue, src/main.ts 파일 내용도 복붙한다.
vite.config.js
파일에 세팅해준다.import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
resolve: {
alias: [
{ find: '@', replacement: '/src' },
]
},
plugins: [vue()]
})
구글링하면 path를 사용해 path.resolve로 alias를 추가하는 방법이 많이 나온다. 하지만 기본적으로 위 코드처럼 alias를 지원해주기 때문에 불필요하게 path 라이브러리가 없어도 된다.
tsconfig.json
파일에 다음과 같이 추가한다.baseUrl, paths 옵션을 추가한다.
{
"compilerOptions": {
// ...
"baseUrl": ".",
"paths": {
"@/*": [
"src/*"
],
}
},
// ...
}
2-1) @types/... 관련 라이브러리를 설치한다. 하지만 TS를 지원하지 않는다면 다음과 같이 해결한다.
2-2) // @ts-ignore
주석 사용하기. 이 방법도 임시방편인 것 같다.
2-3) d.ts 파일로 직접 모듈화하기.
vite 프로젝트를 생성하면 env.d.ts
파일이 존재한다.
declare module '라이브러리명';
위와 같이 라이브러리명을 선언해준다.
vue-cli에서 사용되었던 process.env.ㅁㅁㅁ
형태의 환경변수가 잡히지 않는다. vite에서도 .env 파일의 명명규칙이 유지된다. vue3 환경에서는 VUE_APP_*
접두사를 사용해서 환경변수를 선언하는데, VITE_*
로 변경되었으며 그에 따라 환경변수명도 변경한다.
대표적인 환경변수를 다음과 같이 변경한다. 프로젝트 전체 검색을 통해 변경한다.
.env 파일의 내용을 다음과 같이 변경한다.
public 폴더 내부에 있는 index.html 파일의 위치가 프로젝트로 루트로 변경되었다. vite는 개발모드 시 esbuild를 사용하기 때문에 <script type="module" src="/src/main.ts"></script>
코드가 html 파일의 body 하단에 위치하게 된다.
resolve.extensions에 기본값은 ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json']
이다. .vue 확장자는 vue3에서도 생략하지 않도록 되어있으며, 기본 값을 그대로 유지해준다. 추후 필요한 확장자가 있는 경우 vite.config.js에 추가해준다.
webpack 환경이 아니기 때문에 vue-router에서 사용되는 dynamic import의 webpackChunkName 코드를 제거한다.
vite는 모던 브라우저만을 타깃으로 하기 때문에, 표준을 준수하도록 native css를 사용하도록 권고된다. 다시말해 CSS Pre-processors를 기본적으로 지원하지 않는다는 뜻이다. 다만 필요한 경우에는 어렵지 않게 설치해서 바로 사용할 수 있다.
# .scss and .sass
npm add -D sass
# .less
npm add -D less
# .styl and .stylus
npm add -D stylus
Vue SFC를 사용하는 경우 설치후 별다른 설정없이 <style lang="sass">
와 같은 css 전처리기를 바로 사용할 수 있다. Sass나 Less에서의 @import alias
나 url()
도 사용가능하다.
위 이미지는 webpack의 sass-loader 공식문서 내용에 일부이다. ~
를 사용하는 것은 deprecated되었으며, 코드에서 제거하는 것을 권장한다. 이미 구식 코드에서 사용 중이기 때문에 역사적인 이유(?) 때문에 호환성을 지원한다.
sass-loader의 change log중 일부이다. 11.0.0 버전이 되면서 위와 같은 내용이 적용된다.
프로젝트의 alias 중 가장 유명한 별칭은 at(@)이다. webpack 설정으로 @
을 src 폴더를 가리키게 세팅해준다. tilde를 사용하는 ~@
는 sass 구문에서 alias를 사용하기 위한 prefix이다. ~는 sass의 기능이 아니고 sass-loader에서 구현되는 기능이다. 그러므로 sass-loader의 문법을 수정해야한다. vite에는 sass의 package만 필요할 뿐 loader는 필요없다.
~@
에서 ~
를 제거하는 방식으로 진행하려고 했다. 하지만 프로젝트 코드 중 모든 ~@
를 제거하기에 너무 노가다스럽다는 생각을 하였다. 혹시 ~@
를 sass의 alias로 세팅하면 *.scss
파일 내 코드를 수정없이 사용할 수 있지 않을까 생각하여 검색하게 되었다. vite > github > issue에서 검색한 내용을 힌트로 삼아 다음과 같은 코드로 해결하게 되었다.
export default defineConfig({
resolve: {
alias: [
{ find: '@', replacement: '/src' },
{ find: /^~@/, replacement: '/src' }
]
},
// ...
})
~@
를 /src
로 치환하는 alias로 설정하여 scss파일 내 url(~@/...)
코드를 정상적으로 읽을 수 있게 되었다.
vite 2.9.13의 bug fix내역
2.9.13 (2022-06-27) fix: backport #8804, /@fs/ dir traversal with escaped chars (fixes #8498) (#8805) (e109d64), closes #8498 #8805 fix(wasm): support decoding data URL in Node < v16 (#8668) (1afc1c2), closes #8668
처음에는
{ find: /^~/, replacement: '' }
로 세팅하였으나/@fs/
버그가 생겨서 위 방식처럼 적용하였다. 하지만 vite v2.9.13이후에 패치된 내역과는 다르게/^~/
방식이 적용되지 않았다. 현재는/^~@/
방식을 사용하고 있다.export default defineConfig({ resolve: { alias: [ { find: '@', replacement: '/src' }, { find: /^~/, replacement: '' } ] }, // ... })
2)과정까지 적용하면 vite 서버는 정상적으로 작동한다. 하지만 실제 localhost:3000로 접속해보면 sass의 문제가 발생한다.
Undefined variable.
╷
53 │ border-radius: $border-radius-base;
│ ^^^^^^^^^^^^^^^^^^^
╵
vite.config.ts
에 css.preprocessorOptions를 추가한다(참고 : https://vitejs.dev/config/#css-preprocessoroptions).
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
resolve: {
alias: [
{ find: '@', replacement: '/src' },
]
},
css: {
preprocessorOptions: {
scss: {
additionalData: '@import "@/styles/main.scss";'
}
}
},
plugins: [vue()]
})
위와 같이 scss 옵션을 세팅하고나서 dev 환경에서 style에 대한 문제가 발생한다. 같은 스타일이 반복되게 중복되는 현상이 생기는데, 이 문제는 vite github > issue(https://github.com/vitejs/vite/issues/4448, https://github.com/vitejs/vite/issues/7504)에 올라와있는 이슈이다. 프로젝트 내 scss 파일에 대한 이해가 필요하다. 우선 vite.config.ts
파일의 css.preprocessorOptions.scss.additionalData에 대해 알아보자.
additionalData 옵션은 다음과 같이 정의할 수 있다. (https://github.com/vitejs/vite/issues/4448#issuecomment-1110997673)
vite는 각각의 sass, scss, css import를 webpack과 동일한 방식으로 개별적으로 처리한다. 프로젝트 내 js, ts파일에서 import된 모든 sass, scss, css 파일 앞에 additionalData가 추가된다.
그러므로 모든 스타일 앞에 추가하는 역할을 하는 scss.additionalData 옵션에는 saas의 공통 variables(변수들), mixins(함수들)에 해당하는 scss파일을 추가한다.
// vite.config.ts
export default defineConfig({
// ...
css: {
preprocessorOptions: {
scss: {
additionalData: '@import "@/styles/utils/index";'
}
}
},
// ...
그리고 나머지 공통 스타일은 main.ts
파일에 추가한다.
// main.ts
import { createApp } from 'vue';
import App from '@/App.vue';
import router from '@/router';
import { store, key } from '@/store';
import '@/styles/main.scss';
const app = createApp(App);
// ...
app.mount('#app');
vite.config.ts의 additionalData 옵션과 main.ts에 공통 스타일 import를 통해 scss가 정상적으로 반영되는 것을 볼 수 있다.
vite 환경에 Restful API를 위한 proxy 설정을 해준다. vite.config.ts
파일에 server.proxy의 값을 추가해준다.
export default defineConfig({
// ...
server: {
proxy: {
'/api/v1': {
target: 'http://0000.0000.000/',
},
'/api/v2': {
target: 'http://0000.0000.000/',
},
},
},
// ...
})