在库中使用 vue 槽使 currentRenderingInstance 为空

Using vue slots in library gives currentRenderingInstance is null

我正在使用 Rollup 创建一个 Vue 组件库,但是当我使用 slots 时出现以下错误:

Uncaught (in promise) TypeError: currentRenderingInstance is null

我在我的库中制作了一个非常简单的组件:

<script setup></script>

<template>
  <button>
    <slot></slot>
  </button>
</template>

<style scoped></style>

那我就简单这样用了:

<ExampleComponent>
  Text
</ExampleComponent>

如果我删除插槽并用道具或硬编码文本替换它,一切正常。

这是我的 rollup.config.js:

import { defineConfig } from 'rollup';
import path from 'path';

import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import postcss from 'rollup-plugin-postcss';
import vue from 'rollup-plugin-vue';

// the base configuration
const baseConfig = {
  input: 'src/entry.js',
};

// plugins
const plugins = [
  vue(),
  resolve({
    extensions: ['.js', '.jsx', '.ts', '.tsx', '.vue'],
  }),
  // process only `<style module>` blocks.
  postcss({
    modules: {
      generateScopedName: '[local]___[hash:base64:5]',
    },
    include: /&module=.*\.css$/,
  }),
  // process all `<style>` blocks except `<style module>`.
  postcss({ include: /(?<!&module=.*)\.css$/ }),
  commonjs(),
];

const external = ['vue'];
const globals = {
  vue: 'Vue',
};

export default [
  // esm
  defineConfig({
    ...baseConfig,
    input: 'src/entry.esm.js',
    external,
    output: {
      file: 'dist/vue-my-lib.esm.js',
      format: 'esm',
      exports: 'named',
    },
    plugins,
  }),

  // cjs
  defineConfig({
    ...baseConfig,
    external,
    output: {
      compact: true,
      file: 'dist/vue-my-lib.ssr.js',
      format: 'cjs',
      name: 'VueMyLib',
      exports: 'auto',
      globals,
    },
    plugins,
  }),

  // iife
  defineConfig({
    ...baseConfig,
    external,
    output: {
      compact: true,
      file: 'dist/vue-my-lib.min.js',
      format: 'iife',
      name: 'VueMyLib',
      exports: 'auto',
      globals,
    },
    plugins,
  }),
];

对这个问题有什么想法吗?

经过一整天的搜索,我找到了解决方案(here and here)。在本地使用库(例如,通过 npm link)是一个问题,似乎同时有两个 Vue 实例(在项目和库之一上)。所以,解决办法就是通过webpack告诉项目具体使用自己的vue。

在我的例子中,我使用 Jetstream + Inertia,所以我编辑了 webpack.mix.js:

const path = require('path');

// ...

mix.webpackConfig({
    resolve: {
        symlinks: false,
        alias: {
            vue: path.resolve("./node_modules/vue"),
        },
    },
});

或者,如果您使用 vue-cli 创建项目,请编辑 vue.config.js:

const { defineConfig } = require('@vue/cli-service');
const path = require(path);

module.exports = defineConfig({
  // ...
  chainWebpack(config) {
    config.resolve.symlinks(false);
    config.resolve.alias.set("vue", path.resolve("./node_modules/vue"));
  }
}