Nuxt +typescript project scaffolding

Nuxt has encountered a lot of pits, there is a nuxT mining pit, but there are many related articles skipped. Mainly for TS, I did not find an article to my liking. Jie huai does not have ts this strong type of judgment, so do it. Nuxt actually has TS documentation for TS

The Nuxt official website is attached

Off-topic: Documentation has finally been updated since 2.8. But the NUXT is at 2.10 as I write this. I just want to make fun of a lot of things are still only inside the issue. There are many potholes from version update iterations. At this point, you don’t have to worry about creating the project manually, using official scaffolding.

1. Start a NUXT project based on scaffolding

  • The Nuxt.js team created the scaffolding tool create-Nuxt-app.
  • Make sure NPX is installed (NPX is installed by default in NPM version 5.2.0)

Make sure the above two points before the order, okay? You can also choose official guidance

1.1. Scaffolding instruction construction project
NPX create-nuxt-app nuxt-ts = NPX create-nuxt-appCopy the code
1.2. Configuration selection

You can choose the configuration you need according to your own situation. Mine are as follows:

Create-nuxt-app v2.11.1 ✨ Generating nuxt.js projectin nuxt-ts
? Project name nuxt-ts
? Project description My majestic Nuxt.js project
? Author name collin
? Choose the package manager Yarn
? Choose UI framework None
? Choose custom server framework Koa
? Choose Nuxt.js modules Axios
? Choose linting tools ESLint, Prettier
? Choose test framework None
? Choose rendering mode Universal (SSR)
? Choose development tools jsconfig.json (Recommended for VS Code)
Copy the code
1.3. Project operation and packaging
// Similar to NPM run dev, I use yarncdNuxt-ts yarn dev // package + run (this is usually used for deployment, but can also run locally) :cd nuxt-ts
yarn build
yarn start
Copy the code

Ok, here we are, with the help of scaffolding, we have a prototype of the project. Let’s go on

2. Use Version Lens to upgrade all dependencies to the latest Version

If the download is too slow, you can create a.yarnrc file in the root directory and specify the download source

// .yarnrc
registry "https://registry.npm.taobao.org"
sass_binary_site "https://npm.taobao.org/mirrors/node-sass/"
phantomjs_cdnurl "http://cnpmjs.org/downloads"
electron_mirror "https://npm.taobao.org/mirrors/electron/"
sqlite3_binary_host_mirror "https://foxgis.oss-cn-shanghai.aliyuncs.com/"
profiler_binary_host_mirror "https://npm.taobao.org/mirrors/node-inspector/"
chromedriver_cdnurl "https://cdn.npm.taobao.org/dist/chromedriver"
Copy the code
// package.json
"dependencies": {
    "nuxt": "^ 2.10.2"."cross-env": "^ 6.0.3"."koa": "^ 2.11.0"."@nuxtjs/axios": "^ 5.8.0"
},
"devDependencies": {
    "nodemon": "^ 1.19.4"."@nuxtjs/eslint-config": "^ 1.1.2." "."@nuxtjs/eslint-module": "^ 1.1.0." "."babel-eslint": "^ 10.0.3"."eslint": "^ 6.6.0"."eslint-plugin-nuxt": "> = 0.4.3"."eslint-config-prettier": "^ 6.5.0"."eslint-plugin-prettier": "^ 3.1.1." "."prettier": "^ 1.19.0"
}
Copy the code

Yarn dev Ensures that the project runs properly


3. Supports TS notation

Refer to official documentation

Change js file to TS file (including references)

  • jsconfig.json –> tsconfig.json
  • nuxt.config.js –> nuxt.config.ts
  • Js –> server/index.ts (nuxt.config.ts)
  • Dev in package.json, and the start directive.js –>.ts
  • Added global.d.ts (global declaration) to the root directory
  • Added shims-tx.d to the root directory (write JSX code in Vue project)
  • Added shims-vue. D to the root directory (TypeScript recognizes.vue files)
3.1. Install the TS plug-in
// Version 2.8: Yarn remove @nuxt/typescript yarn add @nuxt/typescript-build yarn add @nuxt/typescript-runtime // If ts-Node is not installed, Then install itCopy the code
3.2 Add @nuxt/typescript-build to the configuration file nuxt.config.ts
// nuxt.config.js
export default {
  buildModules: ['@nuxt/typescript-build']}Copy the code
In 3.3 tsconfig.json, @nuxt/vue-app and @nuxt/config are replaced with @nuxt/types
// tsconfig.json // tsconfig has a lot of other 'fun' configurations. Here is the official basic configuration with new types {"compilerOptions": {
    "target": "esnext"."module": "esnext"."moduleResolution": "node"."lib": [
      "esnext"."esnext.asynciterable"."dom"]."esModuleInterop": true."allowJs": true."sourceMap": true."strict": true."noEmit": true."baseUrl": "."."paths": {
      "~ / *": [
        ". / *"]."@ / *": [
        ". / *"]},"types": [
      "@types/node"."@nuxt/types"// add]},"exclude": [
    "node_modules"]}Copy the code

If you want to import types from @nuxt/ config, you need to import them from @nuxt/types.

3.4. Move custom options from build.typescript to module options
// nuxt.config.js
export default {
  buildModules: [
    ['@nuxt/typescript-build', {
      typeCheck: true,
      ignoreNotFoundWarnings: true}}]]Copy the code
3.5.package. json (run with nuxT-ts)
"scripts": {
  "dev": "nuxt-ts"."build": "nuxt-ts build"."generate": "nuxt-ts generate"."start": "nuxt-ts start"
},
"dependencies": {
  "@nuxt/typescript-runtime"."nuxt"
},
"devDependencies": {
  "@nuxt/typescript-build"
}
Copy the code


4. Install tslint,

4.1 installation @ typescript – eslint/eslint – the plugin
yarn add @typescript-eslint/eslint-plugin
Copy the code
4.2 configuration. Eslintrc. Js

I prefer to use eslint-plugin-vue to deal with the formatting of ‘HTML’ in Vue. (This depends on the individual, do not forget to install the dependent plug-in)

// .eslintrc.js
parserOptions: {
    // parser: 'babel-eslint'
    parser: '@typescript-eslint/parser'
},
extends: [
    '@nuxtjs'.'prettier'.'prettier/vue', / /'plugin:prettier/recommended'.'plugin:vue/recommended'.'plugin:nuxt/recommended'
],
plugins: [
    'vue'.'@typescript-eslint'], rules: {// Use the official eslint-plugin-vue configuration.'nuxt/no-cjs-in-config': 'off'.'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off'.'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'.'vue/html-indent': 0.'vue/max-attributes-per-line': 0."vue/html-closing-bracket-newline": 0.'vue/attributes-order': 0.'vue/name-property-casing': 0.'vue/html-self-closing': 0.'vue/no-parsing-error': [0, {
      'x-invalid-end-tag': false}].'vue/mustache-interpolation-spacing': 0.'vue/attribute-hyphenation': 0.'vue/require-valid-default-prop': 0.'vue/require-default-prop': 0.'vue/require-prop-types': 0."vue/no-unused-components": 0."vue/singleline-html-element-content-newline": 0."vue/multiline-html-element-content-newline": 0."vue/order-in-components": 0."vue/no-dupe-keys": 0, / /... }Copy the code


5. Use TS decorators

So far, you can use it, if you like the decorator style, you can try it out.

yarn add vue-property-decorator vuex-class
Copy the code
// It will be written as <script lang="ts">
  import {Component, Vue} from 'vue-property-decorator'
  import {State, Getter} from 'vuex-class'

  @Component({})
  exportDefault class IndexPage extends Vue {// Original datatestMsg = 'My splendiferous Nuxt.js project'Private get computedVal(): string {return `computedVal: ${this.testMsg}@state (State => state.userinfo) vxUserInfo private Created (): void {} // method public init(): void {} } </script>Copy the code


6. Install a UI library to make up for the process of not installing plug-ins

6.1 Take vant UI as an example
yarn add vant -S
Copy the code
6.2 Creating vant/index.js under Plugin
// vant/index.js
import Vue from "vue";
import Vant from "vant";
import 'vant/lib/index.css'; // Use CSS in nuxt.config.ts: ['vant/lib/index.css'] Configuration also worksexport default () => {
  Vue.use(Vant);
}
Copy the code
6.3 Configuring vant (Flexible + PostCSS-px2REM-exclude)
  1. Use flexible to set the HTML font size
# static/flexible/index.js

!function(e,t){function n(){t.body? t.body.style.fontSize=12*o+"px":t.addEventListener("DOMContentLoaded",n)}function d(){var e=i.clientWidth/10; i.style.fontSize=e+"px"}var i=t.documentElement,o=e.devicePixelRatio||1;if(n(),d(),e.addEventListener("resize",d),e.addEventListener("pageshow".function(e){e.persisted&&d()}),o>=2){var a=t.createElement("body"),s=t.createElement("div"); s.style.border=".5px solid transparent",a.appendChild(s),i.appendChild(a),1===s.offsetHeight&&i.classList.add("hairlines"),i.removeChild(a)}}(window,document);
Copy the code
// nuxt.config.ts 
header: {
  script: [{
      src: '/flexible/flexible.js'.type: 'text/javascript',
      charset: 'utf-8',}}]Copy the code
  1. Postcss-px2rem -exclude vant
yarn add postcss-px2rem-exclude
Copy the code
// nuxt.config.ts
plugins: [
    {src: '~/plugins/vant', ssr: true},
],
build:
    postcss: {
      plugins: {
        'postcss-px2rem-exclude': {remUnit: 75, // convert basic units exclude: /vant/ I,},}, preset: {autoprefixer: {grid:true,},},},}Copy the code
  1. Vant theme configuration official website
/ / new cover official style less file/assets/index/style/theme. The lessCopy the code
// nuxt.config.ts
const path = require('path')

extend(config, ctx) {
  if (ctx.isDev && ctx.isClient) {
    config.module.rules.push(
      {
        test: /\.ts$/,
        exclude: [/node_modules/, /vendor/, /\.nuxt/],
        loader: 'ts-loader',
        options: {
          appendTsSuffixTo: [/\.vue$/],
          transpileOnly: true,},}, // Add topic overwrite configuration {test: /\.less$/,
        use: [
          {
            loader: 'less-loader', options: {modifyVars: {// Override variables directly //'@blue': '#3EB7E7'// Use an external.less file overwrite'hack': `true; @import "${path.join(__dirname, './assets/style/theme/index.less"')}; '},},},],},)}},Copy the code


7. Auth Module

Official Auth Module manual

7.1 installation
yarn add @nuxtjs/auth @nuxtjs/axios -S
Copy the code
7.2 configuration nuxt. Config. Ts
modules: [
    // Doc: https://axios.nuxtjs.org/usage
    '@nuxtjs/axios'.'@nuxtjs/auth',
],
auth: {
    strategies: {
      local: {
        endpoints: {
          login: {url: '/api/login', method: 'post', propertyName: 'data.token'} / / loginlogout: {url: '/api/logout', method: 'post'}, // log out user: {url:'/api/profile', method: 'get', propertyName: 'data'}, // Get personal information}, tokenRequired:true, // Whether tokenType:false, // Whether have been certified as Bearer of additional},},},Copy the code
7.3 the login
// login.vue
public async login() {
  await this.$auth
    .loginWith('local', {
      data: {
        email: this.email,
        password: this.password,
      },
    })
    .then(() => {
      this.$toast({
        message: this.$auth.user.email,
      })
    })
}
Copy the code

Let’s do this for now