使用 Webpack 向全局公开 Vue

Die*_*zar 5 javascript ruby-on-rails webpack vue.js

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

我已经关注了这个问题如何将 Vue 公开为全局对象,我到了这一点,使用公开加载器,将 Vue 对象暴露在Vue.default. 本质上,暴露的“Vue”对象实际上是 aModule而真正的 Vue 对象嵌套在Vue.default.

我通过跟踪我能找到的所有文档和文章来达到这一点。这些是我能找到的最相关的:https : //bibwild.wordpress.com/2019/08/01/dealing-with-legacy-and-externally-loaded-code-in-webpacker/

这似乎不太理想,我想知道是否有一种“更正确”的方式直接暴露 Vue,即不嵌套在模块默认值中。

我试过的

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

yarn install
yarn add vue
yarn add -D expose-loader
yarn add -D webpack-dev-serer
rails webpacker:install
Run Code Online (Sandbox Code Playgroud)

我添加了暴露加载器配置 config/webpack/development.js

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

然后我搭建了一个页面并将其作为根路由。

然后在 app/javascript/packs/application.js

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

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

import Vue from 'expose-loader?Vue!vue'
console.log({ pack: Vue })
Run Code Online (Sandbox Code Playgroud)

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

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

我也试过在不同的configsconfig/webpack/development.jsexpose-loader,如:

{ pack: ƒ Vue(options) }
{ layout: Module
    default: ƒ Vue(options) }
Run Code Online (Sandbox Code Playgroud)

我尝试的另一种方法是将 Vue 从我的 application.js 包文件中直接推送到 window 对象中。这有效,但似乎也是错误的。有没有更好的办法?

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

小智 2

我已经设法通过 webpack 中的以下配置规则来做到这一点

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

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