简体   繁体   English

将库转换为JavaScript闭包

[英]Convert Library to JavaScript closure

I have an external library of JavaScript functions that I need to pull into my server-side Google Apps Script project. 我有一个JavaScript函数的外部库,我需要将其引入我的服务器端Google Apps脚本项目。 I'm doing this mainly for performance reasons, but also because Google now recommends against using external libs . 我这样做主要是出于性能原因,但也因为Google现在建议不要使用外部库

In the current configuration, functions in the external library are referenced by <Libname>.funcName() , and any globals in the library are likewise contained, eg <Libname>.globA . 在当前配置中,外部库中的函数由<Libname>.funcName()引用,同样包含库中的任何全局变量,例如<Libname>.globA If I just copy the library into a file in my project, those functions (and "globals") would be referenced as funcName() alone. 如果我只是将库复制到项目中的文件中,那些函数(和“全局”)将仅作为funcName()引用。 I've got hundreds of such references in my project that potentially need to change. 我的项目中有数百个此类引用可能需要更改。 That's fine; 没关系; it's something a global search & replace can address. 这是全球搜索和替换可以解决的问题。 However, I have worries about "namespace" problems... Since the library is third-party code, I've had no control over it, and now I'm running into name collisions, as objects and functions in the library have the same names as some of my code. 但是,我担心“命名空间”问题...由于库是第三方代码,我无法控制它,现在我遇到名称冲突,因为库中的对象和函数具有与我的一些代码相同的名称。

How can I pull this code into my project in a way that will keep its internal details separate from my code? 如何将此代码以一种将其内部详细信息与我的代码分开的方式提取到我的项目中? Is there a way to do that and retain the current naming convention, <Libname>.funcName() ? 有没有办法做到这一点并保留当前的命名约定, <Libname>.funcName() I believe that JavaScript closures are the right solution, but don't know enough about them. 我相信JavaScript闭包是正确的解决方案,但对它们不够了解。

My project, Code.gs 我的项目Code.gs

var globA = { key: 'aKey', value: 'valA' };

function myFunction() {
  var a = MyLib.getValue();
  Logger.log( JSON.stringify( a ) );  // { key: 'libKey', value: 'valLibA' };
}

function getValue() {
  return globA;
}

Library "MyLib", Code.gs 库“MyLib”, Code.gs

var globA = { key: 'libKey', value: 'valLibA' };

function getValue(  ) {
  return globA;  
}

There are two ways to solve this. 有两种方法可以解决这个问题。

You could use browserify to convert a node library into a piece of code that can simply be pasted into the apps script editor. 您可以使用browserify将节点库转换为一段代码,只需将其粘贴到应用程序脚本编辑器中即可。

Or you wrap the code yourself using an immediately invoked function expression . 或者您使用立即调用的函数表达式自己包装代码。

Like this: 像这样:

var MyLib = (function() {
  var globA = { key: 'libKey', value: 'valLibA' };
  function getValue(  ) {
    return globA;  
  }

  return {
    globA: globA,
    getValue: getValue
  }
})();

btw. 顺便说一句。 if you create several .gs files, the code/definitions in them will be executed in the order the file names are displayed on the left side of the editor. 如果您创建了几个.gs文件,其中的代码/定义将按照编辑器左侧显示文件名的顺序执行。

The best way to structure your modules while keeping some level of closure is in my opinion to use Asynchronous Module Definition (AMD). 在我看来,使用异步模块定义(AMD)来构建模块同时保持某种程度的关闭的最佳方法。 A good library to do that would be requirejs. 一个好的图书馆就是requirejs。

You will define and require your modules like so : 您将定义并要求您的模块如下:

define(['path/to/your1stLib', 'path/to/your2ndLib', ...], function(Your1stLib, Your2ndLib, ...) {

  var MyOtherLib = {
    Your1stLib.doStuff(...)

    // rest of the code
  }

  return MyOtherLib;

});

我建议将库包装为AMD模块,并使用requirejs或类似的方法来加载依赖项。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM