requirejs and ByteBuffer - javascript

im an javascript newbie and google didnt helps:
I tryed to load ByteBuffer.js in an require.js module:
define(['js/ByteBufferAB'], function (ByteBufferAB) {
var MessageBase = function () {
this._version = 0; // unsinged int 16 bits
this._dataType = "";
};
MessageBase.prototype.toBytes = function () {
//console.log( new ByteBufferAB(58));
var headerBytes = new ByteBufferAB(58); // <-- here comes the error
headerBytes.clear();
return headerBytes;
};
return MessageBase;
});
with the same syntax math.js is properly loaded.
But with ByteBufferAB.js the following error comes:
Uncaught TypeError: undefined is not a function
What am I doing wrong?
Thank you for your help

In your define call you refer to the module as js/ByteBufferAB so RequireJS looks for a module named js/ByteBufferAB. However, the module defines itself as ByteBuffer:
/* AMD */ else if (typeof define === 'function' && define["amd"])
define("ByteBuffer", ["Long"], function(Long) { return loadByteBuffer(Long); });
Because the module name is hardcoded, you need to have a mapping like this in your paths in the configuration you give to RequireJS:
ByteBuffer: "js/ByteBufferAB"
and you need to refer to the module as ByteBuffer in your define call.
None of this would be required if the developers for this library had not hardcoded a name but they have, and so here we are.

Related

webpack plugin to replace a function with another

I am trying to create a webpack plugin, that will parse the code for a certain function and replace it with another function, that plugin will also expose the new function as a global.
class someName {
constructor(local, domain, translationFile, options) {
}
apply(compiler) {
// exposing ngt function as a global
compiler.plugin('make', function(compilation, callback) {
var childCompiler = compilation.createChildCompiler('someNameExpose');
childCompiler.apply(new webpack.DefinePlugin({
ngt: function(singular , plural, quantity) {
return quantity == 1 ? singular : plural;
}
}));
childCompiler.runAsChild(callback);
});
// searching for the getValue function
compiler.parser.plugin(`call getValue`, function someNameHandler(expr) {
// create a function to replace getValue with
let results = 'ngt('+ expr.arguments +')';
const dep = new ConstDependency(results, expr.range);
dep.loc = expr.loc;
this.state.current.addDependency(dep);
return true;
});
}
}
module.exports = someName;
update / rephrase
I have an issue here, when compiler.parser.plugin('call getValue', function someNameHandler(expr) {...} block is commented the ngt function exist as a global.
when its not commented, i get an error, ngt is undefined.
commented i mean /**/
I found a workaround for that but its far then idea. right now what I do is I export an anonymous function that does what i want.
You can see the plugin here:
Github
You can override the method based on environment. Let's say you have a method
function a(){
//original defination
}
Now based on the environment, if it's a production you could do something like this
if (environment.production) {
function a(){
//overridden defination
}
}
You can use the webpack-merge plugin, it's very useful to do exactly what do you want.
https://github.com/survivejs/webpack-merge

Pass functions in a vm script context

Let's say I have a library module that looks like this:
module.exports = {
increment: function() {
count++;
}
}
And I'd like to use it in a dynamically generated script that looks like this:
(function() { lib.increment(); })();
by passing it in a sandbox:
var sandbox = {
count: 1
lib: require('./lib')
}
var script = new vm.Script('(function() { lib.increment() })();');
script.runInNewContext(sandbox);
The obvious problem I run into is that I on the one hand can't require "lib" because "count" is not defined in lib.js ; on the other hand if I define var count above the exports of the "lib.js" file, this new count variable will be affected instead of the one in the sandbox.
Here are the constraints that I would like to respect:
Use vm and not a eval() nor a require() on a generated file
Have "lib" defined in a external file
No modification of the automatically generated script, so no use of lib.increment.apply(context) or similar
The only solutions I've found so far is to prepend the lib functions in the generated script as a string, or to define them directly on the sandbox object, which I find to be a less desirable option.
There doesn't seem to be any way of passing a context of variables on the require call.
One way of accomplishing this is have your lib module be a function that takes in a context then returns the correct interface.
lib.js
module.exports = function(context) {
var count = context.count;
return {
increment: function() {
count++;
}
};
};
main.js
var sandbox = {
count: 1
};
sandbox.lib = require('./lib')(sandbox);
var script = new vm.Script('(function() { lib.increment() })();');
script.runInNewContext(sandbox);

How to obtain a custom local requirejs

Is it possible to retrieve a require function with a custom local context?
Same as requiring a require from a module, but i need to arbitrarily choose the base path:
as this pseudo:
var custom_local_require = require.local('/base/url/');
custom_local_require('./path/to/module'); // will return module `/base/url/path/to/module.js`
[EDIT]
digging in requirejs code i found these
var ctx = requirejs.s.newContext(contextName);
ctx.makeRequire(relMap, options);
are requirejs.s.* safe apis ?
any documentation?
meanwhile i ended up with this..
function localrequire(baseurl) {
function path_relative_to(path) {
if (path.startsWith('.'))
return baseurl + path;
else
return path;
}
return function(deps, cb, eb) {
if (Array.prototype.isPrototypeOf(deps)) {
deps = deps.map(path_relative_to);
return require(deps, cb, eb);
} else {
var _local_path = path_relative_to(deps);
return require(_local_path);
}
}
}
var custom_local_require = localrequire('/base/url/');
custom_local_require('./path/to/module'); // will return module `/base/url/path/to/module.js`
seems to work but any suggestion and bug-smell is appreciated!
Got it!
as from docs there is a Multiversion Support for the purpose:
just call require.config with a context property, it returns an isolated require function with that configuration.
so, to solve my problem:
require.config({
baseUrl:'/mainbase/'
});
var _ctx_config = {
baseUrl:'/base/url/'
// any other config may be added here
// they will be kept isolated
};
var custom_local_require = require.config(_ctx_config);
custom_local_require('path/to/module'); // will return module `/base/url/path/to/module.js`
require('path/to/module'); // will return module `/mainbase/path/to/module.js`

Many new instances of requirejs module

I am creating a typing game which I have "app.js" as a main and loading "words.js" by requirejs.
I need to use > 2 words but I am still naive with javascript and not sure this is right to do in AMD. Anyone could point me out. I would really appreciate it.
I think it would be like following code but it doesn't work and give me error
"Uncaught TypeError: object is not a function"
[app.js]
require(['jquery','app/canvas','app/words'], function($,game_screen,words){
var words1 = new words();
var words2 = new words();
.
.
});
[words.js]
define(['app/canvas'],function(canvas){
var word_list=[{"word1"},{"word2"},...];
return {
addWord: function(new_word){
.
.
});
Right now you're returning an object from your words module: { addWord: function() {} ... }. So in app.js, when you set words to be equal to the object returned from the words module, you would invoke the functions by doing words.addWord().
If instead you want to use the new words() syntax in app.js, you would have to change your words module to return a function instead of an object (hence the error):
define(['app/canvas'],function(canvas) {
var word_list=[{"word1"},{"word2"},...]; // not sure how this is used
function words() {
// some code
}
words.prototype.addWords = function() {
// some code
}
return words;
}

RequireJs dependency always undefined

I am using require Js and am getting rather confused as to why my modules are loading but dependencies are always undefined and even upon using require.defined() function to check if my module has been loaded it indeed has been but when I use the require([deps], function(deps){}); all of my dependencies are undefined (except for jquery, underscore and knockout)
my file structure is as follows
my file structure is as follows
scripts
|
|
main.js
|
|_________BusinessScripts
| |
| |
jquery.js |
| |
| boostrapper.js-undefined
ko.js |
|
dataservice.js-undefined
here is an example of my main file that kicks off require
requirejs.config(
{
paths: {
'jquery': 'jquery-1.7.1',
'underscore': 'underscore',
'ko': 'knockout-2.2.1'
},
shim: {
underscore: { exports: '_' },
}
}
);
requirejs(['require', 'BusinessScripts/bootstrapper', 'BusinessScripts/dataservice'],
function (require,bootstrapper, dataservice) {
var def = require.defined('BusinessScripts/bootstrapper'); //this returns true
if (dataservice !== undefined) { // always undefined
alert("Loaded properly");
} else {
alert("not loaded!!!");
}
if (bootstrapper !== undefined) { // always undefined
alert("Loaded properly");
} else {
alert("not loaded!!!");
}
});
my data service class does a quite lengthy jquery get but as a simple example my bootstrapper is doing next to nothing
//bootstrapper
define(function () { var one = 1;
var run = function () {
}
});
//dataservice
define(['jquery', 'underscore'],function ($, _) {
$.ajax({lengthy work...});
});
as I said both modules are being loaded but are never resolving
any help would be much appreciated.
You're not returning anything from your bootstrapper or dataservice modules, so the "public" part of the module is undefined. RequireJS simply executes body of the define function and returns undefined implicitly. I think a good analogy is to think of a module as a black box with all internals hidden, only allowing access through the public interface (which is whatever you return from module's final return statement)
You should rewrite your modules a bit, for example:
bootstrapper.js
define(function () {
var one = 1;
var run = function () {
console.log('Running...');
}
return {
publicRun: run,
publicOne: one
}
});
dataservice.js
define(['jquery', 'underscore'],function ($, _) {
$.ajax({
// lengthy work...
});
return 'Lengthy work started!';
});
Then you could use these modules like this:
requirejs(['require', 'BusinessScripts/bootstrapper', 'BusinessScripts/dataservice'],
function (require, bootstrapper, dataservice) {
// prints "1"
console.log(dataservice.publicOne);
// prints "Running..."
dataservice.publicRun();
// prints "Lengthy work started!"
console.log(bootstrapper);
});
The official docs covers the topic of defining modules in detail, I'd recommend reading as much documentation as possible before diving in.
This answer doesn't fully 'match' the question's (specific) circumstance, but it may help someone for the (general) question - Why is my dependency undefined?
Tip: Double check that your dependency isn't dependent on the thing you're trying to get dependent on...
i.e. If you want A to depend on B, double check that B isn't depending on A.

Categories