Vue: Código JS gerado incorretamente por TypeScript e AMD (UMD) - versão 2

Criado em 4 jan. 2018  ·  3Comentários  ·  Fonte: vuejs/vue

Versão

2.5.13

Link de reprodução

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

Passos para reproduzir

Basta executar o aplicativo abrindo o
/VueProblemApp/VueProblemApp/index.html arquivo e você verá o erro no console.

O que é esperado?

O compilador Typescript deve pegar tipificações Vue e produzir o código certo.

O que realmente está acontecendo?

O código JS resultante não está correto (consulte os comentários para explicação detalhada).


Vários dias atrás, criei o código JS gerado errado pelo bug do TypeScript e AMD (UMD) (clique no link para ver a explicação detalhada do problema).

Recebi uma resposta de @ yyx990803 , mas sou um novato no JS e não
E se entendi agora, o problema ainda é relevante.

Evan me respondeu:

Parece não haver nada em sua configuração que aponte o módulo "vue" para o build UMD vue.js que você incluiu. Portanto, o compilador TS está resolvendo-o a partir de node_modules / vue e usando o campo "principal" em package.json, que é um build CommonJS. Você precisa especificar o mapeamento usando compilerOptions.paths em seu tsconfig.

Então, se entendi bem o Evan, ele pensou que o RequireJS baixou o arquivo vue.js errado.
O correto é para o sistema de módulo UMD / AMD, mas o compilador TS faz uma referência ao arquivo vue.js para o sistema de módulo CommonJS. É por isso que cometi o erro.

Mas não está certo. O compilador TS apenas faz uma referência a

meu site/

e no meu caso é:

mySite / vue.js

não importa o arquivo vue.js. Portanto, se não houver vue.js neste link, haverá o erro 404.

Além disso, tento alterar a configuração principal em node_modules / vue / package.json assim: "main": "dist / vue.js" e me dá o mesmo erro.

Verifiquei o arquivo vue.js que está sendo carregado pelo RequireJS e é o arquivo correto . RequireJS analisa direito, o problema está nas digitações.

Além disso, se eu fizer a importação desta forma (como @ Micene09 oferecido):

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

Tudo funciona bem com o carregamento do mesmo arquivo vue.js em mySite / vue.js.
Então, se eu entendi direito, o problema ainda permanece.

Comentários muito úteis

Eu tive o mesmo problema.

Do meu entendimento, o arquivo vue.js deve estar configurando a variável exports.default como o componente vue-class faz.

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

O arquivo de componente de classe vue tem um caso especial para lidar com a exportação padrão ausente do Vue, e é por isso que funciona.

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

Infelizmente, o compilador TypeScript 2.5 não produz um caso especial para lidar com o padrão ausente. No entanto, o TypeScript 2.7 tem uma nova opção ( esModuleInterop ) que corrige esse problema.

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

Com esModuleInterop definido como true , a saída contém uma função chamada __importDefault , que trata a propriedade padrão ausente corretamente.

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

Todos 3 comentários

Sinto muito, mas esta é realmente uma questão fora do escopo para uma configuração muito específica que não deve ser resolvida em problemas. Os problemas são para relatórios de bugs originados apenas do próprio Vue.

@ 80LevelElf -

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 - Estou em uma situação semelhante, mas diferente. Estou usando a saída commonjs do TypeScript (sem webpack). Uma semelhança entre OP e I é que ambos estamos usando a opção TypeScript baseUrl . Algo está definitivamente errado com a importação padrão no TypeScript.

Eu também estou usando o Vue 2.5.13. Estou configurando o SSR no Node 8.9.3 e TypeScript 2.6. Meu tsconfig.json tem esta aparência:

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

Tentei uma série de outras soluções alternativas, incluindo tentar carregar o arquivo vue.esm.js por meio da propriedade compilerOptions.paths , sem sucesso. Eu estava recebendo exatamente o mesmo erro vue_1.default is not a constructor que OP.

Eu montei uma reprodução aqui e abri uma nova edição

Eu tive o mesmo problema.

Do meu entendimento, o arquivo vue.js deve estar configurando a variável exports.default como o componente vue-class faz.

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

O arquivo de componente de classe vue tem um caso especial para lidar com a exportação padrão ausente do Vue, e é por isso que funciona.

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

Infelizmente, o compilador TypeScript 2.5 não produz um caso especial para lidar com o padrão ausente. No entanto, o TypeScript 2.7 tem uma nova opção ( esModuleInterop ) que corrige esse problema.

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

Com esModuleInterop definido como true , a saída contém uma função chamada __importDefault , que trata a propriedade padrão ausente corretamente.

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({
        ...
  });
});
Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

bdedardel picture bdedardel  ·  3Comentários

lmnsg picture lmnsg  ·  3Comentários

wufeng87 picture wufeng87  ·  3Comentários

seemsindie picture seemsindie  ·  3Comentários

gkiely picture gkiely  ·  3Comentários