Почему vue не распознает синтаксис TS в первой компиляции, но хорошо работает во второй? - PullRequest
2 голосов
/ 27 февраля 2020

Я сталкиваюсь со странной ошибкой, когда vue cli не распознает синтаксис TypeScript при первом его запуске, но работает нормально при втором.

Если вы удалите node_modules/.cache, а затем выполнить команду:

yarn build

Вы получите эту ошибку при первом вызове:

 ERROR  Failed to compile with 1 errors                                                                                           3:54:55 PM
 error  in ./src/components/ATSText/TextDate.vue

Module Error (from ./node_modules/eslint-loader/index.js):
error: Parsing error: Unexpected token : at src\components\ATSText\TextDate.vue:69:11:
  67 |   computed: {
  68 |     dateFormatted: {
> 69 |       get(): string {
     |           ^
  70 |         return this.formatDate(this.value);
  71 |       },
  72 |       set(val: string) {


1 error found.

 @ ./src/utils/schemaConverter.ts 13:47-92
 @ ./node_modules/cache-loader/dist/cjs.js??ref--14-0!./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib!./node_modules/ts-loader??ref--14-3!./node_modules/vuetify-loader/lib/loader.js??ref--20-0!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/views/Schema.vue?vue&type=script&lang=ts&
 @ ./src/views/Schema.vue?vue&type=script&lang=ts&
 @ ./src/views/Schema.vue
 @ ./src/router/index.ts
 @ ./src/main.ts
 @ multi ./src/main.ts

 ERROR  Build failed with errors.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Если вы снова выполните ту же команду, компиляция пройдет нормально:

 DONE  Build complete. The dist directory is ready to be deployed.
 INFO  Check out deployment instructions at https://cli.vuejs.org/guide/deployment.html

Done in 28.14s.

Если вы удаляете кеш и повторяете процесс, цикл повторяется.

Для справки это соответствующие исходные файлы:

TextDate. vue:

<template>
  <v-menu
    ref="menu"
    v-model="menu"
    offset-y
    transition="scale-transition"
    max-width="290px"
    min-width="290px"
    :close-on-content-click="false"
  >
    <template v-slot:activator="{ on }">
      <v-text-field
        v-model="dateFormatted"
        v-mask="'##/##/####'"
        v-on="on"
        dense
        outlined
        hide-details
        prepend-inner-icon="event"
        :label="label"
        :tabindex="tabindex"
        :value="value"
        @blur="onblur"
        @input="oninput"
      />
    </template>
    <v-date-picker 
      v-model="date" 
      no-title 
      @input="menu = false"
    />
  </v-menu> 
</template>

<script lang="ts">
import Vue from 'vue'
export default Vue.extend({
  props: {
    label: String,
    hideDetails: {
      type: [String, Boolean],
      default: false
    },
    noResize: {
      type: Boolean,
      default: true
    },
    value: String,
    hint: String,
    tabindex: [String, Number]
  },
  data() {
    return {
      menu: undefined,
      date: undefined
    }
  },
  watch: {
    date(val) {
      if (val)
        this.dateFormatted = this.formatDate(val);
    },
    value(val) {
      this.date = val
    }
  },
  computed: {
    dateFormatted: {
      get(): string { 
        return this.formatDate(this.value); 
      },
      set(val: string) { 
        this.$emit('input', this.parseDate(val)); 
      }
    },
  },
  methods: {
    oninput(val) {
      this.date = this.parseDate(val);      
      this.$emit('input', this.date);
    },
    onblur() {
      if (!this.date) 
        this.date = this.parseDateForce(this.dateFormatted)
    },
    formatDate (date) {
      if (!date) return null
      const [year, month, day] = date.split('-')
      return `${day}/${month}/${year}`
    },
    parseDate (date) {
      if (!date || (date.length < 10))
        return null;
      const [day, month, year] = date.split('/')

      const result = `${year}-${month.padStart(2, '0')}-${day.padStart(2, '0')}`;
      const nDate = new Date(result);
      if (!(nDate.getTime() === nDate.getTime()))
        return null;
      return result;
    },
    parseDateForce (date) {
      if (!date || (date.length < 8))
        return null;
      const [day, month, year] = date.split('/')
      let result
      if (year >= 70) 
        result = `${year.padStart(4, '1900')}-${month.padStart(2, '0')}-${day.padStart(2, '0')}`;
      else
        result = `${year.padStart(4, '2000')}-${month.padStart(2, '0')}-${day.padStart(2, '0')}`;
      const nDate = new Date(result);
      if (!(nDate.getTime() === nDate.getTime()))
        return null;
      return result;
    },
  },
})
</script>

пакет. json

{
  "name": "framework-ats",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint",
    "electron:build": "vue-cli-service electron:build",
    "electron:serve": "vue-cli-service electron:serve",
    "postinstall": "electron-builder install-app-deps",
    "postuninstall": "electron-builder install-app-deps"
  },
  "main": "background.ts",
  "dependencies": {
    "@rauschma/stringio": "^1.4.0",
    "@types/lodash": "^4.14.149",
    "ajv-i18n": "^3.5.0",
    "core-js": "^3.4.4",
    "lodash": "^4.17.15",
    "node-firebird": "^0.8.9",
    "typed-rest-client": "^1.7.1",
    "typescript-ioc": "^1.2.6",
    "v-money": "^0.8.1",
    "vue": "^2.6.10",
    "vue-class-component": "^7.2.2",
    "vue-form-json-schema": "^2.5.0",
    "vue-property-decorator": "^8.3.0",
    "vue-router": "^3.1.5",
    "vue-the-mask": "^0.11.1",
    "vuetify": "^2.1.0"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "^4.1.0",
    "@vue/cli-plugin-eslint": "^4.1.0",
    "@vue/cli-plugin-router": "^4.1.0",
    "@vue/cli-plugin-typescript": "^4.2.2",
    "@vue/cli-service": "^4.1.0",
    "@vue/eslint-config-typescript": "^4.0.0",
    "babel-eslint": "^10.0.3",
    "electron": "^6.0.0",
    "eslint": "^5.16.0",
    "eslint-plugin-vue": "^5.0.0",
    "material-design-icons-iconfont": "^5.0.1",
    "sass": "^1.19.0",
    "sass-loader": "^8.0.0",
    "typescript": "~3.7.5",
    "vue-cli-plugin-electron-builder": "^1.4.4",
    "vue-cli-plugin-vuetify": "^2.0.4",
    "vue-template-compiler": "^2.6.10",
    "vuetify-loader": "^1.3.0"
  }
}

tsconfig. json:

{
  "compilerOptions": {
    "target": "es6",
    "module": "commonjs",
    "jsx": "preserve",
    "importHelpers": true,
    "moduleResolution": "node",
    "experimentalDecorators": true,
    "allowJs": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "sourceMap": true,
    "baseUrl": ".",
    "typeRoots": [
      "./node_modules/@types",
      "./node_modules/vuetify/types"
    ],
    "types": [
      "webpack-env",
      "vuetify"
    ],
    "paths": {
      "@/*": [
        "src/*"
      ]
    },
    "lib": [
      "esnext",
      "dom",
      "dom.iterable",
      "scripthost"
    ]
  },
  "include": [
    "src/**/*.ts",
    "src/**/*.tsx",
    "src/**/*.vue",
    "tests/**/*.ts",
    "tests/**/*.tsx"
  ],
  "exclude": [
    "node_modules"
  ]
}

vue .config.ts:

module.exports = {
  "devServer": {
    "disableHostCheck": true
  },
  "transpileDependencies": [
    "vuetify"
  ]
}

1 Ответ

0 голосов
/ 28 февраля 2020

Исправление было на самом деле простым, хотя его было очень трудно найти: https://github.com/vuejs/vue-cli/issues/5227

Чтобы решить проблему, необходимо было изменить .eslintrc.js, добавив "parser": "babel-eslint" к parserOptions:

module.exports = {
    "env": {
        "browser": true,
        "es6": true,
        "node": true
    },
    "extends": [
        "eslint:recommended",
        "plugin:@typescript-eslint/eslint-recommended",
        "plugin:@typescript-eslint/recommended",
        "plugin:vue/essential"
    ],
    "globals": {
        "Atomics": "readonly",
        "SharedArrayBuffer": "readonly"
    },
    "parserOptions": {
        "parser": "babel-eslint",
        "ecmaVersion": 6,
        "sourceType": "module",
        "ecmaFeatures": {
            "modules": true
        }
    },
    "plugins": [
        "vue"
    ],
    "rules": {
        "no-console": "off",
        "@typescript-eslint/indent": "off"
    }
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...