Using a third party library in a node application - javascript

In my server.js I have the following functions:
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.json());
I have to use this library as well but I cannot figure out how to use this?
The documentation say that I can just do npm install node-uuid and var uuid = require('node-uuid');
I tried to add var uuid = require('node-uuid'); to server.js but I cannot use uuid in any controller js file like var id = uuid.v1();. I get Error: Can't find variable: uuid.
The controller file looks like this:
(function() {
angular
.module("WebApp")
.controller("TestController", TestController);
function TestController($location) {
// need to get a uuid here
}
})();
How should I use this library?

If your code above client-side code and you really trying to achieve that on client side with angular framework you can try AngularJS wrapper for the original node-uuid library i.e angular-uuid.
Create angular-uuid.js file in your js folder of client
use this link to copy the contents for this file
https://github.com/munkychop/angular-uuid/blob/master/angular-uuid.js
and save this file with the copied contents.
use a regular script tag to include this lib
<script src="angular-uuid.js"></script>
Include angular-uuid in your module defination and inject that in your controller
(function() {
angular
.module("WebApp",["angular-uuid"])
.controller("TestController", ["uuid",TestController]);
function TestController(uuid) {
// need to get a uuid here
}
})();

npm install won't do you any good in your client-side angular code since it has no access to the node_modules.
In the page you linked above, the instructions say to include it in your html with something like:
<script src="uuid.js"></script>
If you do that, then if your controller code runs after the script noted above has been loaded, then you should be good to go.
If your code above isn't client-side code, then I'm not sure what you're doing with angular on the server side.
NOTE: If you're using bundling with something like web-pack then you could use npm to install the uuid library. Please let us know if you're doing that.

You can still use node modules in the frontend if you use a bundler like webpack or browserify. In that case you can do:
var uuid = require('uuid');
Just like you can on the backend. Make sure you link the files bundled by the bundler you chose, and this should work.
Keep in mind that there's a (slight) performance difference between loading it in a script tag (more http requests) vs using a bundler (larger file size).

Related

Typescript - including 3rd party code in released code

Having a simple Typescript project I'm using Gulp to build individual JS files from my TS files (I'm doing this as I have multiple HTML files which are to remain separate).
var tsResult = gulp.src('./src/ts/**/*.ts')
.pipe(ts(tsProject));
return merge([ // Merge the two output streams, so this task is finished when the IO of both operations are done.
tsResult.dts.pipe(gulp.dest('release/definitions')),
tsResult.js.pipe(gulp.dest('release/js'))
]);
So inside my HTML I'll have something like -
<script src="./js/myTSfileTranspiledToJS.js"></script>
Lets say that the TS file had a reference to a 3rd party code base such as jQuery. The code builds and deploys fine with no errors, but when I go to call a method in my TS/JS that contains the jQuery it fails.
This is because when runs it has no jQuery code.
Now I can include the jQuery code using a script tag -
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
but I'd rather not. Is there any way of including/bundling the 3rd party code into the transpiled JS files.
EDIT
To be clear - I'm looking to have a Typescript project that generates some JS files and anything that those JS files depend on should be bundled with them without the need to load them separately.
So if A.js requires B.js, then I want the build to see that and include B.js with A.js to save me adding B.js to some html file.
As an answer below has suggested - Broswerify, but I've not figured that out yet in my setup.
You can just do something like here, where you add the script tag to the document with JavaScript:
<script type="text/javascript">
document.write("\<script src='//ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js' type='text/javascript'>\<\/script>");
</script>
Another method would be to use Browserify or RequireJS. However you must always check the license of any project you include in yours. It wouldn't be anything unusual to provide a Get Started code block and include a
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js"></script>
in it on the other hand, and that is what I'd recommend as many people use jQuery also on their own in their JS projects.
Using mainbowerfiles in gulp (pulled in jquery with bower)
Install jquery with bower
bower install --save jquery
In the html
<script src="./js/site.min.js"></script>
in your gulp file
var gulp = require('gulp'),
uglify = require("gulp-uglify"), //uglify
filter = require("gulp-filter"), //filters
concat = require("gulp-concat"), //concat files
mainBowerFiles = require('main-bower-files'); //auto get bower modules
var paths = {};
paths.jsSource = mainBowerFiles().concat(["js/myTSfileTranspiledToJS.js"]);
paths.baseReleaseFolder = "js";
paths.baseJSReleaseFile = "site.min.js";
gulp.task("min:js", function () {
var jsFilter = filter('**/*.js', { restore: true });
return gulp
.src(paths.jsSource)
.pipe(jsFilter)
.pipe(sourcemaps.init({loadMaps:true}))
.pipe(uglify())
.pipe(concat(paths.baseReleaseFolder + "/" + paths.baseJSReleaseFile))
.pipe(sourcemaps.write("."))
.pipe(gulp.dest("."))
.pipe(jsFilter.restore);
});
The answer to my question is to use webpack and the below link is a clear example which shows how to create a Typescript project and include 3rd party library's such as jQuery here - http://www.jbrantly.com/typescript-and-webpack/
This does have one downside at the moment in that it works with tsd.json config which is now deprecated in favour of using typings.json.
Still it answers this question, even if it leads to another.

I'd like to reuse code from another module in my Nodejs backend

I'm using the Yeoman Generator Angular Fullstack and I'd like to reuse JS code from different directories within my server directory. I'm referencing the file that has the functions I want like:
var something = require('/.path');
I get the error: "Cannot find module" in my terminal.
I tried a number of variations of the path working through all of the levels from server level down to file level where the given functions are contained. I looked at a few tutorials:
http://www.sitepoint.com/understanding-module-exports-exports-node-js/
AND
https://www.launchacademy.com/codecabulary/learn-javascript/node/modules
I clearly missed something. Each module of my nodejs has a controller with an exports.create function. All of my code for each module is contained within my exports.create function accept for other required modules. I have no problem requiring underscore or other libraries in my Node/Bower modules by the way.
To be as detailed as can be, I expected
var something = require('./directory/directory.controller.js');
var something = require('/.path');
The path you are using is likely incorrect. Probably you want to open the file called path.js contained in the same folder of the file from which you are importing it. In order to do that, you should change the import as follows :
var something = require('./path');
./path is a relative path where . stands for current directory.
/.path is an absolute path. In this case require is importing a hidden file in the root directory. I guess is not what you want.

browserify detect custom require()

I want to use a custom require() function in my application.
Namely I have node's standard require() and a custom one I wrote to require files starting from the root called rootRequire() which internally all it does is:
// rootRequire.js
var path = require('path');
var rootPath = __dirname;
global.rootRequire = function (modulePath) {
var filepath = path.join(rootPath, modulePath);
return require(filepath);
};
module.exports = rootRequire;
But even though rootRequire() internally uses node's require(), it does not pick up any files required through that method
Example:
require('rootRequire.js');
rootRequire('/A.js'); // server side it works, in the browser I get an error saying can't find module A.js
Perhaps, this will answer your question on why it is not working on browser.
Quoting the owner's comment: "Browserify can only analyze static requires. It is not in the scope of browserify to handle dynamic requires".
Technically, you are trying to load files dynamically from a variable with your custom require. Obviously, node.js can handle that.
In case of browserify, all requires are statically loaded and packaged when you run the CLI to build the bundle.
HTH.
What i recommend doing here is this:
First create a bundle to be required of anything you might use in rootRequire().
Something like browserify -r CURRENT_PATH/A.js -r CURRENT_PATH/B.js > rootRequirePackages.js
Then, in your webpage, you can include both rootRequirePackages.js and your regular browserified file.
Perhaps just use RequireJS ? It's simple to set up and relatively easy to use.

Requiring/running JavaScript outside of node-webkit application

Suppose I have the following app structure:
outer-folder/
├── my-app/
└── settings.js
where my-app/ is either the unbuilt directory that contains package.json or the packaged application my-app.exe or my-app.app.
I cannot package settings.js with the rest of my app, because I want this file to be editable by users, and loaded upon startup to configure my app. Moreover, I plan to allow settings.js to reside anywhere (for example, in the user's home directory) and be loadable from there.
This works fine when the app is unbuilt. I just have a relative path to the file and require() it like usual. But when the app is built (with grunt-node-webkit-builder if that makes a difference) this fails and I get the dreaded "Cannot find module" error.
I've searched the node-webkit wiki but can't find anything about this issue, am I missing something? What is the best way to load and run an external JavaScript file, like one would do with require(), from a packaged node-webkit app?
I suggest you to use the application data path.
See the documentation here
An exemple
var gui = require('nw.gui');
var path = require('path');
var yaml = require('js-yaml');
var fs = require('fs');
var confPath = path.join(gui.App.dataPath, 'conf', "dev-conf.yml");
try {
conf = yaml.load(fs.readFileSync(confPath, 'utf-8'));
} catch (err) {
throw new Error("Cannot read or parse configuration file '"+confPath+"': "+err);
}
It's a good pratice to separate code and configuration, and App.dataPath aims at the application specific folder in user's application data (different for each OS).
I generally use an installer to copy my configuration file into it.
Next tip: I prefer using YAML instead of JSON for my configuration or settings, because it allows you to insert comments inside the file.

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