Vue: Code JS généré incorrect par TypeScript et AMD (UMD) - version 2

Créé le 4 janv. 2018  ·  3Commentaires  ·  Source: vuejs/vue

Version

2.5.13

Lien de reproduction

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

Étapes à reproduire

Exécutez simplement l'application en ouvrant le
/VueProblemApp/VueProblemApp/index.html et vous verrez l'erreur dans la console.

Qu'est-ce qui est attendu ?

Le compilateur Typescript doit prendre les frappes Vue et produire le bon code.

Que se passe-t-il réellement ?

Le code JS résultant n'est pas correct (voir les commentaires pour une exploration détaillée).


Il y a plusieurs jours, j'ai créé le code JS généré incorrect par TypeScript et le bogue

J'ai reçu une réponse de @yyx990803 , mais je suis un novice du JS et je n'ai pas bien compris dès la première fois.
Et si je comprends tout de suite, le problème est toujours d'actualité.

Eva m'a répondu :

Il semble qu'il n'y ait rien dans votre configuration qui pointe le module "vue" vers la version UMD vue.js que vous avez incluse vous-même. Ainsi, le compilateur TS le résout à partir de node_modules/vue et utilise le champ "main" dans package.json, qui est une version CommonJS. Vous devez spécifier le mappage à l'aide de compilerOptions.paths dans votre tsconfig.

Donc, si j'ai raison, Evan a pensé que RequireJS téléchargeait le mauvais fichier vue.js.
Le bon est pour le système de module UMD/AMD, mais le compilateur TS fait référence au fichier vue.js pour le système de module CommonJS. C'est pourquoi j'ai eu l'erreur.

Mais ce n'est pas juste. Le compilateur TS fait simplement référence à

mon site/

et dans mon cas c'est :

monSite/vue.js

quel que soit le fichier vue.js. Donc, s'il n'y a pas de vue.js dans ce lien, il y aura l'erreur 404.

Aussi, j'essaye de changer la config principale dans node_modules/vue/package.json comme ça : "main": "dist/vue.js" et ça me donne la même erreur.

J'ai vérifié le fichier vue.js qui se charge par RequireJS et c'est le bon fichier . RequireJS l'analyse correctement, le problème réside dans les frappes.

Aussi si je fais l'import comme ceci (comme @Micene09 offert):

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

Tout fonctionne bien avec le chargement du même fichier vue.js dans mySite/vue.js.
Donc si je comprends bien, le problème persiste.

Commentaire le plus utile

Je suis tombé sur le même problème.

D'après ce que j'ai compris, le fichier vue.js devrait définir la variable exports.default comme le fait vue-class-component.

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

Le fichier vue-class-component a un cas particulier pour gérer l'exportation par défaut manquante de Vue, c'est pourquoi cela fonctionne.

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

Malheureusement, le compilateur TypeScript 2.5 ne génère pas de cas particulier pour gérer la valeur par défaut manquante. Cependant, TypeScript 2.7 a une nouvelle option ( esModuleInterop ) qui résout ce problème.

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

Avec esModuleInterop défini sur true , la sortie contient une fonction appelée __importDefault , qui gère correctement la propriété par défaut manquante.

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({
        ...
  });
});

Tous les 3 commentaires

Je suis désolé, mais c'est vraiment une question hors de portée pour une configuration très spécifique qui ne devrait pas être résolue dans les problèmes. Les problèmes concernent uniquement les rapports de bogues provenant de Vue elle-même.

@ 80LevelElf -- J'ai résolu ce problème (pour l'instant) en procédant comme suit :

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 -- Je suis dans une situation similaire, mais différente. J'utilise la sortie commonjs de TypeScript (pas de webpack). Une similitude entre OP et I est que nous utilisons tous les deux l'option TypeScript baseUrl . Quelque chose ne va vraiment pas avec l'importation standard dans TypeScript.

J'utilise aussi Vue 2.5.13. Je configure SSR sur Node 8.9.3 et TypeScript 2.6. Mon tsconfig.json ressemble à ceci :

{
  "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"
  ]
}

J'ai essayé un certain nombre d'autres solutions de contournement, notamment en essayant de charger le fichier vue.esm.js via la propriété compilerOptions.paths , sans succès. J'obtenais exactement la même erreur vue_1.default is not a constructor que OP.

J'ai rassemblé une reproduction ici et ouvert un nouveau numéro

Je suis tombé sur le même problème.

D'après ce que j'ai compris, le fichier vue.js devrait définir la variable exports.default comme le fait vue-class-component.

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

Le fichier vue-class-component a un cas particulier pour gérer l'exportation par défaut manquante de Vue, c'est pourquoi cela fonctionne.

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

Malheureusement, le compilateur TypeScript 2.5 ne génère pas de cas particulier pour gérer la valeur par défaut manquante. Cependant, TypeScript 2.7 a une nouvelle option ( esModuleInterop ) qui résout ce problème.

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

Avec esModuleInterop défini sur true , la sortie contient une fonction appelée __importDefault , qui gère correctement la propriété par défaut manquante.

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({
        ...
  });
});
Cette page vous a été utile?
0 / 5 - 0 notes