Node.js Nodejs中模块的延迟加载
我的第一个问题是:谁负责处理Nodejs应用程序中的Node.js Nodejs中模块的延迟加载,node.js,requirejs,commonjs,Node.js,Requirejs,Commonjs,我的第一个问题是:谁负责处理Nodejs应用程序中的require语句?它是节点本身吗?还是普通的?还是要求?节点中是否包含CommonJS?那RequireJS呢 现在我的第二个问题: 我有一个if-else语句,它决定我们是在服务器端渲染还是在客户端渲染。我想在客户端或服务器端渲染时加载不同的库。是否可以在运行时加载模块?就在需要的时候 if (typeof window === undefined){ var serverSideLibrary = require('
require
语句?它是节点本身吗?还是普通的?还是要求?节点中是否包含CommonJS?那RequireJS呢
现在我的第二个问题:
我有一个if-else语句,它决定我们是在服务器端渲染还是在客户端渲染。我想在客户端或服务器端渲染时加载不同的库。是否可以在运行时加载模块?就在需要的时候
if (typeof window === undefined){
var serverSideLibrary = require('A');
//....
}else{
var clientSideLibrary = require('B');
}
看起来Node在启动应用程序之前加载了所有必需的内容。因此,在代码顶部或if-else块中是否需要它并不重要。在Node.js中,节点本身处理
require
。而您错了—在程序的评估达到之前,不会对要求进行评估。如果您有此代码:
var mod;
setInterval(function() {
if (true) {
mod = require("a");
} else {
mod = require("b");
}
}, 5000);
…你可以肯定两件事:1。模块b
将永远不会加载,2。模块a
在五秒钟后才会加载
在浏览器中,require
仅在使用定义它的库(如RequireJS、Browserify或Webpack)时定义。一般来说,这些工具与节点的行为密切相关:虽然浏览器可能一次下载所有代码(特别是当您有一个将所有模块放入单个文件的构建步骤时),但它们会将每个模块包装在一个函数中,以便在require
d之前不会对其进行实际评估
如果您想根据您的代码是在客户端还是服务器上运行来加载不同的模块,我建议您在构建步骤中执行此操作大多数构建工具(如上文所述)都具有此功能或作为插件提供,而不仅仅是If
语句,因为有了if
语句,您仍然在让浏览器下载它永远不会使用的代码。记住nodeJs是解释的。所以他只是做代码中的任何事情,而不是依赖于它是什么!。。。无论您在何处执行“require(something)”,它都将执行ok,并且不会抛出任何错误,除非您有sintax错误或您尚未安装所需的库
所以你可以随心所欲!,您可以要求在If语句中包含包。您必须考虑的是,如果您尝试使用从未导入的库,那么您将遵循正确的方法,因为您将得到运行时错误。
干杯 覆盖.js
文件扩展名,从目录循环中隐藏.js
文件,默认情况下,当调用require
时会发生这种情况,并创建自定义方法,通过编程方式按需调用require:
var fs = require('fs'),
IonicAppLib = module.exports,
path = require('path');
var camelCase = function camelCase(input) {
return input.toLowerCase().replace(/-(.)/g, function(match, group1) {
return group1.toUpperCase();
});
};
//
// Setup all modules as lazy-loaded getters.
//
fs.readdirSync(path.join(__dirname, 'lib')).forEach(function (file) {
file = file.replace('.js', '');
var command;
if (file.indexOf('-') > 0) {
// console.log('file', file);
command = camelCase(file);
} else {
command = file;
}
IonicAppLib.__defineGetter__(command, function () {
return require('./lib/' + file);
});
});
IonicAppLib.__defineGetter__('semver', function () {
return require('semver');
});
它包装了分配给require
调用的变量的访问器:
var IonicAppLib = require('ionic-app-lib');
参考资料
有两种方式可以选择需要某些东西:
选项1-在块/if语句中
在您的代码中,这将起作用:
let theLibary;
if (typeof window === undefined){
theLibrary = require('A');
} else {
theLibrary = require('B');
}
// Now use theLibrary and only the one you want will be included
其他代码可能会打包到客户机上,但永远不会执行
选项2-创建一个使用Lazy require ninjary的库
创建一个名为library\u of_libraries.js的新库,它可以:
thisLibrary = module.exports;
// Lazy load only on usage
thisLibrary.__defineGetter__("A", function () {
return require("A");
});
thisLibrary.__defineGetter__("B", function () {
return require("B");
});
现在,在您的其他代码中,当您需要库时,它将按需加载
const LibraryOfLibraries = require("library_of_libraries");
LibraryofLibraries.A.someFunc(); // Library B is never loaded
@Paul Sweatte的回答让我走上了正确的道路。#1:Node.js。节点不使用RequireJS。它们只是有一个名为require()
的函数,这两个函数之间的关系很小,但它们的相似程度与Java和JavaScript相似——实际上只是在名称上。CommonJS是一组规范,包括require()
函数的行为。Node.js将是该规范的一个实现。让我们假设我在客户端运行此代码(因此它不需要一个脚本)。在B中有一个自调用函数,它唯一做的事情就是抛出一个错误。我们期望的是不会收到错误。但是我收到一个错误,我认为你把两个不同的东西混在一起了。。为什么在同一个代码上会有在服务器上运行的东西和在客户机上运行的东西?。我猜当你说客户端时,你是指浏览器,对吗?。如果是这样的话,浏览器不会运行nodejs,所以在客户端执行“require”不会起作用,浏览器只运行简单的javascript(只是为了获取信息)。。