【问题标题】:Is it possible to include feature that depend on if the user as installed a certain package (optionalFeature)是否可以包含取决于用户是否安装了某个包的功能(可选功能)
【发布时间】:2018-09-28 04:36:10
【问题描述】:

我正在编写一个模块,如果用户在他的项目react-intl 中安装了该模块,我希望它能够导出具有翻译功能的高级组件。

这样我就不必维护我的组件的两个版本以避免安装警告。

我一直在尝试使用optionalDepenceny,但是当他安装我的包时,它们已安装在用户的项目中。

通常,这是我要导入的源

/**
*
* ToggleOption
*
*/

import React from 'react';
import PropTypes from 'prop-types';
import Option from 'bootstrap-styled/lib/Option';

let injectIntl;
let intlShape;

// this make react-intl optional to our component and our module
try {
  const reactIntl = require('react-intl'); // eslint-disable-line
  injectIntl = reactIntl.injectIntl; // eslint-disable-line
  intlShape = reactIntl.intlShape; // eslint-disable-line
} catch (er) {
  injectIntl = null;
  intlShape = null;
}

/**
 * This component is automatically used when using `<Toggle />`
 * If you need a different option tag, instead just pass the prop `optionTag` of `<Toggle />`.
 */
const ToggleOption = ({
  tag: Tag,
  value,
  message,
  intl,
}) => (
  <Tag value={value}>
    {message && intl ? intl.formatMessage(message) : value}
  </Tag>
);

ToggleOption.defaultProps = {
  tag: Option,
};

/* eslint-disable react/require-default-props */
ToggleOption.propTypes = {
  /**
   * Replace the default component tag by the one specified. Can be:
   */
  tag: PropTypes.oneOfType([
    PropTypes.string,
    PropTypes.element,
    PropTypes.func,
  ]),
  /**
   * The value
   */
  value: PropTypes.string.isRequired,
  /**
   * react-intl messages (optional)
   */
  message: PropTypes.object,
};

let exported = ToggleOption; // eslint-disable-line import/no-mutable-exports

if (intlShape) {
  /** @ignore */
  ToggleOption.propTypes.intl = intlShape.isRequired;
  exported = injectIntl(ToggleOption);
}

export default exported;

有没有办法配置我的模块来做到这一点?

【问题讨论】:

    标签: javascript node.js reactjs npm ecmascript-6


    【解决方案1】:

    您可以检查testing if it's module (it's "namespace") was define (if (typeof Module !== "undefined")...) 是否已经包含/需要一个模块。

    另一个选项,如果你想包含/需要一个可能已经安装的模块,是surround the include / require statement with a try / catch

    祝你好运!

    编辑:

    至于使用optionalDependencies,它不会更改您的代码 - 您仍然需要使用 try/catch 执行相同的检查。

    【讨论】:

    • 我不确定他有什么问题,但我猜他在问如何避免安装软件包,因为它是可选的。 PS:我没有投反对票。
    • @JorgeFuentesGonzález - 感谢您尝试解释。我想我的答案不是最适合 OP 的要求......但也许我真的不明白这个问题¯_(ツ)_/¯
    • 另外,JavaScript 没有用于已安装模块的命名空间。您需要事先要求它们。最接近的方法是检查全局变量,因为在浏览器中,注入库的典型(非 webpack)方法是将它们添加到窗口中,因此您可以使用 if (window.Module)if (typeof Module !== "undefined") 来检查它们,但 if (Module... 会如果未定义模块,则抛出 Module is not defined 错误。
    • 本来打算回复 try/catch 的事情,但是看到你的 -1 所以我试着用其他方式理解这个问题 xD 有点不清楚。
    • @JorgeFuentesGonzález - 感谢您的关注。我修复了丢失的typeof。至于命名空间,我已经解决了这个问题,但我把它留在了括号中。我猜术语可能与 C++ 或 Rust 不同,但全局变量执行几乎相同的功能(将所有函数定义为该变量的成员可防止冲突)...
    【解决方案2】:

    package.json 中的可选依赖项始终默认安装。为了避免它们,您必须安装:

    npm install [PACKAGE] --no-optional
    

    您可以像我一样在描述中注明,例如:https://github.com/Llorx/updated-require

    PS:你的代码很好。

    【讨论】:

    • 我想我帮助你通过了 6K 标记。一开始我没注意到,但它看起来不错:-)
    • @Myst 正是哈哈。谢谢^^
    猜你喜欢
    • 2012-07-10
    • 2019-04-24
    • 2011-03-17
    • 2013-05-05
    • 2014-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-03
    相关资源
    最近更新 更多