我一直在阅读有关AMD和requirejs
等实施的内容。大多数资源都涵盖了用法和API。
但是,在实现这一点时,如何将JavaScript文件加载到变量中呢?例如,您可以看到如下函数:
define(['jquery'], function($){
});
var jquery = require('./jquery');
从API消费者的角度来看,我能理解的是文件jquery.js
神奇地变成了$
,jQuery
等等?这是如何实现的?
任何例子都会有所帮助。
How do AMD loaders work under the hood?是一本有用的读物。
编辑:我认为下面的eval
答案很好,因为它在某些方面实际上是一个eval
问题。但我想从AMD specs实施的角度来了解这一点。
答案 0 :(得分:3)
您不会将javascript文件加载到变量中,而是由browserify或webpack等内容完成。 Javascript本身可以执行此操作,但这些模块生成包含所有代码的单个文件。通过调用require("file")
,您调用browserify的函数来加载存储在代码中的名为“file”的文件。
如果你有一个模块
,可以这样做function demoModule(){
console.log("It works!");
}
module.exports = demoModule
这使得module.exports现在包含文件的“整个”内容
Browserify / webpack将其放入一个返回该文件的module.exports的函数
function require(filename) {
switch(filename){
case "demofile":
let module = {exports:{}}; ((module) => {
function demoModule(){
console.log("It works!");
}
module.exports = demoModule
})(module)
return module.exports;
}
};
require("demofile")();
您的文件将成为可以使用require("demofile")
调用的函数,它将返回任何module.export。
答案 1 :(得分:2)
您知道如何说eval(alert("hello!"))
并执行代码吗?
你也可以:
var str = "hello!"
eval('alert("' + str + '");')
所以下一步是要有一个包含实际脚本的文件:
var str = "hello"
alert(str)
然后你可以使用标准的AJAX请求将该文件提取到变量中,你可以eval()
该变量。
从技术上讲,eval()
被认为是邪恶的 - 充满了危险 - 但还有其他解决方案(例如,在文档正文中注入脚本标记)。我刚跟eval()
一起去了解这个问题。
答案 2 :(得分:1)
扩展了睡眠所说的内容。
这样的事情:
var str = "if (x == 5) {console.log('z is 42'); z = 42;} else z = 0;";
console.log('z is ', eval(str));
更多阅读here。
但请谨慎使用eval()
并绝对确定eval()
的缺陷和缺点。
除非是唯一的选择,否则不要使用它。
也请阅读此answer。
答案 3 :(得分:0)
define
在幕后工作的方式不是将“HTML脚本加载到变量”。通常,普通脚本可以有多个变量,因此捕获值变量没有意义!如果需要,eval
方法可能会做类似的事情。它捕获JavaScript源代码中的所有内容。
AMD
中的真正关键是define
API将名称映射到功能。只要您require
具有该名称,它就会调用该函数并将值返回给您。此返回值应为模块。这是惯例,使一切正常运作!
换句话说,AMD使用一种有趣的约定(设计模式)来确保我们在JavaScript代码中获得模块化效果。这是一个间接的层面。您只需编写一个函数来返回单个值,该函数将捕获您希望作为模块公开的所有内容传递给消费者,而不是正常的“编写代码并在全局范围内执行”范式。