angular module is not available - angularjs-module

This is surely a noob question but I just can't seem to figure out what is wrong with this simple module initiation (JSFiddle):
var myApp = angular.module('myApp', []);
I get an error saying that "Module 'myApp' is not available!". Does anyone know why this does not work?

It's because (in the fiddle at least) that the script is run on window.onload, thus angular cannot find the module before it sees in the DOM that there should be a module named myApp.
before it was (in the head):
window.onload = function() {
angular.module(...)
}
but it had to be:
angular.module(...)
ie. not waiting until the document was fully loaded, thus creating the module before angular sees that it should bootstrap the module myApp.
updated fiddle

Related

Making a node module with js_of_ocaml

The js_of_ocaml documentation says about making a Node.js module:
Js.export and Js.export_all will export a value to module.exports if it exists.
What I'm confused about is the "if it exists" part. How do I make sure that the module def exists? i.e. if I'm making an OCaml library that I'd like to be able to import from JavaScript (TypeScript actually), how can I make sure that I get such a module as the output of js_of_ocaml?
If module.exports exists, a value is exported as node module.
And if module.exports doesn't exists (on web browser for example), a value is exported as global variable.

Using node require with Electron and Webpack

I am building a project with Electron, and using Webpack to build the (Angular 2) render process app.
In this app, I need to dynamically require some files at run-time which do not exist at build-time. The code looks something like this:
require("fs").readdirSync(this.path).forEach(file => {
let myModule = require(path.join(this.path, file));
// do stuff with myModule
});
The problem is that the Webpack compiler will convert the require() call to its own __webpack_require__() and at run-time, it will look in its own internal module registry for the dynamic "myModule" file, and of course will not find it.
I have tried using the "externals" config option, but since this is a dynamic require, it doesn't seem to be processed by "externals".
Anyone else had success in solving this problem?
As suggested in a comment to my question by #jantimon, the solution is to use global.require:
require("fs").readdirSync(this.path).forEach(file => {
let myModule = global.require(path.join(this.path, file));
// do stuff with myModule
});
I came across this article and for some other reason the author needs node modules which gets not transpiled by webpack. He suggested to use
new webpack.IgnorePlugin(new RegExp("^(fs|ipc)$"))
in the webpack.config.js file. This should prevent to transpile the module fs and ipc so it can be used (required) in code.
I am not really sure if this hits also your problem but it might help.
The original article for more context can be found here: https://medium.com/#Agro/developing-desktop-applications-with-electron-and-react-40d117d97564#.927tyjq0y

How to compile TypeScript code in the browser?

Is it possible to run the TypeScript compiler in the browser for transpiling TS to JS 100% in the browser. The use case would be implementing an online TypeScript IDE that runs 100% client side and it has a "Play" button to execute the project. So I need to transpile the project to JavaScript in order for the browser to execute the code.
I presume it should be as simple as loading the relevant typescript JS files, creating an instance of the right class (compiler?) and calling a method or two.
What would be the means suitable to load the Compiler in the browser? Where is the TypeScript Compiler API Reference Documentation ? Where should I start digging in ?
This isn't asking for any specific tool, but ANY way to do this with this particular computer language, and thus is on topic.
You can use typescript-script : https://github.com/basarat/typescript-script
However do not do this in production as it is going to be slow.
You can use webpack (or a similar module bundler) to load npm packages in the browser.
Transpiling ts to js is as simple as loading the typescriptServices.js file from typescript repo or npm, and using it's window.ts.transpile(tsCode)
JSFiddle
<script src="https://unpkg.com/typescript#latest/lib/typescriptServices.js"></script>
<script>
const tsCode = 'let num: number = 123;';
const jsCode = window.ts.transpile(tsCode);
document.write(jsCode);
</script>
Outputs:
var num = 123;
You can also pass the ts compiler options object as second argument to ts.transpile() to specify whether output js should be es2020, es5, es6, and other stuff, though for meaning of values you'll likely have to dive into the source code.
Since this question got re-opened (just as planned >:D), I'm also re-posting my comment here.
#basarat's solution was great; even though his lib is outdated and abandoned, it helped me a lot in writing another, self-sufficient modern lib with support for sub-dependencies: ts-browser
Usage: (given you use relative paths in all your ts files)
<!-- index.html -->
<script type="module">
import {loadModule} from 'https://klesun.github.io/ts-browser/src/ts-browser.js';
loadModule('./index.ts').then(indexModule => {
return indexModule.default(document.getElementById('composeCont'));
});
</script>
// index.ts
import {makePanel} from './utils/SomeDomMaker'; // will implicitly use file with .ts extension
export default (composeCont) => {
composeCont.appendChild(makePanel());
};

How to namespace modules in the browser but not in node

I have seen many examples of the self-invoking pattern that detects the global object (module.export / window) -- but I am not sure how to do namespacing with this pattern and still have it work in node the same way.
(function(exports) {
'use strict';
// how do i do something like this and have it work in node as well
// exports Namespace.Models.HelloWorld = function () {}
exports.say = function() {
return 'hello world';
};
}(typeof exports === 'undefined' ? this.helloworld = {} : exports));
After looking at the code some more I think you're code should work fine. What you want is to namespace all your code so that it doesn't pollute the global namespace right? So what you need is a single object in the global namespace that you then put all your code under.
Note: The global namespace in the browser is window in case you didn't know.
For example, JQuery creates only two global objects: jQuery and $. Everything you do with JQuery involves only those two global objects. JQuery even has a compatibility mode that disables the dollar sign so then you only have the jQuery object. The pattern people use to get the dollar sign back even when it's been disabled is to do this:
(function ($) {
// Do stuff with $
})(jQuery);
It's a self-invoking function that passes the jQuery object into itself which then becomes the $ argument. That way you can still have the convenience of the dollar sign without clogging up the global window object with yet another property. In your code (this.helloWorld) the this keyword refers to the global namespace (unless your code is wrapped inside another function or something and you didn't post it). What you've done is create a property on the window object (global namespace) called helloWorld, you set it to an empty object, and you pass it in. But you only do this if exports is undefined. That's the part that identifies if you're in node or not. exports will only be undefined if you're in the browser because exports is only available in node modules (just don't add an exports property to the global namespace in the browser, lol).
Note: Node has no application-wide "global" namespace that things get put into by default. Everything in node is scoped to the module level. So even if you define a variable on the first line of your module you can still define the exact same variable on the first line of another module and they won't conflict with each other. There is however, a global object in node that truly is global and you can access its properties from any module. I do not encourage you to use the global object, like, ever. If you need to use that object then you should probably reconsider your application structure.
Whatever you attach to exports in node becomes available to any other module that requires it.
// helloWorld.js
exports.message = "Hello, world!";
and then...
// main.js
var helloWorld = require('./helloWorld.js');
// Now all the properties are available on the variable `helloWorld`.
console.log(helloWorld.message);
// Prints "Hello, world!" to the console.
In the browser you want to do something similar by attaching a single uniquely named object to window and then whomever uses your script should access all your functions through that "namespace". So finally we have this:
// helloWorld.js
(function (myNamespace) {
myNamespace.message = "Hello, world!";
})(typeof exports === 'undefined' ? this.helloWorld = {} : exports)
If exports does not exist then add helloWorld to this (which refers to window when in the global scope like it is in this example) and pass that in. If exports does exist then pass it in instead. Now inside the function we can attach properties and methods to myNamespace and they'll either be attached to window.helloWorld or exports depending on the environment.
I could add the above helloWorld.js file to my node application and use it like this:
// nodeScript.js
var helloWorld = require('./helloWorld.js');
console.log(helloWorld.message);
Or I could add the above helloWorld.js file to my web app. Your page might look like this:
// index.html
<html>
<head>
<title>My Site</title>
<script src="helloWorld.js" />
<script src="clientScript.js" />
</head>
<body>
<div id="messageBox"></div>
</body>
</html>
And your script might look like this:
// clientScript.js
document.getElementById('messageBox').innerHTML = helloWorld.message;
The above page would end up with "Hello, world!" inside the div because it read the message from our module's exposed properties :)
Hopefully that clears things up. Sorry for jumping in with browserify at first instead of directly answering your original question. I do highly recommend browserify though :)
You need browserify. Write your modules in the node-style and then let browserify turn them into proper client-side scripts :)
From browserify home page:
Write your browser code with node.js-style requires:
// main.js
var foo = require('./foo');
var gamma = require('gamma');
var n = gamma(foo(5) * 3);
var txt = document.createTextNode(n);
document.body.appendChild(txt);
Export functionality by assigning onto module.exports or exports:
// foo.js
module.exports = function (n) { return n * 11 }
Install modules with npm:
npm install gamma
Now recursively bundle up all the required modules starting at main.js into a single file with the browserify command:
browserify main.js -o bundle.js
Browserify parses the AST for require() calls to traverse the entire dependency graph of your project.
Drop a single <script> tag into your html and you're done!
<script src="bundle.js"></script>
Not only is it fun to write client-side scripts like this but browserify will bundle it all together into a nice and tidy minified single script file :D

Requiring the same local node module from two directories results in two copies

I have a module (server.js) in the root of my project structure. It includes a module in a directory called lib:
var mongo = require('./lib/MongoUtils');
Another module in the lib directory also needs the 'MongoUtils' module, so it does:
var mongo = require('./MongoUtils');
The problem is I end up with two copies of the object (which is bad as it has some system resources like DB connections, etc.).
I've read the Node.js caching caveats documentation (http://nodejs.org/api/modules.html#modules_module_caching_caveats) and so it seems the problem is that I'm referring to the same module with two different paths and thus Node.js gives me two copies. Is this understanding correct?
How can I work around this? I didn't want to just dump my modules in node_modules since that's managed by npm via my package.json (and .gitignore-d). I thought about putting my local modules in the package.json (assuming that's possible), but then I'd need to be running 'npm install' whenever I make a change.
If this can't be done cleanly, I'll simply load the module in one place and pass it around, but that doesn't sound scalable if this occurs with lots of my modules.
I solved it. It turns out I typoed the capitalization of one of my modules. Node.js happily loaded the module and it worked fine, the only side effect was that I got the module loaded twice.
Here's an example. Note the capital B in the require statement in lib1.js.
main.js:
var lib1 = require('./lib/lib1')
, lib2 = require('./lib/lib2');
lib/lib1.js:
var lib2 = require('./liB2');
lib/lib2.js:
function MyClass() {
console.log('Constructor called');
}
module.exports = new MyClass();
If you run "node main.js" you'll get the following output:
Constructor called
Constructor called
If you fix the capital B in lib1.js and run it again, you'll see:
Constructor called

Resources