vuejs / vue-loader

📦 Webpack loader for Vue.js components
MIT License
4.99k stars 914 forks source link

Vue3 + <script setup> + typescript = confused imports/exports error #1954

Closed Colisan closed 2 years ago

Colisan commented 2 years ago

Hi, I encounter the following, very puzzling, build&runtime error :

Files

index.ts

import { createApp } from "vue";
import test from "./test.ce.vue";

console.log("imported");
console.log("imported", test);

export const toto = "toto";

createApp(test).mount(document.body);

test.ce.vue

<script setup lang="ts">
    import { toto } from './index';

    const greeting= 'Hello ' + toto + ' !';
</script>

<template>
  <p class="greeting">{{ greeting }}</p>
</template>

<style>
.greeting {
  color: red;
  font-weight: bold;
}
</style>

webpack.config.js

const path = require('path');
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { VueLoaderPlugin } = require("vue-loader");

module.exports = {
  entry: './src/index.ts',
  mode: "production",
  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader'
      },
      {
        test: /\.tsx?$/,
        use: [{loader: 'ts-loader', options: {onlyCompileBundledFiles: true}}],
      },
      {
        test: /\.jsx?$/,
        use: [
          {
            loader: "babel-loader",
          },
        ],
      },
      {
        test: /\.s[ac]ss$/i,
        use: [
          "style-loader",
          "css-loader",
          "sass-loader",
        ],
      },
      {
        test: /\.css$/i,
        use: [
          "style-loader",
          "css-loader",
        ],
      },
    ],
  },
  resolve: {
    extensions: ['.tsx', '.ts', '.js'],
  },
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist'),
  },
  plugins: [
    new VueLoaderPlugin(),
    new HtmlWebpackPlugin({
      title: "MAIN UI",
      scriptLoading: "module",
      template: "src/index.ejs",
      filename: "index.html",
    }),
  ],
};

tsconfig.json

{
    "compilerOptions": {
      "outDir": "./dist/",
      "noImplicitAny": true,
      "module": "es2020",
      "target": "es5",
      "jsx": "preserve",
      "allowJs": true,
      "moduleResolution": "node"
    }
  }

Build Error

WARNING in ./src/test.ce.vue?vue&type=script&setup=true&lang=ts 1:0-205
export 'default' (reexported as 'default') was not found in '-!../node_modules/ts-loader/index.js??clonedRuleSet-1.use[0]!../node_modules/vue-loader/dist/index.js??ruleSet[1].rules[8].use[0]!./test.ce.vue?vue&type=script&setup=true&lang=ts' (possible exports: toto)
 @ ./src/test.ce.vue 1:0-69 2:0-64 2:0-64 7:49-55
 @ ./src/index.ts 2:0-33 4:24-28 6:10-14

When building, somehow the loader think that the exports from the vue file are instead the exports from the index.ts file. The same happen in another big project where the .vue export seems to be confused from any random exports in any random .ts file.

Maybe there's a conflit between vue-loader and ts-loader? Maybe my configuration is wrong?

Workaround

If I replace the script with a non-Typescript one:

<script setup>
    import { toto } from './index';

    const greeting= 'Hello ' + toto + ' !';
</script>

It works fine and without error. However, not using Ts is not an option in my context and I'd prefer if we could fix the causes instead of dodging the consequences =)

vue-bot commented 2 years ago

Hello, thank you for taking time filling this issue!

However, we kindly ask you to use our Issue Helper when creating new issues, in order to ensure every issue provides the necessary information for us to investigate. This explains why your issue has been automatically closed by me (your robot friend!).

I hope to see your helper-created issue very soon!