使用Webpack在全球范围内公开Vue

时间:2020-01-23 23:32:52

标签: javascript ruby-on-rails vue.js webpack

我正在使用旧版Rails应用程序,该应用程序已部分迁移为使用Webpacker和Vue。我们也有一个通过CDN加载的旧脚本。该脚本也需要使用Vue,但是我们不希望将Vue捆绑到其中,而只使用旧版Rails应用程序中已经存在的Vue。

我已经遵循了这个问题How to expose Vue as global object,并且到了这一点,我使用暴露加载程序在Vue.default公开了Vue对象。本质上,暴露的“ Vue”对象实际上是Module,而真正的Vue对象嵌套在Vue.default中。

我遵循了所有可以找到的文档和文章,从而达到了这一点。这些是我能找到的最舒适的地方:https://bibwild.wordpress.com/2019/08/01/dealing-with-legacy-and-externally-loaded-code-in-webpacker/

这似乎不太理想,我想知道是否存在直接暴露Vue的“更正确”方法,即不嵌套在Module默认值中。

我尝试过的事情

我从头开始创建了一个新的Rails 6应用程序。通过以下方式添加JS依赖项后:

yarn install
yarn add vue
yarn add -D expose-loader
yarn add -D webpack-dev-serer
rails webpacker:install

我将Exposure-loader配置添加到config/webpack/development.js

environment.loaders.append('expose', {
  test: require.resolve('vue'),
  use: [{
      loader: 'expose-loader',
      options: 'Vue'
  }]
})

然后我搭建了一个页面并使其成为根目录。

然后在app/javascript/packs/application.js创建了一个入口JS文件

import Vue from 'expose-loader?Vue!vue'
console.log({ pack: Vue })

在应用程序布局的javascript_pack_tag 'application'下,我有:

<script>
  try {
    console.log({ layout: Vue })
  } catch (error) {
    console.warn('Global Vue not found')
  }
</script>

现在在浏览器控制台中,我得到

{ pack: ƒ Vue(options) }
{ layout: Module
    default: ƒ Vue(options) }

我还为config/webpack/development.jsexpose-loader中尝试了不同的配置,例如:

  test: require.resolve('vue/dist/vue.esm.js')
// or
  test: require.resolve('vue/dist/vue.esm.js').default
// or
  test: require.resolve('expose-loader?Vue!vue')
// and different permutations of that.

我尝试的另一种方法是将Vue从我的application.js包文件直接推到window对象中。那行得通,但似乎也错了。有更好的方法吗?

问题

如何公开Webpacker托管的Vue对象,以便任何非Webpacker托管的脚本都能看到它?即使其在window对象上可用。

1 个答案:

答案 0 :(得分:1)

我已经设法在 webpack 中使用以下配置规则来做到这一点

{
  test: require.resolve("vue/dist/vue.esm.js"),
  loader: "expose-loader",
  options: {
    exposes: [{
      globalName: "Vue",
      moduleLocalName: "default",
    }]
  },
},

moduleLocalName 只是从属性 default 中提取 Vue 并用 globalName 公开它,这样当你访问 window.Vue 时它就会在那里