How can a require.js plugin call parentRequire relative to the baseURL? - requirejs

I'm using require-ts (https://github.com/iammerrick/require-ts) to import a typescript file with require.js. I need to import several .d.ts files to satisfy the compiler. When I specify the declarations inside my require.config, they are resolved relative to the module importing them. This is because require-ts calls parentRequire on the declarations. However, I want to resolve the declarations globally, relative to my baseURL, as the definitions have nothing to do with the specific module. What is the best way to do this? I'm absolutely fine with modifying the require-ts if that is what's needed.

Per module id / resource URI resolution rules, the resource ID is NOT resolved relative the current container/module, unless that resource ID starts with "." char. ("./" or "../")
I am not aware of formal AMD / RequireJS article on ID normalization / resolution, but the following two may help:
module ID resolution / normalization
general language on define statement
In other words, "stop using . as the starting char of the resource and the resource should be resolved against the AMD tree root."

Related

In a module, using a defined resource works in puppet3, but fails in puppet5

All is in the manifests directory.
In manifest execute.pp, I have:
define execute (
String $command = "echo",
String $workdirectory = "/tmp",
String $runas = "www",
Boolean $failonerror = true
) {
# Resources
require stdlib
etc ...
The code which uses it :
....
if defined(Execute["$titlePreviousExecRes"]) {
....
The error with puppet5 is
Error: Evaluation Error: Error while evaluating a Resource Statement, Evaluation Error: Resource type not found: Execute at ...
Your defined type's manifest is physically located among those of a module (whose name you have not disclosed), but the type is not part of the module, in the sense that its name is not in the module's namespace. As a result, Puppet's loader will not find it. Your code was buggy for Puppet 3, too, but it seems to have benefited from a confluence a laxness features.
If your defined type is supposed to belong to a module named "mymodule", for example, then it should be explicitly declared in that namespace:
define mymodule::execute ( ...
and it should also be referenced via that namespace:
if defined(Mymodule::Execute["$titlePreviousExecRes"]) {
. Fix your problem by placing your defined type in the correct namespace, and referring to it via its fully-qualified name.
As for why it seemed to work in Puppet 3, version 3 of the Puppet language supposed that references to classes and types that were not explicitly anchored to top scope (e.g. ::execute) might be relative to the namespace of the class or type in which the reference appeared (or even to some others). In your case, then, the autoloader would first guess that your reference to a type named Execute might be intended to refer to ::mymodule::execute. Seeing that a manifest mymodule/manifests/execute.pp exists, it would evaluate that file, and thereby obtain a definition of type ::execute -- not the ::mymodule::execute it was looking for.
Having not found the type it was looking for, the autoloader would then search in other namespaces, until ultimately trying top scope. When it got there, however, it would find that it already had the top-scope definition it obtained from the manifest in the module, so the loader would succeed, providing that misplaced definition. But that would only work for references from within the same module, and it presented a grave risk of collisions.
Puppet 5's autoloader still exhibits some fallback behavior for locating class and defined type definitions, but Puppet no longer recognizes relative class and defined type names. Thus, when trying to resolve your reference to type execute, the autoloader never considers evaluating mymodule/manifests/execute.pp, because that's where it would expect to find ::mymodule::execute, not the type it's looking for, ::execute.
Thus, no, your definition is never located or loaded. This is a feature, not a bug.

How to include modules from a different directory in puppet

My module tree is like this
- modules
- socle1
- stdlib
- socle2
- ntp
How do I include the stdlib module in my site.pp?
I have tried include socle1::stdlib and it is not working .
Should I modify the environment.conf for the directory environment?
If you want to arrange your modules in separate trees, then you may do so. You should then include each base path in your environment's modulepath, and refer to the modules by their regular names. Note in particular that altering the path to a module does not change its name or the names of any of the classes or types it defines -- the path influences only whether the autoloader can find them.
I strongly advise against making subdirectories of the standard module directory, however. Instead, if you want to group modules in multiple directories then create parallel module directories for that purpose:
- modules
- socle1
- stdlib
- socle2
- ntp
Should I modify the environment.conf for the directory environment?
In order to support any module directories beyond or instead of the default, yes, you should. The puppet documentation describes how to configure your environment's modulepath. But do consider following #MattSchuchard's advice and instead restricting yourself to the standard module directories.
You are not supposed to put modules inside of other modules. Your tree should be like:
- modules
- socle1
- stdlib
- socle2
- ntp
Also, you would very rarely include stdlib, because stdlib is almost entirely a type/function module, so you would only reference its types and functions. You would not be declaring its classes unless you were planning on using the stages functionality it provides (thanks to John Bollinger for corrections to this paragraph).
However, declaring the ntp module in your site.pp is as simple as:
include ntp
or:
class { 'ntp': }
inside of your node { }.
In your init.pp
class classname ( parameters ) {
include ::socle2::ntp
}
Try this and tell me if this works or not!

Groovy - extensions structure

I'd like to extend String's asType method to handle LocalDateTime. I know how to override this method, however I've no idea where should I put it in project structure to work globally - for all strings in my project. Is it enough to put such extension wherever in the classpath? I know that there's a special convention for extensions (META-INF/services), how does it work for method overriding?
All documentation regarding this topic can be found here. And here exactly the relevant part can be found.
Module extension and module descriptor
For Groovy to be able to load your extension methods, you must declare
your extension helper classes. You must create a file named
org.codehaus.groovy.runtime.ExtensionModule into the META-INF/services
directory:
org.codehaus.groovy.runtime.ExtensionModule moduleName=Test module for
specifications moduleVersion=1.0-test
extensionClasses=support.MaxRetriesExtension
staticExtensionClasses=support.StaticStringExtension The module
descriptor requires 4 keys:
moduleName : the name of your module
moduleVersion: the version of your module. Note that version number is
only used to check that you don’t load the same module in two
different versions.
extensionClasses: the list of extension helper classes for instance
methods. You can provide several classes, given that they are comma
separated.
staticExtensionClasses: the list of extension helper classes for
static methods. You can provide several classes, given that they are
comma separated.
Note that it is not required for a module to define both static
helpers and instance helpers, and that you may add several classes to
a single module. You can also extend different classes in a single
module without problem. It is even possible to use different classes
in a single extension class, but it is recommended to group extension
methods into classes by feature set.
Module extension and classpath
It’s worth noting that you can’t use an extension which is compiled at
the same time as code using it. That means that to use an extension,
it has to be available on classpath, as compiled classes, before the
code using it gets compiled. Usually, this means that you can’t have
the test classes in the same source unit as the extension class
itself. Since in general, test sources are separated from normal
sources and executed in another step of the build, this is not an
issue.

RequireJS - When specify module id in define()

In RequireJS documents (http://requirejs.org/docs/api.html#modulename), I couldn't understand this sentence.
You can explicitly name modules yourself, but it makes the modules less portable
My question is
Why explicitly naming module makes less portable?
When explicitly naming module needed?
Why explicitly naming module makes less portable?
If you do not give the module a name explicitly, RequireJS is free to name it whichever way it wants, which gives you more freedom regarding the name you can use to refer to the module. Let's say you have a module the file bar.js. You could give RequireJS this path:
paths: {
"foo": "bar"
}
And you could load the module under the name "foo". If you had given a name to the module in the define call, then you'd be forced to use that name. An excellent example of this problem is with jQuery. It so happens that the jQuery developers have decided (for no good reason I can discern) to hardcode the module name "jquery" in the code of jQuery. Once in a while someone comes on SO complaining that their code won't work and their paths has this:
paths: {
jQuery: "path/to/jquery"
}
This does not work because of the hardcoded name. The paths configuration has to use the name "jquery", all lower case. (A map configuration can be used to map "jquery" to "jQuery".)
When explicitly naming module needed?
It is needed when there is no other way to name the module. A good example is r.js when it concatenates multiple modules together into one file. If the modules were not named during concatenation, there would be no way to refer to them. So r.js adds explicit names to all the modules it concatenates (unless you tell it not to do it or unless the module is already named).
Sometimes I use explicit naming for what I call "glue" or "utility" modules. For instance, suppose that jQuery is already loaded through a script element before RequireJS but I also want my RequireJS modules to be able to require the module jquery to access jQuery rather than rely on the global $. If I ever want to run my code in a context where there is no global jQuery to get, then I don't have to modify it for this situation. I might have a main file like this:
define('jquery', function () {
return $;
});
require.config({ ... });
The jquery module is there only to satisfy modules that need jQuery. There's nothing gained by putting it into a separate file, and to be referred to properly, it has to be named explicitly.
Here's why named modules are less portable, from Sitepen's "AMD, The Definite Source":
AMD is also “anonymous”, meaning that the module does not have to hard-code any references to its own path, the module name relies solely on its file name and directory path, greatly easing any refactoring efforts.
http://www.sitepen.com/blog/2012/06/25/amd-the-definitive-source/
And from Addy Osmani's "Writing modular javascript":
When working with anonymous modules, the idea of a module's identity is DRY, making it trivial to avoid duplication of filenames and code. Because the code is more portable, it can be easily moved to other locations (or around the file-system) without needing to alter the code itself or change its ID. The module_id is equivalent to folder paths in simple packages and when not used in packages. Developers can also run the same code on multiple environments just by using an AMD optimizer that works with a CommonJS environment such as r.js.
http://addyosmani.com/writing-modular-js/
Why one would need a explicitly named module, again from Addy Osmani's "Writing modular javascript":
The module_id is an optional argument which is typically only required when non-AMD concatenation tools are being used (there may be some other edge cases where it's useful too).

Use __dirname into class compiled in Typescript AMD

I'm looking for a solution to use __dirname (or equivalent) inside a TypeScript class compiled in AMD, __dirname doesn't exists there. And because it's typescript, I can't (or I don't know how) import module that contains uri, allowing me to get the uri.
I found the solution once, but I don't remember how and I can't find it again so far.
I took a look to this, but it's in pure javascript and I use typescript, I tried to import module, but I get a TS error.
https://stackoverflow.com/questions/9027429/how-to-use-nodejs-global-module-objects-in-requirejs-modules
One solution is to:
In app.js, create a global var:
__basePath = __dirname;
Then, in the AMD script, use __basepath + 'relativePathFromBasePath' to load the file.
I know I found another solution but I cannot remember how.
I do not use TypeScript, but on the basis of the TypeScript code I've seen and on the basis of what I know of RequireJS, I believe you should be able to access module.uri like this:
import module = require("module");
console.log(module.uri);
The name module is special. You could also use require.toUrl(<module name>) (that's Url as in URL whereas the variable above is uri as in URI) but it does not seem as useful as module.uri for this task. For one thing you'd have to include the module's name in the call.
module.uri may contain .., so it needs cleaning up. I understand your code to be running server-side, so in Node.js we'd call path.dirname(path.normalize(module.uri)).

Resources