How to import other javascript module in PhantomJS or CasperJS - javascript

I'm trying to build a functional test using CasperJS.
caseperjs is run by a backend test suite using the following command:
PHANTOMJS_EXECUTABLE=../client/node_modules/phantomjs/bin/phantomjs ../client/ext_modules/casperjs/bin/casperjs test ../client/test/functional/init.coffee
In init.coffee I want to import/include other module (file) which seats just next to it. How to do it?
The following doesn't works:
require("user")
All I want is to get a content from other file into init.coffee

After trying a number of the other suggestions (each expected to work in the context of their corresponding environments), hit on this solution:
phantom.page.injectJs( 'script.js');

As of 1.1, CasperJS relies on PhantomJS’ native require():
https://groups.google.com/forum/#!topic/phantomjs/0-DYnNn_6Bs
Injecting dependencies
While injecting additional modules, CasperJS looks for path relative to cur directory
(the place where we run a casperjs command)
We can inject dependency using clientScripts option. However the injected dependencies can't
use require "globally". They are injected immediately to every page loaded.
casper.options.clientScripts = ["path/relative/to/cur/dir"]
Also we can inject modules using commandline args:
casperjs test --includes=foo.js,bar.js path/to/the/test/file
Using require
To import user modules use:
require "./user-module.coffee"
Then in user modules you can also use require. Using require paths are resolved
relative to the current file (where require is called).
If in user module you want to import casper libs, then you need to patch require,
check: https://casperjs.readthedocs.org/en/latest/writing_modules.html

There's a section about that in the docs
var require = patchRequire(global.require);
require('./user');
In your case you should use global.require since you're using CoffeeScript.

Related

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.

How to use Node.js packages within a client-side html document using browserify

I'm unable to use a node.js module on my website with broweserify. The example only shows how to run a javascript file that is separate from the .html file, not how to use the node.js module within the .html file. Seems like a trivial problem, but I'm unable to make it work.
Here's what I've done:
Initialized node.js & installed a package, npm i webtorrent-health as an example
Created require_stuff.js which consists of a single line: var WebtorrentHealth = require('webtorrent-health')
Run browserify: browserify require_stuff.js > bundle.js
Include package in my html document, e.g. <script src='bundle.js'></script>
Use the package somewhere in my document, e.g. like this: <script>webtorrentHealth(magnet).then(foobazbar())</script>
Despite bundle.js executing and seemingly defining webtorrentHealth, the script within the .html document fails with WebtorrentHealth is not defined. What am I doing wrong? How do I make it work? Thank you!
You're very close to what you want to achieve. In fact, your code bundle.js is inaccessible from outside (in your case the browser) due to browserify, but you can expose your module by writing at the end of your file require_stuff.js:
window.WebtorrentHealth = WebtorrentHealth;
Now you can use WebtorrentHealth in your document.

Use Browserify with JavaScript libraries such as Backbone or Underscore?

I know I can install underscore using npm but that's not what I can do in my work environment. I need to be able to download the Underscore.js library and then make it "browserify-compatible".
So let's assume Underscore.js looks something like this:
(function() {
var root = this;
// Rest of the code
}.call(this));
I downloaded that file on my hard drive and saved it as under.js.
My file that requires underscore looks like this:
var underscore = require("./under");
console.log(underscore);
And then I run browserify from the cli.
I have an HTML page called test.html and basically all it does is load the generated bundle.js.
However, the console.log(underscore) line fails - says that underscore is undefined.
What have I tried?
Obviously I added module.exports to the first line - right before the function definition in under.js, and that's how I got the error mentioned above. I also tried the method from this answer , still got the same error.
So, how would I use Browserify to load libraries such as Underscore.js or Backbone without using npm-installed modules?
That's because browserify does not add variables to the global scope. The version you download is identical to the version that you install via NPM.
You need to explicitly attach it to the window to export it to the top level scope.
If you create a file called "expose_underscore.js" and put this in it:
var _ = require('./under');
window._ = _;
Will do it, followed by: browserify expose_underscore.js > bundle.js and then add bundle.js as a <script> tag you will be able to do the following in your console:
HOWEVER, you shouldn't do this if you're using browserify. The point behind it (and Node's version of commonJS) is that you explicitly require it everywhere you need it. So every file you have that needs underscore should import it to a local variable.
Don't worry -- you will still only have one copy loaded.
I typically add my vendor libs like Underscore as script tags. Underscore will attach itself to the global scope, so then you don't need to require it anywhere to use it.
If you do want to use it in a Browserified fashion, verify that you have the correct path in your require statement (browserify requires are relative paths) and move the module.exports statement to the end of the file.

Browserify including entire module when only some parts used (react-addons)

I'm using Browserify to bundle serverside react.js code for the client.
However, I have a bad feeling that using a module from within an npm package results in that entire package being bundled by Browserify.
Q: Does require('react-addons').LinkedStateMixin result in the entire react-addons package being bundled into my Browserified JS?
IE: does Browserify treat require('react-addons').LinkedStateMixin the same as require('react-addons')?
If so, is there any way around this? External tools, Browserify options etc.
Browserify does not have the ability to extract parts of the functionality from a module.
What you can do though, is require the desired module from within react-addons like this:
require('react-addons/lib/LinkedStateMixin')
This will only include the one module (and it's dependencies) in your bundle. However, you now depend on the internal structure of the module. If the LinkedStateMixin is renamed, you will have to change your require statement.
#mantoni was helpful but as this is a react-addons specific question i will post my answer.
Don't use react-addons and react side by side. Instead, when requiring React use require('react/addons'). This calls a script at /addons/ that returns the full React with addons.
So for my example:
var React = require('react/addons');
var LinkedStateMixin = React.LinkedStateMixin;
//this works as normal!
React.createClass({});
Thanks guys!
In ReactJS 0.13.3 if you want to use e.g. CSSTransitionGroup you have to do the next:
var React = require('react/addons'),
CSSTransitionGroup = React.addons.CSSTransitionGroup;
And all that has to be installed – npm install react.

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.

Categories

Resources