javascript - 当我在 Node JS 中调用 Modernizr.build 时,范围行为非常不寻常

标签 javascript node.js modernizr

我正在尝试使用 Modernizr 一次构建多个 json,但它似乎破坏了我的函数范围。 这很难解释,所以看看这个例子,如果你不相信我,就试试吧:

[1,2,3,4,5].forEach(function(i){
    require("modernizr").build({}, function (result) {
        console.log(i);
    });
})

输出:

5
5
5
5
5

而不是预期的 1、2、3、4、5,就像任何类似的函数一样。

在我使用类似 ECMAScript 的语言进行编码的这些年里,我从未遇到过这种行为,并且围绕这样的想法构建了我的项目(以及之前的项目):不能像这样破坏函数的作用域。

它会破坏任何基于 promise 甚至简单回调的系统。 这让我困惑了一整天,找不到合适的解决办法。 我什至很难想象是什么导致了这种情况的发生。 请帮忙。

编辑:

好吧,看起来你已经对 forEach 挂断了...... 这是另一个例子,可以让它更清楚一点:

function asd(i){
    require("modernizr").build({}, function (result) {
        console.log(i);
    });
}

asd(1);
asd(2);
asd(3);
asd(4);

输出

4
4
4
4

到底发生了什么?

最佳答案

Modernizr 特有的问题与全局变量被破坏有关。

build 命令基本上是一个大型的 requirejs 配置函数,全部由大型配置对象提供支持。有一些基本的东西总是正确的,它们建立在函数的顶部

{
  optimize: 'none',
  generateSourceMaps: false,
  optimizeCss: 'none',
  useStrict: true,
  include: ['modernizr-init'],
  fileExclusionRegExp: /^(.git|node_modules|modulizr|media|test)$/,
  wrap: {
    start: '\n;(function(window, document, undefined){',
    end: '})(window, document);'
  }
}

然后,由于 Modernizr 无需更改即可在浏览器和 Node 中工作,因此需要有一种方法让它知道是否应该通过文件系统或通过 http 加载其依赖项。因此,我们在环境检查中添加了更多选项,例如 basePath

if (inBrowser) {
  baseRequireConfig.baseUrl = '/i/js/modernizr-git/src';
} else {
  baseRequireConfig.baseUrl = __dirname + '/../src';  
}

此时,配置对象被传递到 requirejs.config 中,它连接了 require 并允许我们开始调用 build

最后,在创建所有这些之后,我们有一个构建函数,它最终还会再次修改配置对象以进行特定于构建的设置(构建中的实际检测、正则表达式以删除一些 AMD crud 等)。

所以这是最终发生的事情的 super 简化伪代码版本

var config = {
  name: 'modernizr'
}

if (inBrowser) {
  config.env = 'browser';
} else {
  config.env = 'node';    
}

requirejs.config(config);

module.exports = function(config, callback) {
  config.out = function (output) {
    //code to strip out AMD ceremony, add classPrefix, version, etc

    callback(output)
  }

  requirejs.optimize(config)
}

发现问题了吗?

由于我们在运行异步 require.optimize 函数之前接触了配置对象的 .out 方法(其范围是整个模块,因此其上下文在 build() 调用之间保存),因此每次调用 build 时,您传递的回调都会重写 .out 方法。

这应该在 Modernizr 中几个小时内修复

关于javascript - 当我在 Node JS 中调用 Modernizr.build 时,范围行为非常不寻常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34773567/

相关文章:

javascript - Stripe 自定义结帐未发布

javascript - 动态requirejs配置扩展

node.js child_process 生成忽略等号

javascript - 使用socket.io从Mt. Gox的 "now"值获取日期/时间?

html - 结合 modernizr 和 selectvizr?

javascript - QUnit 中的 'Q' 代表什么?

javascript - 在 OWL Carousel 中滑动 2 个元素

javascript - 如何将时刻 JS 时间插入 MySQL

javascript - modernizr 如何检查对 webforms2.0 中新输入属性的支持?

jquery - 我如何在 jquery 中切换点击功能