egoist / poi

⚡A zero-config bundler for JavaScript applications.
https://poi.js.org
MIT License
5.22k stars 256 forks source link

Typecast in Vue SFC prop results in Babel error? #740

Open scbash opened 4 years ago

scbash commented 4 years ago

I'm relatively new to web development, so hopefully is a fairly trivial configuration change rather than a bug, but here goes...

I'm using Typescript in a Vue SFC, and I'm trying to enforce the type of a component property:

... snip ...
<script lang="ts">
import type { PropType } from 'vue'
import type { Emitter as MittEmitter } from 'mitt'
... snip ...
export default {
... snip ...
  props: {
    eventBus: {
      type: Object as PropType<MittEmitter>,
      required: true
    }
  },
... snip ...
}

This produces an error during poi --serve:

./src/components/Library.vue?vue&type=script&lang=ts)
Module build failed (from ./node_modules/poi/lib/webpack/babel-loader.js):
SyntaxError: .../src/components/Library.vue: Unexpected token, expected "," (68:19)

  66 |   props: {
  67 |     eventBus: {
> 68 |       type: Object as PropType<MittEmitter>,
     |                    ^
  69 |       required: true
  70 |     }
  71 |   },

which lead me to this VueJS Developers post implying Babel needs to be using the Typescript parser (search for "babel eslint parser"), but AFAICT the Poi Babel preset does use the Typescript parser?

My package.json is vanilla (just dependencies), and I'm not overriding any Poi defaults. I am working with Vue 3rc5, though AFAIK this code isn't Vue 3 specific. Other possibly relevant versions:

$ npx poi --version
poi/12.9.0 linux-x64 node-v13.13.0
$ node --version
v13.13.0
$ npm --version
6.14.4

It seems like I'm close, but obviously still missing something. I will very much appreciate any tips, thanks in advance!

scbash commented 4 years ago

Quick note (walking away from the computer always spawns new thoughts): in this case the mitt function also serves as a constructor, so

import mitt from 'mitt'
... snip ...
  props: {
    eventBus: {
      type: mitt,
      required: true
    }
  }

works around the problem, but for future use I'd like to know how to do the type cast as well... (Vue complains about a prop type mismatch at runtime, but does work)

scbash commented 4 years ago

Hm... Seems like something funny is going on with my babel-loader:

./src/components/Library.vue?vue&type=script&lang=ts)
Module build failed (from ./node_modules/poi/lib/webpack/babel-loader.js):
SyntaxError: /home/scbash/Development/delenn/delenn-app/src/components/Library.vue: Unexpected token (142:45)

  140 |       })
  141 | 
> 142 |       let getItems = new Promise<LibraryItem[]>((resolve, reject) => {
      |                                              ^
  143 |         browseServer(id, this.serverUrl, {}, (err: null|string, result: BrowseServerResult) => {
  144 |           if (err) {
  145 |             reject(err)

Ah ha! While I thought this wasn't related to Vue 3, of course I'm using vue-loader 16.0.0-beta5... that could easily be the source of these bugs! (to be clear, I haven't confirmed that, but it seems highly likely)

scbash commented 4 years ago

Downgrading to Vue 2 and vue-loader 15.9.3 did not fix the issue.

egoist commented 4 years ago

There's probably something going on with the default babel preset, I still need to investigate this furthur.

scbash commented 4 years ago

Thanks for keeping up with this. Looks to me like I'm running into babel/babel#6959, where babel is trying to interpret <...> as TSX. That lead me to poi/plugin-typescript, which worked but needed an update to fork-ts-checker-webpack-plugin to support Vue 3 (it worked but spewed errors because I don't have vue-template-compiler installed). I hacked together an update that works for me. There were some old config values that I couldn't figure out how to update, so it's probably not pull request ready.

Let me know what you think. Reading the Poi and Babel docs it seems like I might be able to disable enough TSX functionality to also work around the problem (the Babel issue has some tips), but I don't think I actually need Babel right now, so I'm happy with plugin-typescript.

github-actions[bot] commented 4 years ago

This issue has been marked as Stale, it will be closed in a week if there's no furthur activity.

wulucxy commented 3 years ago

@scbash @egoist got the same problem,how do you solve this?

scbash commented 2 years ago

As I mentioned above, my temporary fix was to patch ts-checker to a newer version than Poi shipped with. Unfortunately my long term solution was switching to Vite because the Vue 2 to Vue 3 transition became a little too complicated with Poi (at the time; it might be easier now...)