custom script languages (such as coffeescript) no longer supported in vue 3.3?

349 Views Asked by At

UPDATE 2: This seems to be like an undocumented change to how the compiler works with the code in the tags (most likely unintentional, so probably a regression)

Here's how the compiler handles exceptions thrown by the parser in versions 3.2 and 3.3

version 3.2: https://github.com/vuejs/core/blob/3.2/packages/compiler-sfc/src/compileScript.ts#L202

    } catch (e) {
      // silently fallback if parse fails since user may be using custom
      // babel syntax
      return script
    }

version 3.3: https://github.com/vuejs/core/blob/main/packages/compiler-sfc/src/script/context.ts#L109

      } catch (e: any) {
        e.message = `[vue/compiler-sfc] ${e.message}\n\n${
          descriptor.filename
        }\n${generateCodeFrame(
          descriptor.source,
          e.pos + offset,
          e.pos + offset + 1
        )}`
        throw e
      }

version 3.2 fails silently (because it knows it could be a custom syntax), and version 3.3 just throws the error.

I posted an issue in the vuejs/core github if anyone is interested: https://github.com/vuejs/core/issues/8368


UPDATE: I created a repo to replicate the bug easily: https://github.com/Boux/vite-coffee-bug

git clone https://github.com/Boux/vite-coffee-bug.git
cd vite-coffee-bug
npm install
npm run build

I am using vitejs + vue for a simple project and I was trying to set it up with coffeescript as the scripting language, as I have done easily in the past, but when using vue 3.3 or above it seems to crash while it works fine in vue 3.2.

in my vite.config.js I simply use 2 plugins: @vitejs/plugin-vue (version 4.2.3) and a custom plugin that simply compiles the coffeescript code into javascript

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import CoffeeScript from "coffeescript"

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    {
      name: 'coffee_compile',
      transform: function(src, id) {

        // compile coffee files to js
        if (/\.coffee$/.test(id)) {
          var {js, sourceMap} = CoffeeScript.compile(src, { sourceMap: true })
          return { code: js, map: sourceMap }
        }

      }
    }
  ],
})

In my project i have src/App.vue:

<script lang='coffee'>
import { ref } from 'vue'

export default
  data: -> { count: ref(0) }
</script>

<template>
  <div>
    <button type="button" @click="count++">count is {{ count }}</button>
  </div>
</template>

<style scoped>

</style>

When I use vue 3.2, the @vitejs/plugin-vue uses what I assume is @vue/compiler-sfc to give me something like this:

import _sfc_main from "/Users/boux/repo/vite_coffee_bug/src/App.vue?vue&type=script&lang.coffee"
export * from "/Users/boux/repo/vite_coffee_bug/src/App.vue?vue&type=script&lang.coffee"
import { toDisplayString as _toDisplayString, createElementVNode as _createElementVNode, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"

function _sfc_render(_ctx, _cache) {
  return (_openBlock(), _createElementBlock("div", null, [
    _createElementVNode("button", {
      type: "button",
      onClick: _cache[0] || (_cache[0] = $event => (_ctx.count++))
    }, "count is " + _toDisplayString(_ctx.count), 1)
  ]))
}


import _export_sfc from 'plugin-vue:export-helper'
export default /*#__PURE__*/_export_sfc(_sfc_main, [['render',_sfc_render]])

Where it imports App.vue again on the first line, but only the script tag and it specifies that it's lang.coffee so I can then get that and compile it in the next plugin, and it works perfectly, if I'm using vue 3.2.

In vue 3.3, when @vitejs/plugin-vue calls @vue/compiler-sfc, it simply crashes with syntax errors, like it's trying to do something with the coffeescript code as if it were javascript instead of just importing and compiling it from coffeescript like it does in vue 3.2:

error during build:
SyntaxError: [vue/compiler-sfc] Missing semicolon. (5:6)

/Users/boux/repo/vite_coffee_bug/src/App.vue
3  |  
4  |  export default
5  |    data: -> { count: ref(0) }
   |        ^
6  |  </script>
7  |  
    at instantiate (/Users/boux/repo/vite_coffee_bug/node_modules/@babel/parser/lib/index.js:653:32)
    at constructor (/Users/boux/repo/vite_coffee_bug/node_modules/@babel/parser/lib/index.js:946:12)
    at Parser.raise (/Users/boux/repo/vite_coffee_bug/node_modules/@babel/parser/lib/index.js:3270:19)
    at Parser.semicolon (/Users/boux/repo/vite_coffee_bug/node_modules/@babel/parser/lib/index.js:3637:10)
    at Parser.parseExportDefaultExpression (/Users/boux/repo/vite_coffee_bug/node_modules/@babel/parser/lib/index.js:13759:10)
    at Parser.parseExport (/Users/boux/repo/vite_coffee_bug/node_modules/@babel/parser/lib/index.js:13663:25)
    at Parser.parseStatementContent (/Users/boux/repo/vite_coffee_bug/node_modules/@babel/parser/lib/index.js:12661:27)
    at Parser.parseStatementLike (/Users/boux/repo/vite_coffee_bug/node_modules/@babel/parser/lib/index.js:12549:17)
    at Parser.parseModuleItem (/Users/boux/repo/vite_coffee_bug/node_modules/@babel/parser/lib/index.js:12526:17)
    at Parser.parseBlockOrModuleBlockBody (/Users/boux/repo/vite_coffee_bug/node_modules/@babel/parser/lib/index.js:13121:36)
    at Parser.parseBlockBody (/Users/boux/repo/vite_coffee_bug/node_modules/@babel/parser/lib/index.js:13114:10)
    at Parser.parseProgram (/Users/boux/repo/vite_coffee_bug/node_modules/@babel/parser/lib/index.js:12437:10)
    at Parser.parseTopLevel (/Users/boux/repo/vite_coffee_bug/node_modules/@babel/parser/lib/index.js:12427:25)
    at Parser.parse (/Users/boux/repo/vite_coffee_bug/node_modules/@babel/parser/lib/index.js:14245:10)
    at Object.parse (/Users/boux/repo/vite_coffee_bug/node_modules/@babel/parser/lib/index.js:14286:38)
    at parse (/Users/boux/repo/vite_coffee_bug/node_modules/@vue/compiler-sfc/dist/compiler-sfc.cjs.js:15811:25)
    at new ScriptCompileContext (/Users/boux/repo/vite_coffee_bug/node_modules/@vue/compiler-sfc/dist/compiler-sfc.cjs.js:15827:43)
    at Object.compileScript (/Users/boux/repo/vite_coffee_bug/node_modules/@vue/compiler-sfc/dist/compiler-sfc.cjs.js:19766:15)
    at resolveScript (file:///Users/boux/repo/vite_coffee_bug/node_modules/@vitejs/plugin-vue/dist/index.mjs:285:31)
    at genScriptCode (file:///Users/boux/repo/vite_coffee_bug/node_modules/@vitejs/plugin-vue/dist/index.mjs:2471:18)
    at transformMain (file:///Users/boux/repo/vite_coffee_bug/node_modules/@vitejs/plugin-vue/dist/index.mjs:2284:54)
    at Object.transform (file:///Users/boux/repo/vite_coffee_bug/node_modules/@vitejs/plugin-vue/dist/index.mjs:2796:16)
    at file:///Users/boux/repo/vite_coffee_bug/node_modules/rollup/dist/es/shared/node-entry.js:24551:40

I'm not sure if this is a bug in the @vitejs/plugin-vue since vue 3.3 just got released, or if I'm missing some config options for the plugin.

in the vue 3.3 post: https://blog.vuejs.org/posts/vue-3-3#script-setup-typescript-dx-improvements, they do talk about changes to the compiler, so I'm thinking I should have an option to skip that step since I'm not using typescript

0

There are 0 best solutions below