How can I make a npm module avaible in browser - node.js

I made a npm module, it works perfectly in node, but I laso want to make it avaible in browser as Socket.io is. In node I use it that way : var AIM = require('aimjs')(server)
server param is optional and is from http.Server (Node.js doc) if specified it serve a client version of the module as Socket.io do :
if (this.server != null) {
var listeners = this.server.listeners('request').slice()
this.server.removeAllListeners('request')
this.server.on('request', function (req, res) {
if (url.parse(req.url).pathname === '/AIM.js') {
res.setHeader('Content-Type', 'application/javascript')
res.writeHead(200)
res.end(fs.readFileSync(__dirname + '/AIM.client.js'))
} else {
for (var i = 0; i < listeners.length; i++) {
listeners[i].call(self.srv, req, res)
}
}
})
}
This file (AIM.client.js) is a browserified version of my main, but the module is not avaible outside. How can I make it global ? I want that users just have to install module, include <script type='text/javascript' src='/AIM.js'></script> and can use it both client side and server side.

When you browserify your file, use the --standalone (-s) option.
Example:
browserify index.js -s aimjs
This will make your file a UMD bundle.
If it is used in a CommonJS environment, it will behave as a CommonJS module.
If it is used in an AMD environment, it will behave as an AMD module.
If it is simply included via a script tag, it will attach itself to window.aimjs.

Related

Use global module in node

I have a node application with some modules.
I would like to use one of my module in this way:
Init the module inside server.js (the first file called from npm)
When the request is passed from socket set the request configuration inside my module
Use the module with the request configuration in other modules.
Example:
module.js
'use strict';
const Module = require('module');
let module = new Module({
some_information
});
function test(message) {
module.info(message);
}
function configureRequest(request) {
module.configure({
payload: {
request: request
}
});
}
module.exports = {
info,
configureRequest
};
server.js (little piece of code)
let module = require('./src/module.js');
get_request.js
let module = require('./src/logger.js');
let another = require('./src/another.js');
scServer.on('connection', function (socket) {
module.configureRequest(socket.request);
module.info('test'); //inside it there is request
another.start();
});
another.js
let module = require('./src/logger.js');
module.info('test'); //inside it there isn't request
As you can see inside another.js I require again my global module so the request is not set, I don't want if is possible to pass every time the request into all modules (I have many and many modules that use the global module)
How can I solve?
What I usually do is use consign module to autoload my modules inside my app. https://github.com/jarradseers/consign

change requireJS from adding the .js file extension automatically on intern.js

Currently I am working in custom html reporter for intern.js. The Templating engine that i am using is marko.js.
marko.js have extension file with ".marko" for me to input my html syntax
The file is generated correctly in normal node.js (common.js)
The issue occurred when i integrate the same code to intern.js. The requirejs(AMD) that use by internjs is adding the .js file extension automatically to my marko extension when i do
var template = require('./hello-world.marko');
which make the file become hello-world.marko.js and this caused the code broke in markojs
the custom html reporter code is below
define(function (require) {
// require('intern/dojo/node!marko/node-require').install();
var fs = require('intern/dojo/node!fs');
var template = require('./hello-world.marko');
console.log(template);
function JsonReporter(config) {
config = config || {};
this.output = config.output;
}
JsonReporter.prototype = {
runEnd(executor) {
// console.log("toJson: " + JSON.stringify(executor.suites))
data = JSON.stringify(executor.suites);
template.renderToString(data,
function (err, output) {
console.log(output);
fs.writeFile('result.html', output, function (err) {
if (err) return console.log(err);
console.log('Save done');
});
});
},
}
return JsonReporter;
})
The require function isn't really meant for loading arbitrary text resources in either Node's loader or an AMD loader. In Node, whether you're running Intern or not, you can use fs.readFile or fs.readFileSync. In Intern's Dojo-based AMD environment you can also use the dojo/text loader plugin, like this:
var template = require('dojo/text!./hello-world.marko');

Execute webpack compiled bundle in NodeJS

I want to implement server-side rendering for my ReactJS app. I use react-router. I take routes.js as webpack entry point and compile with output.libraryTarget = "commonjs2" option. Then I require the result of compilation in NodeJS script to make rendering. But I've got en error.
Webpack wrap modules in following code:
/* 277 */
/***/ function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(Buffer, global) {
if (global.foo) {
/* ... */
}
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(277).Buffer, (function() { return this; }())))
/***/ }
When NodeJS tries to execute (function() { return this; }()) its return undefined. In browser it will return window. Why webpack use such wrap code? How to make this code works in NodeJS?
I use node-clone as external lib. It don't use any other libs as dependency. But webpack in its bundle makes buffer as a dependency for this lib. And inside the buffer code I've got en error Cannot read property 'TYPED_ARRAY_SUPPORT' of undefined. It happens because in nodeJS (function() { return this; }()) return undefined.
By default, webpack will package things up for browsers. If you want to build Node libraries with webpack, you need to specifiy a target in your configuration:
module.exports = {
// ...
target: 'node',
};

How can I configure options using the traceur module on nodejs

How do I configure options using the traceur module on nodejs. I'm doing the following but it doesn't seem to work.
require('traceur').require.makeDefault(function(filename) {
// don't transpile our dependencies, just our app
return filename.indexOf('node_modules') === -1;
});
traceur.options.annotations = true;
require('./start.js');
traceur.options.annotations = true is not resulting in annotations being enabled in traceur
Pass the options as the second argument to makeDefault:
require('traceur').require.makeDefault(function(filename) {
// don't transpile our dependencies, just our app
return filename.indexOf('node_modules') === -1;
}, {annotations: true});
See https://github.com/google/traceur-compiler/blob/master/src/node/require.js#L58
You need to update use this feature.

phantomjs and requirejs

codes in file main.js is like this:
phantom.injectJs("libs/require-1.0.7.js");
require.config(
{
baseUrl: ""
}
);
require([], function(){});
when i run "phantomjs main.js" in the commandline, requirejs doesn't work well in the main.js. I know how to use requirejs in the page running in the browser(including phantomjs' way: page.open(url, callback)), but not like above. I tries using requirejs like the main.js, it is a popular problem, i think. Thank you!
I just struggled for some time. My solution is not clean, but it works, and I'm happy with that due to the unfinished api documentation from phantomjs.
Wordy explanation
You need three files. One is your amd phantomjs test file which I'll call "amd.js". The second is your html page to load which I'll name "amd.html". Finally the browser test which I called "amdTestModule.js".
In amd.html, declare your script tag per normal:
<script data-main="amdTestModule.js" src="require.js"></script>
In your phantomjs test file, this is where it gets hacky. Create your page, and load in the 'fs' module. This allows you to open a relative file path.
var page = require('webpage').create();
var fs = require('fs');
page.open('file://' + fs.absolute('tests/amd.html'));
Now since requirejs loads files asynchronously, we can't just pass in a callback into page.open and expect things to go smoothly. We need some way to either
1) Test our module in the browser and communicate the result back to our phantomjs context. Or
2) Tell our phantomjs context that upon loading all the resources, to run a test.
#1 was simpler for my case. I accomplished this via:
page.onConsoleMessage = function(msg) {
msg = msg.split('=');
if (msg[1] === 'success') {
console.log('amd test successful');
} else {
console.log('amd test failed');
}
phantom.exit();
};
**See full code below for my console.log message.
Now phantomjs apparently has an event api built in but it is undocumented. I was also successfully able to get request/response messages from their page.onResourceReceived and page.onResourceRequested - meaning you can debug when all your required modules are loaded. To communicate my test result however, I just used console.log.
Now what happens if the console.log message is never ran? The only way I could think of resolving this was to use setTimeout
setTimeout(function() {
console.log('amd test failed - timeout');
phantom.exit();
}, 500);
That should do it!
Full Code
directory structure
/projectRoot
/tests
- amd.js
- amdTestModule.js
- amd.html
- require.js (which I symlinked)
- <dependencies> (also symlinked)
amd.js
'use strict';
var page = require('webpage').create();
var fs = require('fs');
/*
page.onResourceRequested = function(req) {
console.log('\n');
console.log('REQUEST');
console.log(JSON.stringify(req, null, 4));
console.log('\n');
};
page.onResourceReceived = function(response) {
console.log('\n');
console.log('RESPONSE');
console.log('Response (#' + response.id + ', stage "' + response.stage + '"): ' + JSON.stringify(response, null, 4));
console.log('\n');
};
*/
page.onConsoleMessage = function(msg) {
msg = msg.split('=');
if (msg[1] === 'success') {
console.log('amd test successful');
} else {
console.log('amd test failed');
}
phantom.exit();
};
page.open('file://' + fs.absolute('tests/amd.html'));
setTimeout(function() {
console.log('amd test failed - timeout');
phantom.exit();
}, 500);
amd.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<script data-main='amdTestModule.js' src='require.js'></script>
</body>
</html>
amdTestModule.js
require([<dependencies>], function(<dependencies>) {
...
console.log(
(<test>) ? "test=success" : "test=failed"
);
});
console
$ phantomjs tests/amd.js
amd test successful
you are misunderstanding webpage.injectJs()
it's for injecting scripts into the page you are loading, not into the phantomjs runtime environment.
So using .injectJs() is making requirejs load up into your page, not into phantomjs.exe.
That said, phantomjs's runtime environment has an aproximation of commonjs. RequireJs will not run on there by default. If you felt especially (VERY) motivated, you could attempt porting the require-shim made for nodejs, but it doesn't work out of the box, and would require an incredibly deep understanding of the runtimes. for more details: http://requirejs.org/docs/node.html
a better idea:
probably you should make sure you have commonjs versions of your javascript you wish to run. i personally write my code in typescript so i can build for either commonjs or amd. i use commonjs for phantomjs code, and amd for nodejs and browser.

Resources