亲爱的堆栈溢出/ Vue.js /汇总社区
对于使用Vue和Rollup的主插件开发人员来说,这可能是一个菜鸟问题。我会非常明确地写这个问题,希望它能帮助像我这样的其他国家在未来。
我有一个简单的插件,可以帮助表单验证。这个插件中的一个组件导入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上,因此没有必要将其捆绑在这里(假设)。
bundler使用的非常简单的src/index.js如下:
import Form from './Form.vue'
export default {
install(Vue, _) {
Vue.component('bs-form', Form)
}
}Rollup创建两个文件(一个esm和一个umd),并在插件package.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 )通过一个插件文件中非常简单的导入来导入这个插件(使用npm-link,因为它正在开发中):
/* 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'}]
...一切照常进行,但问题来了:

由于客户端是一个Nuxt应用程序,当然,默认情况下Vue是导入的,但是外部化的Vue模块(通过forms插件)也是在客户机中导入的。因此,客户端包中存在此包的复制。
我想客户端应用程序可以配置它的webpack配置,以删除这个重复的模块。也许是通过使用类似Dedupe插件之类的东西?有人能建议如何最好地处理这种情况吗?
但我真正想学的是,首先要捆绑插件的最佳实践,这样客户端就不必改变配置中的任何内容,只需导入这个插件就可以继续前进了。
我知道在插件中导入Vue.js可能不是一件好事。但是,像这样的导入可能还有其他原因,例如,假设插件可以用类型记录编写,而Vue.js / Typescript是通过使用Vue.extend语句编写的(参见下面),这些语句还导入Vue (以便启用类型接口):
import Vue from 'vue'
const Component = Vue.extend({
// type inference enabled
})这是一个很长的问题。请总结大师,帮助我和社区通过建议最佳实践方法(或您的方法)来处理这样的情况。
谢谢!
发布于 2020-03-12 11:45:58
我用一个有趣的警告来解决这个问题:
当通过NPM包(由npm install -save <plugin-name>安装)使用插件时,不会导入重复的Vue包。
但是,在开发过程中,如果使用vie npm链接(如npm link <plugin-name>),Vue将被导入两次,如原始问题中的图像所示。
将来遇到类似问题的用户,请尝试发布和导入您的包,看看它是否有任何不同。
谢谢!
发布于 2020-07-13 11:53:22
我也遇到了同样的问题,我发现@vatson的这个答案非常有用
您的问题是"npm链接“的结合、nodejs模块加载的性质以及来自不同地方的多个实例的vue不容忍。简介nodejs中的导入是如何工作的。如果您的脚本有某种类型的库导入,那么nodejs最初会在本地node_modules文件夹中查找,如果本地node_modules不包含所需的依赖项,那么nodejs会转到上面的文件夹中查找node_modules,并在那里找到导入的依赖项。
您不需要在NPM上发布您的软件包。如果您在本地使用npm pack生成包,然后将其安装到您的其他项目npm install /absolute_path_to_your_local_package/your_package_name.tgz中,这就足够了。如果您更新了包中的某些内容,您可以在其他项目中重新安装它,并且一切都应该正常工作。
这是关于npm pack和npm link https://stackoverflow.com/a/50689049/6072503之间区别的来源。
https://stackoverflow.com/questions/60561167
复制相似问题