Nuxt 활용 팁들 정리

- 이 문서에서는 Nuxt 환경에서 활용할 수 있는 팁이나 오류 해결 방법들을 정리하고 있으며 수시로 변경될 수 있습니다.

Host / Port 변경하기

Nuxt는 기본 값으로 Host: localhost, Port: 3000 으로 설정되어 있다. 당연히 변경 가능하며 여러가지 방법이 있다.

Yarn (NPM) 스트립트 수정 (Direct Arguments)

package.json 파일의 scripts 부분을 아래와 같이 수정하면 된다.

package.json 파일의 scripts 수정
1...
2  "scripts": {
3    "dev": "nuxt-ts --hostname <host> --port <port>",
4    "build": "nuxt-ts build",
5  },
6...

환경설정 (nuxt.config.[js|ts])

nuxt.config.[js|ts] 내에 서버에 대한 설정을 추가해서 적용할 수 있다.

package.json 파일의 scripts 수정
 1...
 2export default {
 3  /*
 4  ** Server Configuration
 5  */
 6  server: {
 7    port: 4444,
 8    host: '0.0.0.0'
 9  },
10...

환경 변수 활용

환경 변수를 직접 package.json 파일에 환경 변수를 설정하는 방식

package.json 파일의 scripts 부분을 아래와 같이 수정하면 된다.

package.json 파일의 scripts 수정
1...
2  "scripts": {
3    "dev": "NUXT_HOST=0.0.0.0 NUXT_PORT=3333 nuxt-ts",
4    "dev": "HOST=0.0.0.0 PORT=3333 nuxt-ts",
5  },
6...

Cross Platform을 위해서 cross-env 패키지를 설치해서도 사용할 수 있다.

yarn add -D cross-env

package.json 파일의 scripts 수정
1...
2  "scripts": {
3    "dev": "cross-env NUXT_HOST=0.0.0.0 NUXT_PORT=3333 nuxt-ts",
4    "dev": "HOST=0.0.0.0 PORT=3333 nuxt-ts",
5  },
6...

package.json에 설정

package.json 파일에 config 설정을 아래와 같이 추가해서 사용할 수 있다.

package.json 파일의 config 설정
1...
2  "config": {
3      "nuxt": {
4          "host": "0.0.0.0",
5          "port": "3333"
6      }
7  },
8...

개발할 때 자동으로 브라우저 실행시키기

딱히 획기적인 팁은 아니지만 터미널에서 개발서버를 구동시키고 브라우저로 확인하는 것이 기본이다 보니 브라우저를 다시 실행하는 것이 귀찮을때가 많다. 물론 한번 실행하고 안 닫으면 되겠지만…

package.json을 사용하는 방법

package.json에 구성한 스크립트에 --open 옵션을 추가하면 된다.

package.json - 개발서버 실행할 때 브라우저 실행하기
1...
2  scripts: {
3    'dev': 'nuxt-ts --open'   // typescript가 아닌 경우는 "nuxt --open" 사용
4    ...
5  }
6...
  • 빌드되는 동안 브라우저에 살짝 진행 과정이 표시된다.
  • 시스템 기본 브라우저가 실행된다.

opn 모듈 사용

위의 방식이 편하지만 맥북의 경우는 크롬이 아니라 사파리가 열린다. 물론 기본 브라우저를 바꾸면 되지만 시스템 설정을 바꾸지 않고 처리하는 방법은 opn 모듈을 설치해서 사용하는 것이다.

opn 패키지 설치
$ yarn add -D opn   // 개발 의존성으로 설치

기본적인 사용방법은 아래와 같이 URL, 옵션 방식이다.

opn 실행 방법
// 크롬 실행
opn('http://ccambo.github.io', {app: 'chrome'});    // 'google chrome', 'firefox', ...

추가적인 정보와 옵션들은 위의 opn 링크를 참조하면 된다.

Nuxt에 적용하는 방법은 간단한다. nuxt.config.ts 파일에 opn 패키지를 import하고 nuxt의 hooks 를 이용해서 호스트의 변경이 발생하면 브라우저를 실행해 주는 방식이다.

nuxt.config.js (javascript 환경인 경우)

nuxt.config.js - opn 패키지 적용
 1const opn = require('opn')
 2...
 3export default {
 4  ...
 5  hooks: {
 6    listen(server, { host, port }) {
 7      opn(`http://${host}:${port}`, { app: ['google chrome', '--incognito']});
 8    }
 9  }
10  ...
11}

nuxt.config.ts (Typescript 환경인 경우)

nuxt.config.ts - opn 패키지 적용
 1const opn = require('opn')    // 형식 노출이 없어서 import 문에 오류 발생하므로...
 2...
 3export default {
 4  ...
 5  hooks: {
 6    listen: (_server: any, { host, port }: any) => {    // _server는 no-unused-var 오류를 피하는 방법
 7      opn(`http://${host}:${port}`, { app: ['google chrome', '--incognito']})
 8    }
 9  }
10  ...
11}

Module parse failed: Identifier ‘installComponents’ has already been declared

Nuxt App run dev
$ yarn run dev  # 또는 npm run dev 또는 npx run dev

위의 명령으로 개발환경으로 처리할 때는 문제가 없이 동작을 했지만 배포 테스트를 위해서 아래와 같이 빌드 명령을 수행하면 오류가 발생한다.

Nuxt App run build/generate
$ yarn run build  # 또는 npm run build 또는 npx run build

발생하는 오류는 다음과 같다.

Module parse failed: Identifier ‘installComponents’ has already been declared

오류를 해석해 보면 “installComponents”가 선언되었기 때문에 중복으로 선언되어 Moudle 파싱을 처리할 수 없다는 내용이다. 이런 문제가 발생하는 이유는 Vuetify가 두번 로드되고 있다고 생각하면 된다.

Nuxt에서는 Webpack이 내부적으로 구성되어 동작하고 Vuetify를 Module로 처리하고 있기 때문에 이런 중복에 관련된 것은 설정상의 문제 (nuxt.config.[js|ts]]) 뿐이 없다. 물론 Webpack을 커스텀하게 구성하고 있다면 다른 문제가 된다.

여기서는 기본적인 Nuxt를 사용하고 있다는 가정하게 아래와 같이 nuxt.config.[js|ts] 파일에 중복 설정된 것을 확인해 보면 된다.

nuxt.config.ts - Vuetify Module 설정
 1...
 2  /*
 3  ** Nuxt.js Build modules
 4  */
 5  buildModules: [
 6    '@nuxt/typescript-build',
 7    '@nuxtjs/vuetify',
 8  ],
 9...
10  /*
11  ** Nuxt.js modules
12  */
13  modules: [
14    [
15      '@nuxtjs/axios',
16      {
17        debug: process.env.NODE_ENV === 'development'
18      }
19    ],
20    '@nuxtjs/vuetify'
21    // '@nuxtjs/auth',
22    // 'nuxt-material-design-icons'
23  ],
24...

위의 예시와 같이 buildModules, Modules 두 곳에 @nuxtjs/vuetify가 등록되어 있는 것을 확인할 수 있다. 이런 문제가 생기는 이유는 아마도 Vuetify 버전을 Upgrade 등을 수행하면서 처리된 것이다.

buildModules 에서 @nuxtjs/vuetify를 제거 해 주면 문제가 해결된다.

기본 폴더 재 정의하기

Nuxt는 기본적인 폴더 구조를 제공하고 있다. 그런데 실제 프로젝트를 진행하다 보면 이를 재 구성해서 의미론적으로 운영할 때가 많다. 예를 들면 “layout”과 “pages”를 모두 “Views”라는 폴더 밑의 서브 폴더로 통합운영하는 것 등이다.

Nuxt 기본 폴더
./
  assets/
  components/
  layouts/
  ...
  pages/
  ...
  store/

위의 기본 폴더를 아래와 같이 기능별로 묶어서 구성할 수 있다.

Nuxt 기본 폴더
./
  assets/
  components/
  ...
  store/
  views/
    layouts/
    pages/

위와 같이 폴더를 재 구성하는 경우는 아래와 같이 “nuxt.config.[js|ts]” 를 변경하면 된다.

nuxt.config.ts - 폴더 재 구성
...
  dir: {
    layouts: 'views/layouts',
    pages: 'views/pages'
  }
...

“ERR_ACTION_ACCESS_UNDEFINED” 오류

nuxt.js에서 Store의 Action을 “vuex-module-decorators” 패키지를 이용해서 사용할 때 아래와 같은 오류가 발생할 수 있다.

Namespaces do not function. Throws “ERR_ACTION_ACCESS_UNDEFINED” when using namespaces

vuex-module-decorators 내부에서 처리하는 과정에 발생하는 것으로 설정에 따라서 다양한 원인으로 발생할 수 있다. 다만, 그 중에 한가지는 Store Action에서 사용자 정의 Error를 반환할 떄 발생하는 것이며, 아래와 같이 Action 선언을 처리해 주면 된다.

@/store/user.ts - 사용자 정의 오류 반환
 1...
 2  @Action({ rawError: true })
 3  public async signup(name: string, email: string, password: string) {
 4    // TODO: password 암호화
 5    let data = await $axios.$post('/signup', { name, email, password })
 6      .then((res) => {
 7        const user = res as IUserState
 8        this.set_user(user)
 9        return user
10      })
11      .catch((err) => {
12        if (err.config && err.config.url)
13          throw new Error("API Server 환경을 검토하십시오.")
14        else
15          throw new Error(err.message)
16      })
17  }
18...

위의 코드에서와 같이 @Action({ rawError: true }) 를 설정하면 해결된다. 단, 다른 원인에 의해서 발생하는 경우는 해당 원인을 파악해 본후에 적용해야 한다.

[갱신일자 : 2020/01/14]

만일 위의 증상을 해결해서 정상동작하고 있는 상태라고 해도 nuxt-auth 모듈 패키지를 설치해서 운영하는 경우라면 위와 같은 오류가 발생한다. 인증 부분을 처리하기 위해서 도입하고 설정해서 사용하는 중에 지속적으로 같은 오류가 발생한다. 따라서 결국은 들어내고 수동으로 구현하는 것이외에는 아직 해결 방법이 없는 것 같다.

참고 자료