我正试图围绕如何在Meteor方法中隐藏客户端的秘密服务器代码。 The docs seem to imply以下是如何完成的一般模式。 https://guide.meteor.com/structure.html#using-require
(请注意,根据文档,我使用的是require
而不是导入,因为import
无法在条件块中使用。)
首先,这是一个名为methods.js
的文件中定义的方法,并在客户端和服务器上导入:
/* methods.js */
let ServerCode
if (Meteor.isServer) {
ServerCode = require('/imports/server-code.js')
}
Meteor.Methods({
'myMethodName': function() {
// ... common code
if (Meteor.isServer) {
ServerCode.secretFunction()
}
// ... common code
}
})
其次,这是/imports/server-code.js
中的秘密服务器代码,我试图不发送给客户端:
/* server-code.js */
class ServerCode {
secretFunction() {
console.log('TOP SECRET!!!!')
}
}
const ServerCodeSingleton = new ServerCode()
module.exports = ServerCodeSingleton
但当我检查发送到客户端浏览器的源时,我仍然看到我的秘密服务器代码被发送到客户端:
即使我进行了制作,我仍然可以搜索并找到“TOP SECRET !!”串。我觉得我对require
的工作方式的理解太天真了,但Meteor的文档使它看起来如此简单。那么隐藏从Meteor Methods调用的密码的正确方法是什么?
答案 0 :(得分:1)
我终于想到了这一点。
简短的版本是,忽略它在这里所说的;我认为这是不正确的或至少是误导性的:
https://guide.meteor.com/structure.html#using-require
请按照此处的说法进行操作:
https://guide.meteor.com/security.html#secret-code
更长的解释是:在仅服务器文件中,import
密码并将其分配给全局变量。然后,在< em> common file ,使用isServer
(或!isSimulation
)有条件地引用该全局变量。
所以我原来的例子可能会像这样重写:
/* /imports/methods.js */
// Note: no conditional use of require this time
Meteor.Methods({
'myMethodName': function() {
// ... common code
if (Meteor.isServer) {
ServerCode.secret() // <-- Defined as a global outside of this file!
}
// ... common code
}
})
因此密码文件可能如下所示:
/* /imports/server-code.js */
class _ServerCode {
secret() {
console.log("Shhhhhh, I'm secret()!")
}
}
// Here's the global variable:
SecretCode = new _SecretCode()
然后在仅限服务器文件中,它可能如下所示:
/* /server/server-main.js */
import '/imports/secret-code' // <-- declare the global
import '/imports/methods' // <-- use the global in here
然后在仅限客户端文件中,它可能如下所示:
/* /client/client-main.js */
import '/imports/methods'
//...
Meteor.call('myMethodName')
现在,客户端和服务器都可以在方法体(DRY)中执行与 部分 完全相同的代码,而某些密码可以是仅服务器并赢得也不会被送到客户端。不得不求助于使用全局变量,这有点烦人,但也许这是最干净的选择,直到import
的更高版本出现,支持内置的模块延迟加载。
答案 1 :(得分:0)
编辑:无视答案,没有解决OP对DRY代码或乐观更新的渴望。
默认情况下,Meteor实现了关于文件的急切加载方案。你的methods.js就是一个例子。
如果文件位于名为“client”的文件夹下的任何目录中,则该文件仅提供给客户端。同样,“服务器”下的任何文件仅提供给该文件夹。这就是你如何处理确保文件只服务于服务器。
正如您所发现的那样,“Meteor.isServer”构造仅限制在环境中运行的内容,而不是在那里提供的内容。
我通常会实现像这样的Meteor方法:
服务器/一些/路径/ stuff.js:
// this is only on the server
Meteor.methods({
'getStuff': function() {
return "stuff";
}
});
的客户机/一些/路径/ clientStuff.js:
// this is only on the client, calling the server method
Meteor.call('stuff', function(error, result) {
if (error && error.reason) {
alert(error.reason);
}
else {
// use result
}
});
关于要求,你为什么要使用它?
我看到你在/ imports中有代码,Meteor将其视为特殊代码并且不会急于加载。这告诉我你明确地导入了这些东西。
MDG对目录结构,ES15模块以及如何加载代码有一些强烈的建议,他们在这里详细说明:
https://guide.meteor.com/structure.html
你会注意到他们没有使用require,并且指定的模块与你的模式不同。