Problems using aws-sdk in the browser with browserify - javascript

I am working on browser based application that makes use of aws-sdk. I am using browserify for my app code but have not figured out how to roll aws into it. I have tried a couple of different approaches:
//MyApp.js - Take 1 using downloaded minified version
var AWS = require ('./aws-sdk.min.js');
...
AWS.config.region='us-east-2';
...
results in Cannot set property 'region' of undefined
My guess is that this doesn't work because browserify does not resolve the minified code.
//MyApp.js - Take 2 using downloaded development version
var AWS = require ('./aws-sdk.js');
This does not compile. Browserify reports Error: Cannot find module '../lib/core'.
Is there a trick to this that I am missing?

When I used AWS in the browser I set my region depending on the service I need, for example:
new AWS.EC2({apiVersion: '2016-11-15', credentials, region})
So this made me wonder, maybe the version you downloaded is encapsulated and not exposing anything for browserify.
First I tested the version in the browser as follows:
console.log(AWS)
<script src="https://cdnjs.cloudflare.com/ajax/libs/aws-sdk/2.184.0/aws-sdk.min.js"></script>
Everything looked good so then I went ahead and tested on browserify.
Turns out you are reassigning the AWS global variable when you do:
var AWS = require ('./aws-sdk.min.js');
But you are already bundling it, so you are good, what you need to do is the following:
require ('./aws-sdk.min.js');
// And then use it happily
AWS.config.region='us-east-2';
Without reassigning the AWS global variable

Related

Sharing global between JavaScript files without using modules/exports

I have a self contained JavaScript function in one file, and some Mocha BDD tests in another file that reference it using [nodejs] require(). So in my function under test I export using module.exports. That's all well and good, in the IDE/build.
Now my function under test is actually an external virtual endpoint, which when deployed into a cloud instance, runs standalone inside a JSVM sandbox (Otto) which has no support for exports or modules, and is ES5 based (it does however embed a version of the Underscore library). If I leave the nodejs module definition in there when I deploy to cloud, it kicks off an error at runtime (as Otto doesn't recognise modules). So I want to remove it, and use some vanilla JS mechanism for the linkage back to the Mocha tests and test runner.
So my question is, if I can't use nodejs or requirejs modules, how can I link my Mocha tests in one file to a JS function in another? I had a play with placing a function closure (which most module implementations use) in the file under test, and Otto is happy with this, as its vanilla JS, but any variable with global scope in the file is still not visible from my test file, so there is no linkage.
Any thoughts?
From a quick look at the Otto docs, it looks like Otto only wants whole files and (as you've said) doesn't recogise commonjs modules from node.
If you've got many files I would recommend bundling them into a single file with webpack/browserify/etc, which is how most people convert modules for use in the browser, which similarily doesn't recognise commonjs modules without tooling.
Alternatively, you could convert all the module.exports to simple var declarations, concatenate the files together and hope you don't have a naming collision.
I don't see anything in the docs about having access to a window or global object to hang globals onto, which limits your options
One of my colleague came up with a suggestion to use closure in the file under test which gets deployed into the cloud instance, if you are running under Nodejs, and conditionally do the export. I added the small anonymous closure below to do this, and Otto doesn't complain.
(function () {
if (typeof module != 'undefined') {
module.exports = pdp_virtual_endpoint;
}
}());
Not sure why I didn't think about this earlier :)

Attempting to load a JavaScript sdk into an Angular2 application. Can't find all dependencies

I'm attempting to make use of this library: https://github.com/MagicTheGathering/mtg-sdk-javascript in an Angular2 application.
Unfortunately, I've been going in circles trying to load it into my application.
Firstly, on the TypeScript side if I import it using:
import { } from 'mtgsdk';
there are no types to load into the {}.
If I attempt to load it using something similar to:
import * as mtg from 'mtgsdk'
I'm unable to because it says that it's unable to find a module named mtgsdk.
I've installed the module using
npm install --save mtgsdk
Also, npm installs work fine for other modules.
The application compiles fine if I load it in using require via something similar to this:
var mtg = require('mtgsdk');
Taking that approach, I'm able to compile and launch but in the browser I get a number of errors about modules that it can't find. I figure they are prerequisites for the sdk that didn't get loaded so I start bringing them in via package.json.
For every one that I bring in, I then have to go to systemjs.config.js and add an entry pointing to the module's entry point and often have to specify a default extension using blocks like this:
pointer
'mtgsdk': 'npm:mtgsdk/lib/index.js',
'request-promise': 'npm:request-promise/lib/rp.js',
'ramda': 'npm:ramda/dist/ramda.js',
'emitter20': 'npm:emitter20/index.js',
'bluebird': 'npm:bluebird/js/browser/bluebird.js',
'request': 'npm:request/index.js'
default extension
'request-promise':
{
defaultExtension: 'js'
}
I'm not sure if that's the right approach though because the more dependencies I add, the more that I end up requiring. At one point I had literally gotten up to 50 extra dependencies added because every time I launched, the browser console would find more that were needed.
Is there any easier way to load all of these in?
Also, some of them (such as tough-cookie and request-promise-core) were very problematic to load and I couldn't get the browser console to stop complaining about them. Finally, some of them seemed very basic such as url, http, https. Those seem like they should already be present.
Using systemjs was utilized in the previous versions of Angular 2, However Angular 2 has evolved to Angular 4, with super new features like Angular CLI.
I recommend your use Angular CLI, with #angular/cli.
Importing Node modules
Since mtgsdk is a node-module, you can easily import it using
import * as mtg from 'mtgsdk'
However for your program to compile, you must install a type definition for it. or declare one for it in /typings.json or your app might not build.
Importing Client Scripts
For client scripts like firebase.js you won't need to add client scripts as entries in systemjs.config.js again.
Using #angular/cli, you would easily add them in the scripts[] array in your angular-cli.json for automatic compilation.
Then access them like this
declare const firebase: any;
Here is a quickstart tutorial to set up Angular with #angular/cli.

Require is not working for node-opcua

I want to load a local version of node-opcua with 'require' inside a HTML file, but it does not really work. The code snippet is the following:
<script type="text/javascript" src="path_to_require.js"></script>
<script>
var opcua = require(["path_to_node-opcua"]); <!-- Yes, the path is correct >
var client = new opcua.OPCUAClient();
...
When I execute the script I get the following error in the console:
Uncaught TypeError: opcua.OPCUAClient is not a constructor
Hence, var opcua is loaded correctly, but OPCUACluent is not, although the class is declared in a file that is present in the node-opcua folder called opcua_client.js under node-opcua\lib\client\
Sources:
The 'require' script from http://requirejs.org/docs/download.html#requirejs.
The node-opcua folder with the console command
npm install node-opcua.
node-opcua is not intended to run inside a browser as it relies on nodejs specific features such as filesystem access, crypto and so on.
You need to use browserify if you want to use that module in client. You will also need to look at how to use browserify with file system access (it can be done if paths are known ahead of time).

Problems concerning require() javascript

I'm trying to run the JavaScript client for the Tumblr API but I'm getting a "require not defined" error. I've scoured almost every corner of SO trying to find a way to make it work.
I've managed to use Browserify to recognize it but at some point, I'm getting a fs.readFileSync error.
Then I tried RequireJS and again it does the require thing but I'm getting a Module name "something" has not been loaded yet for context"
I'm really new to Node.js but if I'm understanding it correctly the require() part isn't something the browser can do right? Can anyone guide me as to what solutions I can take for this? If it helps, I'm not planning to upload this on a server or anything. I'm just trying to run it on my local computer and just planning to run the API locally.
Edit:
Here's what I have on my main.js
var tumblr = require('index.js');
var client = tumblr.createClient({
consumer_key: '<consumer key>',
consumer_secret: '<consumer secret>',
token: '<token>',
token_secret: '<token secret>'
});
// Show user's blog names
client.userInfo(function (err, data) {
data.user.blogs.forEach(function (blog) {
alert('dang');
});
});
When I try requirejs, I do this to reference it <script data-main="script/main" src="scripts/require.js"></script>
It seems to me that you might be confusing server-side JavaScript (Node) and client-side JavaScript (in the browser). The Tumblr API you're trying to use is for Node only; you can't run it in a browser. You have to:
Install NodeJS and NPM on your system
npm install tumblr.js
Run the script with node <script name>
Start with the Tumblr.js example script, then customize for your own purposes!

Basic requirejs concept needed to make work musicjson package

I'd like to use the musicjson.js package that helps to convert musicXML files into json notation, looking if it's a good way to import for example exported musicXML Finale scores into a browser playing with the Fermata/VexFlow class.
https://github.com/saebekassebil/musicjson
The thing is that this module works with require (calling for
nodes packages like fs) and I'm just a newbee in requirejs...Even if I spent few time in understanding the tutorial in the website, I don't still get how to solve this kind of basic problem when the dependencies of my musicjson.js need to be called like :
var xmldom = require('flat-xmldom'),
fs = require('fs'),
path = require('path'),
util = require('util');
My index.php page does the classic require call:
<!DOCTYPE html>
<head>
<!-- javascript head -->
<!-- REQUIRE -->
<script data-main="scripts/main" src="bower_components/requirejs/require.js"></script>
</head>
<body>
</body>
</html>
In my scripts/main.js, I'd like to do simply what it is told from musicjon :
var music = require('musicjson');
music.musicJSON(xml, function(err, json) {
// Do something with the MusicJSON data
});
I putted also, in the same directory scripts/, the flat-xmldom folder, fs.js, path.js, util.js
When I do this, I've just obtain this classic error of :
*Error: Module name "musicjson" has not been loaded yet for context: _. Use require([])*
...That looks like a common error referenced in the requirejs website,
but if I try things that I guess it should be written, I get a bit lost to determine where is the fundamental conceptual mistake here :
require.config({
baseUrl: '/scripts/',
paths: {
flatxmldom:'./flat-xmldom/__package__',
fs: 'fs',
path:'path',
util:'util',
musicjson: 'musicjson'
}
});
require(['flatxmldom','fs','path','util','musicjson'],function(flatxmldom,fs,path,util,musicjson){})
Error returned in this case for example :
*Module name "fs" has not been loaded yet for context: _. Use require([])*
Thanks a lot for your attention.
So, this is not a RequireJS problem per-se. The package you want to use is a Node.js package. It is intended to run in node (a server/desktop execution environment for JavaScript). It cannot/will not run in web page in a browser.
The packages it is trying to use (fs in particular) provide access to system resources such as the file system. Node provides these packages as part of its core libraries to any package that runs in node. A browser is specifically designed for security reasons never to allow direct access to such resources to any code that run in the browser because who knows where it came from or might try to do.
I haven't really tried to do this myself, but browserify (alternative to requirejs) claims that it will allow you to use any node package in your application.
If musicjson is at the heart of what your app should achieve and requirejs is a small step on the way to getting there, you could try your luck with browserify instead.

Categories

Resources