当前位置: 首页 > 知识库问答 >
问题:

将插件与Rollup绑定,但具有重复的Vue。在客户端应用程序包(Nuxt)中导入的js包

巫马淳
2023-03-14

亲爱的堆栈溢出/Vue。js/Rollup社区

对于使用Vue和Rollup的主插件开发人员来说,这可能是一个难题。我将非常明确地写下这个问题,希望它能在未来帮助像我这样的noob。

我有一个简单的插件,可以帮助表单验证。该插件中的一个组件导入Vue,以便通过编程创建一个组件,并在装载时附加到DOM,如下所示:

import Vue from 'vue'
import Notification from './Notification.vue' /* a very simple Vue component */
...
mounted() {
  const NotificationClass = Vue.extend(Notification)
  const notificationInstance = new NotificationClass({ propsData: { name: 'ABC' } })
  notificationInstance.$mount('#something')
}

这按预期工作,并且此插件使用Rollup与如下配置捆绑在一起:

import vue from 'rollup-plugin-vue'
import babel from 'rollup-plugin-babel'
import { terser } from 'rollup-plugin-terser'
import resolve from 'rollup-plugin-node-resolve'
import commonjs from 'rollup-plugin-commonjs'

export default {
  input: 'src/index.js',
  output: {
    name: 'forms',
    globals: {
      vue: 'Vue'
    }
  },
  plugins: [
    vue(),
    babel(),
    resolve(),
    commonjs(),
    terser()
  ],
  external: ['vue']
}

如你所见,Vue。js在这个捆绑包中被外部化了。其目的(和假设)是,导入此插件的客户端应用程序将在Vue上运行,因此无需在此处捆绑(假设)。

非常简单的src/index。bundler使用的js如下:

import Form from './Form.vue'

export default {
  install(Vue, _) {
    Vue.component('bs-form', Form)
  }
}

Rollup创建2个文件(一个esm和一个umd),并在插件包中引用它们。json文件如下:

  "name": "bs-forms",
  "main": "./dist/umd.js",
  "module": "./dist/esm.js",
  "files": [
    "dist/*"
  ],
  "scripts": {
    "build": "npm run build:umd & npm run build:es",
    "build:es": "rollup --config rollup.config.js --format es --file dist/esm.js",
    "build:umd": "rollup --config rollup.config.js --format umd --file dist/umd.js"
  }

到目前为止,一切都按预期工作,并且包生成得很好。

客户端应用程序(Nuxt SSR)通过在插件文件中的一个非常简单的导入来导入这个插件(因为它正在开发中,所以使用npm链接):

/* main.js*/
import Vue from 'vue'

import bsForms from 'bs-forms'
Vue.use(bsForms)

此插件文件(main.js)作为插件添加到nuxt.config.js:

// Nuxt Plugins
...
plugins: [{src: '~/plugins/main'}]
...

一切仍按预期运行,但问题来了:

我想客户端应用程序可以配置其webpack配置以删除此重复模块。也许通过使用Dedupe插件之类的东西?有人能建议如何最好地处理这样的情况吗?

但我真正想了解的是,首先捆绑插件的最佳实践,这样客户端就不必更改其配置中的任何内容,只需导入该插件并继续。

我知道导入Vue。插件中的js一开始可能不是一件好事情。但是,这样的导入可能还有其他原因,例如,想象一下插件可以用Typescript和Vue编写。js/Typescript是使用Vue编写的。extend语句(见下文)也会导入Vue(以便启用类型接口):

import Vue from 'vue'

const Component = Vue.extend({
  // type inference enabled
})

所以这是一个很长的问题。请Rollup的大师们,通过建议处理此类情况的最佳实践方法(或您的方法)来帮助我和社区。

非常感谢。

共有2个答案

向俊贤
2023-03-14

我用一个有趣的警告来解决这个问题:

当插件通过NPM包使用时,不会导入重复的Vue包(由npm install-保存安装

但是,在开发过程中,如果您使用包vie npm link(如npm link

如果将来遇到类似问题,请尝试发布和导入您的包,看看是否有什么不同。

谢谢你!

谭绍晖
2023-03-14

我有同样的问题,我发现@vatson的这个答案非常有帮助

您的问题是“npm link”、nodejs模块加载的性质以及对来自不同地方的多个实例的vue不容忍的组合。

简短介绍如何在nodejs中导入。如果您的脚本具有某种库导入,那么nodejs最初会在local node_modules文件夹中查找,如果local node_modules不包含所需的依赖项,那么nodejs会转到上面的文件夹,在那里查找node_模块和您导入的依赖项。

您不需要在NPM上发布您的包。如果您使用npm pack在本地生成包,然后将其安装在您的其他项目npm install /absolute_path_to_your_local_package/your_package_name.tgz中就足够了。如果您更新了包中的某些内容,您可以在其他项目中重新安装它,并且一切都应该正常。

以下是有关npm-packnpm-linkhttps://stackoverflow.com/a/50689049/6072503.

 类似资料:
  • 我无法在任何vue组件中导入引导(使用最新的nuxtjs)。我得到: 我的(简单)组件是: 我真的被卡住了。你有什么想法或建议吗?

  • 我有一个新安装的VITE应用程序。 错误显示: [vite]避免深度导入“vuelidate/lib/validators”(由/src/App.vue导入),因为“vuelidate”已由vite预先优化到单个文件中。倾向于直接从模块条目导入: 导入{…}来自“vuelidate” 如果依赖项需要深度导入才能正常工作,请将深度路径添加到optimizeDeps。包括在vite中。配置。js。 主

  • 我需要一个用于java spring应用程序的graphQL客户端,以与另一个基于graphQL API的微服务通信。我知道Apollo Android,但它似乎没有用maven实现(也许你知道maven的一些链接或示例等)。有什么想法和建议吗?提前感谢!

  • 问题内容: 我在Javascript中使用以下代码进行Ajax调用: 我也想在Java中做到这一点。基本上,我想编写一个Java客户端应用程序,该应用程序通过Ajax调用将该数据发送到服务器。 如何在Java中执行Ajax? 问题答案: AJAX与任何其他HTTP调用均没有不同。您基本上可以从Java发布相同的URL,就目标服务器而言,这无关紧要: 上面的代码或多或少与您的jQuery AJAX调

  • 我想创建一个gradle java应用程序,它从一个openAPI规范文件生成一个客户端,并使用该客户端。所以我用gradle init创建了一个java应用程序(类型:应用程序,语言:Java,DSL:groovy,测试框架:JUnit Jupiter,项目名称:简单-java-app,包结构:)。 我可以用一个包和一个类创建一个新的源文件夹。并使用以下 主类可以访问: 现在,我尝试对opena

  • 我的就像bellow: 但让我大喊错误: