webpack - DefinePlugin方法

时间:2017-04-19 17:54:53

标签: webpack

在webpack插件的定义中,我正在尝试提供一个覆盖函数,如果方法存在,我的模块将会拾取。

export const listFetchAPI = () => {
  return ( LIST_FETCH_API ? LIST_FETCH_API : '/list/');
};
export const listFetchTX = (data) => {
  return ( LIST_FETCH_TX === 'function' ? LIST_FETCH_TX(data) : data );
};

在我的webpack配置中,基于项目的环境或实现,我可能会或可能不想为这些功能提供覆盖。

webpackConfig.plugins.push(
  new webpack.DefinePlugin({
    LIST_FETCH_API: JSON.stringify('https://testapi.com/listFetch/')
    LIST_FETCH_TX(data) { return { ...data, test: 'HELLO!' }; }
  })
);  

我尝试过使用ES5和ES6表示法。当我构建时,我收到错误SyntaxError: Unexpected identifier

我没有在文档中看到您可以通过DefinePlugin传递方法。 https://webpack.js.org/plugins/define-plugin/

谷歌搜索出现了。我的下一步是传递字符串值,然后使用react-json-schema来获取组件。这看起来太复杂了,所以我希望有一种方法可以在DefinePlugin中定义方法。

修改 为了澄清,我正在做的是构建一个通用的redux模块,它可以注册到私有的npm注册表。调用时,可以为API URL和响应转换器提供此模块的覆盖。这使我无法在每次为不同供应商安装时分支代码或创建99%相似的模块。

如果通过环境变量提供函数不合适,那么允许这样的覆盖的替代方法是什么?我不确定配置对象是否会在通过商店发送内容时播放出来。我正在玩的另一个选项是覆盖模块中的整个文件。我在Ruby中使用import_path熟悉方法,但在研究中,我还没有看到任何等效的JS / npm方法。

2 个答案:

答案 0 :(得分:2)

DefinePlugin是直接文本替换,类似于C中的宏.Webpack将查找标识符并将其替换为给定的字符串。以下示例说明了它的工作原理。

使用以下插件配置

new webpack.DefinePlugin({
  VAR: 'myVar',
  STRING: '"a string (note the quotes inside quotes)"',
  FUNCTION: 'function myFun(arg) { console.log("myFun was called with", arg); }'
})

和JavaScript作为输入:

const myVar = 'hello';

console.log(VAR);
console.log(STRING);
console.log(FUNCTION);
// IIFE requires parens to execute
(FUNCTION)('iife');

// Better, only defines the function once
const functionToCall = FUNCTION;
functionToCall('another arg');

输出JavaScript将是:

const myVar = 'hello';

console.log(myVar);
console.log("a string (note the quotes inside quotes)");
console.log(function myFun(arg) { console.log("myFun was called with", arg); });
// IIFE requires parens to execute
(function myFun(arg) { console.log("myFun was called with", arg); })('iife');

// Better, only defines the function once
const functionToCall = function myFun(arg) { console.log("myFun was called with", arg); };
functionToCall('another arg');

正如您所看到的,它们已被简单地替换为DefinePlugin中定义的值。如果您运行它,您将获得以下控制台日志:

hello
a string (note the quotes inside quotes)
[Function: myFun]
myFun was called with iife
myFun was called with another arg

对于STRING,您通常会使用JSON.stringify(),它只是为您提供字符串的字符串表示(引号内的引号)。如果你不这样做,它只是一个标识符,如果标识符没有定义,它将引发错误。 FUNCTION还表示它将在任何地方被替换,它不会引用相同的功能,因为它是直接替换文本。

如果你想要选择性地定义某些东西,你还需要检查变量是否存在,因为如果你不这样做,它就会抛出一个错误。

const varOrDefault = typeof VAR !== 'undefined' ?  VAR : 'default'; 

你不能VAR === undefined因为它假设变量存在并且只检查它是否未定义,但是当它没有被定义时,它将引发错误VAR未定义。之后,您可以自由地使用变量并按照您的需要使用它并检查它是否具有功能(当检查函数时,您可以跳过测试是否已定义,因为这将使用{{1无论如何)。

说实话,这不是一个很好的解决方案,特别是因为需要typeof检查所需的功能两次。公平地说,这种文本替换不适用于任何有条件定义的动态结构。将其移动到配置对象会更好。接受配置对象并提供默认值非常简单。有几种方法可以实现这一目标。

例如Object.assign

typeof

答案 1 :(得分:0)

根据DefinePlugin

的文档
  

DefinePlugin允许您创建可以的全局常量   在编译时配置。这可以用于允许不同的   开发构建和发布构建之间的行为。

这些定义是键值对,在以下代码行语法中:键:应遵循值。

Key : Value

 LIST_FETCH_TX(data) { return { ...data, test: 'HELLO!' }; }

我仍然不确定它是否适用于函数,因为目的是创建全局常量。它可能在未来发生变化,新的东西不断涌现: - )

不确定这个答案,但可能会帮助你弄清楚它为什么会抛出错误:缺失。

干杯!

相关问题