Skip to main content

Nuxt 2.0(nuxt-edge) + Typescript

· 4 min read ·
yoonhoGo

Nuxt 2.0에서 Typescript를 적용하는 방법에 대해서 한번에 요약되어 있는 글이 없어서 글로 정리하고 보일러플레이트로 repo를 만들어 뒀습니다.


우선 vue-cli를 이용하여 nuxt starter-template을 받아줍니다.

  1. yarn global add @vue/cli @vue/cli-init
  2. vue init nuxt-community/starter-template <project-name>

그리고 기존에 있던 nuxt를 지우고 nuxt-edge(Nuxt.js 2.0)을 받아줍니다.

yarn remove nuxt && yarn add next-edge

이것 자체로 nuxt-edge 설정은 완료되었습니다. 이제 Typescript를 설정을 해줍니다. Typescript와 nuxt에서 내부적으로 돌아가는 webpack을 위한 ts-loader 그리고 lint 적용을 위해서 tslint를 devDependencies에 설치해줍니다.

yarn add typescript ts-loader tslint --dev

설치가 완료되면 초기 설정 파일을 만들어줍니다. 아래 명령어를 실행하면 tsconfig.json과 tslint.json 파일이 각각 생성됩니다. tslint는 홈페이지를 참고해서 rule을 수정하시면 됩니다. *Gist 내용은 Copy&Paste 해주시면 됩니다.

tsc --init && tslint --init

// tsconfig.json
{
"compilerOptions": {
/* Basic Options */
"target": "es5" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */,
"module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */,
"allowJs": true /* Allow javascript files to be compiled. */,
"outDir": "./.dist" /* Redirect output structure to the directory. */,
/* Strict Type-Checking Options */
"strict": true /* Enable all strict type-checking options. */,
/* Module Resolution Options */
"moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */,
"baseUrl": "./src" /* Base directory to resolve non-absolute module names. */,
"paths": {
"*": ["node_modules/*"],
"~/*": ["src/*"],
"@/*": ["types/*"]
} /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */,
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
/* Experimental Options */
"experimentalDecorators": true /* Enables experimental support for ES7 decorators. */
}
}

설정이 완료 되셨으면 Nuxt에서 typescript를 build 할 때 제대로 load 할 수 있도록 ts-loader를 연결해줍니다. *Gist 내용은 Copy&Paste 해주시면 됩니다.

// nuxt.config.js
module.exports = {
srcDir: "src/",
extensions: ["js", "ts"],
/*
** Headers of the page
*/
head: {
title: "portfolio",
meta: [
{ charset: "utf-8" },
{ name: "viewport", content: "width=device-width, initial-scale=1" },
{ hid: "description", name: "description", content: "my portfolio site" },
],
link: [{ rel: "icon", type: "image/x-icon", href: "/favicon.ico" }],
},
/*
** Customize the progress bar color
*/
loading: { color: "#3B8070" },
/*
** Build configuration
*/
build: {
/*
** Run ESLint on save
*/
extend(config, { isServer }) {
const tsLoader = {
loader: "ts-loader",
options: { appendTsSuffixTo: [/\.vue$/], transpileOnly: true },
exclude: [/vendor/, /\.nuxt/],
}
config.module.rules.push({
test: /((client|server)\.js)|(\.tsx?)$/,
...tsLoader,
})
config.resolve.extensions.push(".ts")
config.module.rules.map(rule => {
if (rule.loader === "vue-loader") {
rule.options.loaders = { ts: tsLoader }
}
return rule
})

if (isServer) {
config.externals = []
}
},
},
}

마지막으로 vue에서 typescript를 쓸 때 다른 Component를 import할 수 있도록 .vue 파일 타입을 정의해줍니다. *Gist 내용은 Copy&Paste 해주시면 됩니다.

// types/index.d.ts
declare module "*.vue" {
import Vue, { VueConstructor } from "vue"
const vue: VueConstructor<Vue>
export default vue
}

선택가능한 부분

만약 class형태로 components를 나누신다면 nuxt-class-componentnuxt-property-decorator를 참고하시기 바랍니다. 보일러플레이트에서는 적용 되었습니다. yarn add nuxt-property-decorator


결론

이제 yarn dev를 실행하여 테스트 해보시기 바랍니다.