Skip to content
This repository was archived by the owner on Mar 4, 2025. It is now read-only.

add TypeScript integration #207

Closed
wants to merge 28 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ yarn create nuxt-app <my-project>
- Linter / Formatter
- [Prettier](https://prettier.io/)
- [Axios](https://github.com/nuxt-community/axios-module)
- [Typescript](https://github.com/nuxt/nuxt.js)
3. Choose your favorite UI framework:
- None (feel free to add one later)
- [Bootstrap](https://github.com/bootstrap-vue/bootstrap-vue)
Expand Down
28 changes: 27 additions & 1 deletion saofile.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ module.exports = {
{
name: 'Axios',
value: 'axios'
},
{
name: 'TypeScript support',
value: 'typescript'
}
],
default: []
Expand Down Expand Up @@ -118,6 +122,7 @@ module.exports = {
const linter = this.answers.features.includes('linter')
const prettier = this.answers.features.includes('prettier')
const axios = this.answers.features.includes('axios')
const typescript = this.answers.features.includes('typescript')
const esm = this.answers.server === 'none'

return {
Expand All @@ -126,6 +131,7 @@ module.exports = {
eslint: linter ? 'yes' : 'no',
prettier: prettier ? 'yes' : 'no',
axios: axios ? 'yes' : 'no',
typescript: typescript ? 'yes' : 'no',
esm
}
},
Expand All @@ -148,7 +154,19 @@ module.exports = {
}
}]

if (this.answers.ui !== 'none') {
if (this.answers.ui !== 'none' && this.answers.features.includes('typescript')) {
actions.push({
type: 'add',
files: '**',
templateDir: `template/frameworks/${this.answers.ui}-ts`
})
} else if (this.answers.ui === 'none' && this.answers.features.includes('typescript')) {
actions.push({
type: 'add',
files: '**',
templateDir: `template/frameworks/nuxt-ts`
})
} else if (this.answers.ui !== 'none') {
actions.push({
type: 'add',
files: '**',
Expand Down Expand Up @@ -187,6 +205,14 @@ module.exports = {
})
}

if (this.answers.features.includes('typescript')) {
actions.push({
type: 'add',
files: '**',
templateDir: 'template/frameworks/typescript'
})
}

actions.push({
type: 'add',
files: '*',
Expand Down
24 changes: 19 additions & 5 deletions template/_.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,36 @@ module.exports = {
use: true
},<% } %>
parserOptions: {
parser: 'babel-eslint'
<% if (typescript === 'yes' && prettier === 'yes') { %>
parser: '@typescript-eslint/parser',
sourceType: 'module',
project: './tsconfig.json',
ecmaFeatures: { "legacyDecorators": true }
<% } else { %>
parser: 'babel-eslint'<% } %>
},
extends: [
'@nuxtjs',
'plugin:nuxt/recommended'<% if (prettier === 'yes'){ %>,
'plugin:prettier/recommended',
'prettier',
'prettier/vue'<% } %>
'prettier/vue'<% } else if (prettier === 'yes' && typescript === 'no'){ %>
'prettier',
<% } else if (prettier === 'yes' && typescript === 'yes'){ %>
'prettier/@typescript-eslint'
<% } -%>
],<% if (prettier === 'yes'){ %>
plugins: [
'prettier'
'prettier'<% if (typescript === 'yes') { %>,
'@typescript-eslint'
<% } %>
],<% } %>
// add your custom rules here
rules: {
<% if (!esm){ -%>
'nuxt/no-cjs-in-config': 'off'
<% } -%>
<% } -%><% if (typescript === 'yes') { %>
'no-unused-vars': 'off',
'@typescript-eslint/no-unused-vars': 'error'
<% } %>
}
}
19 changes: 13 additions & 6 deletions template/_package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,16 @@
"dev": "<% if (server === 'none') { %>nuxt<% } else { %>cross-env NODE_ENV=development nodemon server/index.js --watch server<% } %>",
"build": "nuxt build",
"start": "<% if (server === 'none') { %>nuxt start<% } else { %>cross-env NODE_ENV=production node server/index.js<% } %>",
"generate": "nuxt generate"<% } %><% if (eslint === 'yes') { %>,
"lint": "eslint --ext .js,.vue --ignore-path .gitignore .",
"generate": "nuxt generate"<% } %><% if (eslint === 'yes' && typescript === 'no') { %>,
"lint": "eslint --ext .js,.vue --ignore-path .gitignore .",<% } %><% if (eslint === 'yes' && typescript === 'yes') { %>,
"lint": "eslint --ext .ts,.js,.vue --ignore-path .gitignore .",<% } %><% if (eslint === 'yes') { %>
"precommit": "<%= pm %> run lint"<% } %><% if (test !== 'none') { %>,
"test": "<%= test %>"<% } %>
},
"dependencies": {
"cross-env": "^5.2.0"<% if (edge) { %>,
"nuxt-edge": "latest"<% } else { %>,
"nuxt": "^2.4.0"<% } %><% if (server === 'express') { %>,
"nuxt": "^2.6.3"<% } %><% if (server === 'express') { %>,
"express": "^4.16.4"<% } else if (server === 'koa') { %>,
"koa": "^2.6.2"<% } else if (server === 'hapi') { %>,
"@hapi/hapi": "^18.3.1",
Expand Down Expand Up @@ -50,11 +51,14 @@
"nuxt-buefy": "^0.3.2"<% } else if (ui === 'iview') { %>,
"iview": "3.1.5"<% } %><% if (axios === 'yes') { %>,
"@nuxtjs/axios": "^5.3.6"<% } %><% if (pwa === 'yes') { %>,
"@nuxtjs/pwa": "^2.6.0"<% } %><% if (ui === 'tachyons') { %>,
"@nuxtjs/pwa": "^2.6.0"<% } %><% if (typescript === 'yes') { %>,
"ts-node": "^8.2.0",
"typescript": "^3.5.1",
"nuxt-property-decorator": "^2.1.3"<% } %><% if (ui === 'tachyons') { %>,
"tachyons": "^4.11.1"<% } %>
},
"devDependencies": {
"nodemon": "^1.18.9"<% if (eslint === 'yes') { %>,
"nodemon": "^1.18.11"<% if (eslint === 'yes') { %>,
"@nuxtjs/eslint-config": "^0.0.1",
"@nuxtjs/eslint-module": "^0.0.1",
"babel-eslint": "^10.0.1",
Expand Down Expand Up @@ -82,6 +86,9 @@
"browser-env": "^3.2.5",
"require-extension-hooks": "^0.3.3",
"require-extension-hooks-babel": "^0.1.1",
"require-extension-hooks-vue": "^2.0.0"<% } %>
"require-extension-hooks-vue": "^2.0.0"<% } %><% if (typescript === 'yes') { %>,
"@nuxt/typescript": "^2.6.3"<% } %><% if (typescript === 'yes' && prettier === 'yes') { %>,
"@typescript-eslint/parser": "^1.9.0",
"@typescript-eslint/eslint-plugin": "^1.9.0"<% } %>
}
}
32 changes: 32 additions & 0 deletions template/frameworks/nuxt-ts/layouts/error.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<template>
<div>
<h1 v-if="error.statusCode === 404">
{{ pageNotFound }}
</h1>
<h1 v-else>
{{ otherError }}
</h1>
<NuxtLink to="/">
Home page
</NuxtLink>
</div>
</template>

<script lang="ts">
import { Vue, Component, Prop } from 'nuxt-property-decorator'

@Component({})
export default class Error extends Vue {
layout: string = 'empty'
pageNotFound:string = '404 Not Found'
otherError:string = 'An error occurred'
@Prop({ type: Object, default: null }) error: Object
head() {
const title =
this.error.statusCode === 404 ? this.pageNotFound : this.otherError
return {
title
}
}
}
</script>
69 changes: 69 additions & 0 deletions template/frameworks/nuxt-ts/pages/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<template>
<section class="container">
<div>
<logo />
<h1 class="title">
twitter-nuxt-ts
</h1>
<h2 class="subtitle">
My kryptonian Nuxt.js project
</h2>
<div class="links">
<a href="https://nuxtjs.org/" target="_blank" class="button--green"
>Documentation</a
>
<a
href="https://github.com/nuxt/nuxt.js"
target="_blank"
class="button--grey"
>GitHub</a
>
</div>
</div>
</section>
</template>

<script lang="ts">
import Logo from '~/components/Logo.vue'
import { Component, Vue } from 'vue-property-decorator'

@Component({
components: {
Logo
}
})
export default class Home extends Vue {}
</script>

<style>
.container {
margin: 0 auto;
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
}

.title {
font-family: 'Quicksand', 'Source Sans Pro', -apple-system, BlinkMacSystemFont,
'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
display: block;
font-weight: 300;
font-size: 100px;
color: #35495e;
letter-spacing: 1px;
}

.subtitle {
font-weight: 300;
font-size: 42px;
color: #526488;
word-spacing: 5px;
padding-bottom: 15px;
}

.links {
padding-top: 15px;
}
</style>
1 change: 1 addition & 0 deletions template/frameworks/typescript/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
2 changes: 2 additions & 0 deletions template/frameworks/vuetify-ts/assets/style/app.styl
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Import Vuetify styling
@require '~vuetify/src/stylus/app.styl'
1 change: 1 addition & 0 deletions template/frameworks/vuetify-ts/assets/style/variables.styl
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@require '~vuetify/src/stylus/settings/_variables.styl'
79 changes: 79 additions & 0 deletions template/frameworks/vuetify-ts/components/Logo.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<template>
<div class="VueToNuxtLogo">
<div class="Triangle Triangle--two" />
<div class="Triangle Triangle--one" />
<div class="Triangle Triangle--three" />
<div class="Triangle Triangle--four" />
</div>
</template>

<style>
.VueToNuxtLogo {
display: inline-block;
animation: turn 2s linear forwards 1s;
transform: rotateX(180deg);
position: relative;
overflow: hidden;
height: 180px;
width: 245px;
}

.Triangle {
position: absolute;
top: 0;
left: 0;
width: 0;
height: 0;
}

.Triangle--one {
border-left: 105px solid transparent;
border-right: 105px solid transparent;
border-bottom: 180px solid #41b883;
}

.Triangle--two {
top: 30px;
left: 35px;
animation: goright 0.5s linear forwards 3.5s;
border-left: 87.5px solid transparent;
border-right: 87.5px solid transparent;
border-bottom: 150px solid #3b8070;
}

.Triangle--three {
top: 60px;
left: 35px;
animation: goright 0.5s linear forwards 3.5s;
border-left: 70px solid transparent;
border-right: 70px solid transparent;
border-bottom: 120px solid #35495e;
}

.Triangle--four {
top: 120px;
left: 70px;
animation: godown 0.5s linear forwards 3s;
border-left: 35px solid transparent;
border-right: 35px solid transparent;
border-bottom: 60px solid #fff;
}

@keyframes turn {
100% {
transform: rotateX(0deg);
}
}

@keyframes godown {
100% {
top: 180px;
}
}

@keyframes goright {
100% {
left: 70px;
}
}
</style>
21 changes: 21 additions & 0 deletions template/frameworks/vuetify-ts/components/VuetifyLogo.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<template>
<img
class="VuetifyLogo"
alt="Vuetify Logo"
src="data:image/png;base64,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"
>
</template>

<style>
.VuetifyLogo {
width: 180px;
transform: rotateY(560deg);
animation: turn 3.5s ease-out forwards 1s;
}

@keyframes turn {
100% {
transform: rotateY(0deg);
}
}
</style>
Loading