如何在 webpacker rails 中使用 ProvidePlugin?

Posted

技术标签:

【中文标题】如何在 webpacker rails 中使用 ProvidePlugin?【英文标题】:How to use ProvidePlugin in webpacker rails? 【发布时间】:2018-09-11 03:12:21 【问题描述】:

我目前正在尝试使用 webpack.ProvidePlugin,但似乎没有正确加载它。这是我的environment.js

var webpack = require("webpack");

const  environment  = require("@rails/webpacker");
const vueLoader = require("./loaders/vue");

environment.loaders.append("vue", vueLoader);

environment.plugins.append(
  "Provide", // arbitrary name
  new webpack.ProvidePlugin(
    Vue: "vue",
    _: "lodash"
  )
);

module.exports = environment;

还有我的文件Header.vue

<h1>_.capitalize(title) </h1>

错误:

vue.runtime.esm.js:587 [Vue warn]: Property or method "_" is not defined on
 the instance but referenced during render. Make sure that this property is 
reactive, either in the data option, or for class-based components, by 
initializing the property. 

【问题讨论】:

题外话:无需添加vue loader。它默认出现。查看我自己的代码,唯一的区别是您有“Provide”的第一个参数,我有“ProvidePlugin”。不知道这是否有区别。其次,为什么不直接在 vue 文件中导入 lodash 方法呢?可能问题是在编译 vue 文件时,webpack 看不到全局上下文。此外,根据 Vue 的常见做法,您应该在计算函数中进行大写 嗯,使用ProvidePlugin 的全部意义在于,您可以在全局范围内提供这些值,我没有导入 _ 的问题,除了不方便,某些常用模块不应该到处都是回购。 不,我的意思是只导入您使用的那些函数。然后,当 babel 为导入函数实现良好的 tree-shaking 算法时,你就不必重写任何东西了。但这只是一个建议。 @Kkulikovskis 我正在为其他事情做,而不是像 lodash 之类的事情 【参考方案1】:

你可以使用 Vue 的 vue-lodash 插件,它在 Vue 模板中提供了 lodash,你的代码就可以工作了。

安装它 (npm i vue-lodash) 并配置 Vue 以使用它:

import Vue from 'vue'
import VueLodash from 'vue-lodash'

Vue.use(VueLodash, options)

您可以在 Vue 模板中使用 lodash,就像在 Header.vue 中所做的那样:)

【讨论】:

谢谢,但我认为这回答了我的问题,为什么提供程序不起作用。【参考方案2】:

这不应与 webpacker、webpack 或 ProvidePlugin 相关。 您可以通过从您的组件(即在创建的钩子中)访问 _ 轻松检查这一点。

当您尝试从 template 引用该方法时,问题就开始了:

模板表达式是沙盒化的,只能访问诸如 Math 和 Date 等全局变量的白名单。您不应尝试在模板表达式中访问用户定义的全局变量。

为了使访问成为可能,您可以将 _ 添加到您的数据中:

  data: function () 
    return 
      _
    
  ,

但是,在 Vue 中不建议使用 _ 或 $ 作为前缀或名称,因为框架本身保留了很多这样的名称(Source):

以 _ 或 $ 开头的属性不会在 Vue 实例上代理,因为它们可能与 Vue 的内部属性和 API 方法发生冲突。您必须以 vm.$data._property 的身份访问它们。

Link1 Link2

因此,您可以只使用“lodash”而不是“_”。

environment.plugins.append(
  "Provide", // arbitrary name
  new webpack.ProvidePlugin(
    Vue: "vue",
    lodash: "lodash"
  )
)

...

  data: function () 
    return 
      lodash
    
  ,

在野外,以 _ 的形式在全局范围内实际访问 lodash 的方法是:

在 Vue 原型中添加 lodash:

要么

Vue.prototype._ = _

Object.defineProperty(Vue.prototype, '_',  value: _ )    

Source

按照前面的建议将其添加为插件

Source

【讨论】:

我认为您正在转移到一个我不知道甚至存在的不同问题上。但我认为我遇到的问题是当前版本的 webpacker 的当代问题。我可能是错的,但我的预感是许多其他人正在使用最新最好的 webpacker。 我承认我不只是想“解决你的问题”,我只是不想给你一个解决方案,让你从一个问题跑到另一个问题。如果您可以尝试从脚本中访问 lodash,而不是我在第 1 行中建议的模板,这将非常有助于确保插件或您的设置没有任何实际问题。由于 _ 未在您的 Vue 实例上定义,因此任何 Vue 设置都会发生此错误,就像您设置 Vue 实例一样。 (不管是 Webpacker 还是插件) 感谢您的建议,但正如问题所暗示的那样,我的问题更具体到 ProvidePlugin 的使用,而不是在 lodash 中添加。

以上是关于如何在 webpacker rails 中使用 ProvidePlugin?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Webpacker 中使用 Rails Url 助手/Rails 5.1 中的 React-rails

如何在 Rails 6 和 webpacker 中使用 morris.js?

如何使用 @rails/webpacker 加载本地字体?

如何在 Rails / Webpacker / React 应用程序中处理图像?

如何在 Rails 中检查 webpacker 版本?

如何在 Elastic Beanstalk 容器中提供 Rails 应用程序的 webpack 资产?