Vue: Kode JS yang dihasilkan salah oleh TypeScript dan AMD (UMD) - versi 2

Dibuat pada 4 Jan 2018  ·  3Komentar  ·  Sumber: vuejs/vue

Versi: kapan

2.5.13

Tautan reproduksi

https://github.com/80LevelElf/VueProblemApp

Langkah-langkah untuk mereproduksi

Jalankan saja aplikasinya dengan membuka
/VueProblemApp/VueProblemApp/index.html file dan Anda akan melihat kesalahan di Konsol.

Apa yang diharapkan?

Kompiler TypeScript harus menggunakan pengetikan Vue dan menghasilkan kode yang tepat.

Apa yang sebenarnya terjadi?

Kode JS yang dihasilkan tidak benar (lihat komentar untuk penjelasan detail).


Beberapa hari yang lalu saya membuat kode JS yang dihasilkan salah oleh TypeScript dan bug AMD (UMD) (klik tautan untuk melihat penjelasan detail masalah).

Saya mendapat jawaban dari @yyx990803 , tetapi saya seorang pemula di JS dan tidak melakukannya dengan benar sejak pertama kali.
Dan jika saya mendapatkannya sekarang, masalahnya masih relevan.

Evan menjawab saya:

Tampaknya tidak ada apa pun di konfigurasi Anda yang mengarahkan modul "vue" ke versi UMD vue.js yang Anda sertakan sendiri. Jadi kompiler TS menyelesaikannya dari node_modules/vue dan menggunakan bidang "utama" di package.json, yang merupakan build CommonJS. Anda perlu menentukan pemetaan menggunakan compilerOptions.paths di tsconfig Anda.

Jadi jika saya mendapatkan Evan yang benar, dia berpikir bahwa RequireJS mengunduh file vue.js yang salah.
Yang benar adalah untuk sistem modul UMD/AMD, tetapi kompiler TS membuat referensi ke file vue.js untuk sistem modul CommonJS. Inilah mengapa saya mendapatkan kesalahan.

Tapi itu tidak benar. Kompiler TS hanya membuat referensi ke

Situsku/

dan dalam kasus saya adalah:

mySite/vue.js

tidak peduli apa file vue.js itu. Jadi jika tidak ada vue.js di tautan ini akan ada kesalahan 404.

Juga, saya mencoba mengubah konfigurasi utama di node_modules/vue/package.json seperti itu: "main": "dist/vue.js" dan itu memberi saya kesalahan yang sama.

Saya telah memeriksa file vue.js yang dimuat oleh RequireJS dan itu adalah file yang tepat . RequireJS menguraikannya dengan benar, masalahnya ada di pengetikan.

Juga jika saya melakukan impor seperti ini (seperti yang ditawarkan @Micene09 ):

import { Vue } from "vue-property-decorator";

Semuanya berfungsi dengan baik dengan memuat file vue.js yang sama di mySite/vue.js.
Jadi jika saya membuat Anda benar masalahnya masih tetap ada.

Komentar yang paling membantu

Saya mengalami masalah yang sama.

Dari pemahaman saya, file vue.js seharusnya mengatur variabel exports.default seperti yang dilakukan komponen kelas-vue.

vue-class-component.js (Baris 192):
exports['default'] = Component$1;

File komponen kelas-vue memiliki kasus khusus untuk menangani ekspor default yang hilang dari Vue, itulah sebabnya ia berfungsi.

vue-class-component.js (Baris 12):
Vue = Vue && Vue.hasOwnProperty('default') ? Vue['default'] : Vue;

Sayangnya, kompiler TypeScript 2.5 tidak menampilkan kasus khusus untuk menangani default yang hilang. Namun, TypeScript 2.7 memiliki opsi baru ( esModuleInterop ) yang memperbaiki masalah ini.

{
    "compilerOptions": {
        "module": "amd",
        "esModuleInterop": true,
        ...
    },
    ...
}

Dengan esModuleInterop disetel ke true , output berisi fungsi yang disebut __importDefault , yang menangani properti default yang hilang dengan benar.

var __importDefault = (this && this.__importDefault) || function (mod) {
  return (mod && mod.__esModule) ? mod : { "default": mod };
}
define(["require", "exports", "vue"], function (require, exports, vue_1) {
  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  vue_1 = __importDefault(vue_1);
  var app = new vue_1.default({
        ...
  });
});

Semua 3 komentar

Maaf, tetapi ini benar-benar pertanyaan di luar cakupan untuk pengaturan yang sangat spesifik yang tidak boleh diselesaikan dalam masalah. Masalah hanya untuk laporan bug yang berasal dari Vue itu sendiri.

@80LevelElf -- Saya memecahkan ini (untuk saat ini) dengan melakukan hal berikut:

import { VueConstructor } from "vue";
const Vue = require("vue") as VueConstructor;  // cast as VueConstructor to get typings. 

const app = new Vue({
  template: "<h1>Hello World</h1>
});

@yyx990803 -- Saya dalam situasi yang sama, tetapi berbeda. Saya menggunakan commonjs keluaran dari TypeScript (tanpa webpack). Satu kesamaan antara OP dan saya adalah bahwa kami berdua menggunakan opsi TypeScript baseUrl . Pasti ada yang salah dengan impor standar di TypeScript.

Saya juga menggunakan Vue 2.5.13. Saya sedang menyiapkan SSR di Node 8.9.3 dan TypeScript 2.6. tsconfig.json terlihat seperti ini:

{
  "compilerOptions": {
    "outDir": "build",
    "target": "es6",
    "module": "commonjs",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "rootDir": "./src",
    "baseUrl": "./src",
    "noUnusedLocals": true
  },
  "exclude": [
    "node_modules",
    "typings"
  ]
}

Saya mencoba sejumlah solusi lain, termasuk mencoba memuat file vue.esm.js melalui properti compilerOptions.paths , tanpa hasil. Saya mendapatkan kesalahan vue_1.default is not a constructor sama persis dengan OP.

Saya telah mengumpulkan reproduksi di sini dan membuka edisi baru

Saya mengalami masalah yang sama.

Dari pemahaman saya, file vue.js seharusnya mengatur variabel exports.default seperti yang dilakukan komponen kelas-vue.

vue-class-component.js (Baris 192):
exports['default'] = Component$1;

File komponen kelas-vue memiliki kasus khusus untuk menangani ekspor default yang hilang dari Vue, itulah sebabnya ia berfungsi.

vue-class-component.js (Baris 12):
Vue = Vue && Vue.hasOwnProperty('default') ? Vue['default'] : Vue;

Sayangnya, kompiler TypeScript 2.5 tidak menampilkan kasus khusus untuk menangani default yang hilang. Namun, TypeScript 2.7 memiliki opsi baru ( esModuleInterop ) yang memperbaiki masalah ini.

{
    "compilerOptions": {
        "module": "amd",
        "esModuleInterop": true,
        ...
    },
    ...
}

Dengan esModuleInterop disetel ke true , output berisi fungsi yang disebut __importDefault , yang menangani properti default yang hilang dengan benar.

var __importDefault = (this && this.__importDefault) || function (mod) {
  return (mod && mod.__esModule) ? mod : { "default": mod };
}
define(["require", "exports", "vue"], function (require, exports, vue_1) {
  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  vue_1 = __importDefault(vue_1);
  var app = new vue_1.default({
        ...
  });
});
Apakah halaman ini membantu?
0 / 5 - 0 peringkat