load modules using module name and not the file name - javascript

I have two 'define' in two separate js files.
def1.js and def2.js
define("mydefname1",["file1",...]});
define("mydefname2",["file2",....]});
I have another require statement where i check if the two definetions are loaded.
require(['def1','def2'], function(){alert('loaded')});
this works fine..
but if I try
require(['mydefname1','mydefname2'], function(){alert('loaded')});,
it does not work.
Is there a way I could actually use mydefname1 and mydefname2.. i.e. the module name to load them, and not the file name?

As far as I know, that's not possible. What I usually do is format my file names to include my module name, so I can include it that way.
For a metaclass name Overlay, the file name would be class.Overlay.js and my require/include functions would take my module name and build the file name from it.

As I understand it, RequireJS recommends that you avoid manually assigning module names - see here: http://requirejs.org/docs/api.html#modulename
FWIW, have you played around with the "path" configuration option? I don't think you can use it to do exactly what you are looking to do but it may offer an acceptable alternate approach. See here: http://requirejs.org/docs/api.html#config
Hope it helps!

Related

Sails: Exclude directory from being auto loaded as helper

I am building a Sails.js application using sails 1.2.3, node 10.15. I want to include a javascript module in my api/helpers/* directory, without sails automatically using it to try to create a helper. I.e. I have javascript objects that use helpers and are used in a helper, but are not helpers themselves; as in this image, where the module 'rules' is imported into the create-rule helper and the objects exported by this module are used within the helper.
By default, sails tries to load each file in the helpers/* directory as a helper, and throws if the underlying implementation does not match that of a valid helper:
ImplementationError: Failed to load helper `create-rule/rules/foo/index` into a Callable! Sorry, could not interpret "index" because its underlying implementation has a problem:
------------------------------------------------------
• Missing the `fn` property.
------------------------------------------------------
Hoping someone can help out! Let me know if more info is needed. Thanks in advance!
I don't quite understand what you are trying to do. In my humble opinion I would grab all object constructors and placed them as a single file in api/services. That will make it automatically available in all controllers. I would not allow my object's methods to use helpers by them selves (I even think you can't, at least easily). Then when you need a helper to use your object, just pass it as parameter. Anyway, again, in my humble opinion; you are structuring your code to fit all inside /helpers and that will make it extremely hard to develop. Let assume you manage to make it work all inside /helpers, only you without exception, will be able to understand what it does or how it works. Doesn't seem as a good idea.

Calling a function defined outside of the Javascript library

I am working on video.js library. I was trying to modify it, so that it uses a custom player instead of the HTML5 player.
So I replaced the function calls to play() etc with the calls to my custom player(say custFunc1()). These calls are defined in a separate javascript file: custPlayer.js.
So in my index.html file, I will first include the custPlayer.js file and then the built video.js file.
However the problem is that while building the video.js package using grunt, I get the error that custFunc1 is not defined and thus grunt is not able to create the video.js library.
Now I was able to find out from a colleague that adding
/* global custFunc1 */
at the beginning of the particular file in the video.js package from where I was calling custFunc1 resolves the issue. The grunt build succeeds and it works fine.
So what I want to know is:
How does this actually resolve the issue, since this is exactly like a comment in javascript, how does it treat this differently and understand that it indicating that the function definition will be present outside the library?
Is the word global some sort of keyword in javascript?
Are there other ways of achieving this apart from what I mentioned?
On a slightly different note, I wanted to ask if grunt is the rough equivalent of make ?
Your javascript is being linted as part of your grunt process, if you look at the root of your project folder you should see a file like .jshintrc or something along those lines (different depending on the linter).
Your current settings means that the linter is going through your .js files one at a time and if it comes across a variable or function from another files it's throwing the error your seeing. You can either turn off this check or add custFunc1 to an array of known global variables. In jshint you do it like so - https://github.com/gruntjs/grunt-contrib-jshint#jshintrc
{
"globals": {
"custFunc1": true
}
}
The globals will probably already be present in the file, so just add custFunc1: true to it.
Oh and to answer question 1 - the comment type syntax tells the linter to ignore it's settings for that current file, basically overriding the settings in the .jshintrc file.
2 - Yes it's a setting in jshintrc and your adding custFunc1 to it inside the file itself instead of globally in the .jshintrc file.
3 - Mentioned above.
4 - Never used maker but yes i believe its similar in that its a pre process tool

Understanding the Communication between Modules in jQuery Source Code Structure [duplicate]

Uncompressed jQuery file: http://code.jquery.com/jquery-2.0.3.js
jQuery Source code: https://github.com/jquery/jquery/blob/master/src/core.js
What are they doing to make it seem like the final output is not using Require.js under the hood? Require.js examples tells you to insert the entire library into your code to make it work standalone as a single file.
Almond.js, a smaller version of Require.js also tell you to insert itself into your code to have a standalone javascript file.
When minified, I don't care for extra bloat, it's only a few extra killobytes (for almond.js), but unminified is barely readable. I have to scroll all the way down, past almond.js code to see my application logic.
Question
How can I make my code to be similar to jQuery, in which the final output does not look like a Frankenweenie?
Short answer:
You have to create your own custom build procedure.
Long answer
jQuery's build procedure works only because jQuery defines its modules according to a pattern that allows a convert function to transform the source into a distributed file that does not use define. If anyone wants to replicate what jQuery does, there's no shortcut: 1) the modules have to be designed according to a pattern which will allow stripping out the define calls, and 2) you have to have a custom conversion function. That's what jQuery does. The entire logic that combines the jQuery modules into one file is in build/tasks/build.js.
This file defines a custom configuration that it passes to r.js. The important option are:
out which is set to "dist/jquery.js". This is the single
file produced by the optimization.
wrap.startFile which is set to "src/intro.js". This file
will be prepended to dist/jquery.js.
wrap.endFile which is set to "src/outro.js". This file will
be appended to dist/jquery.js.
onBuildWrite which is set to convert. This is a custom function.
The convert function is called every time r.js wants to output a module into the final output file. The output of that function is what r.js writes to the final file. It does the following:
If a module is from the var/ directory, the module will be
transformed as follows. Let's take the case of
src/var/toString.js:
define([
"./class2type"
], function( class2type ) {
return class2type.toString;
});
It will become:
var toString = class2type.toString;
Otherwise, the define(...) call is replace with the contents of the callback passed to define, the final return statement is stripped and any assignments to exports are stripped.
I've omitted details that do not specifically pertain to your question.
You can use a tool called AMDClean by gfranko https://www.npmjs.org/package/amdclean
It's much simpler than what jQuery is doing and you can set it up quickly.
All you need to do is to create a very abstract module (the one that you want to expose to global scope) and include all your sub modules in it.
Another alternative that I've recently been using is browserify. You can export/import your modules the NodeJS way and use them in any browser. You need to compile them before using it. It also has gulp and grunt plugins for setting up a workflow. For better explanations read the documentations on browserify.org.

Dynamically resolve paths with RequireJS

Is there a way to dynamically resolve paths with RequireJS? For example, is it possible to configure it so that, if I do
require(['mymodule'], function(mod){ });
some sort of function of mine will be called, with "mymodule" being passed as a parameter, and with the value I return therefrom being used by Require as the path to use for mymodule?
I do understand that Require has some wonderful convention over configuration with respect to path resolution, and I also understand that paths can be manually configured. But right now I'm trying to add in RequireJS to an old project that was written without Require in mind, so I'm trying to see what all of my options are.
You might be best served by implementing a loader plugin.
Not sure if it's a problem for you, but this would mean your require syntax would turn into something like this:
require(['myplugin!mymodule'], function(mod){ });
The specific method you would use is normalize:
normalize is called to normalize the name used to identify a resource. Some resources could use relative paths, and need to be normalized to the full path. normalize is called with the following arguments:
EDIT: I see there's a replace plugin listed on the plugins wiki which sounds similar to what you are trying to do. It uses only the load method, so apparently what I said above about the normalize method is not a blanket rule.
If the path is truly dynamic, this won't help, but if you just need to modify how the legacy script is returned back to your modules (e.g. taking two different globals and putting them under a different top-level global), you might also think about using the init hook in the shim config option
EDIT 2: some related hacks are posted in this question: Configuring RequireJS to load from multiple CDNs

Django-pipeline and javascript dependencies

I'm working on a Django project that uses Django-pipeline for assets, and I keep having issues where I define something in one javascript file that is required by another file, but the second file gets loaded before the first and thus the second file fails to load properly. I can mess with the order things get included into PIPELINE_JS but this is pretty awkward to deal with. In most languages you can do things like require foo to make sure that foo is defined but it seems like with javascript and django-pipeline this isn't possible. I've looked into RequireJS a little but I'm not sure how whether I can use it with django-pipeline. What should I do in this case? What do others who use django-pipeline or django in general do for javascript dependency management?
As a side note, I'm actually using Coffeescript, not straight Javascript, but that doesn't seem to help things any. In rails I could do #= require 'foo' to require another coffeescript file but that seems to be linked to the rails asset pipeline.
The only way to do this is to order 'source_filenames' list accordingly, also remember that those file will be concatenated in this order when running collectstatic.
Pipeline will respect this order, it will also avoid duplicate so that your are safe when doing this :
'base.coffee',
'*.coffee',
There is no "require" syntax for now in django-pipeline.
Hope this helps.

Categories

Resources