Running a script via NodeJS which imports from a library is failing because the library references the window variable. Even though in the library, it looks like this:
{
baseUrl: (typeof window !== undefined ? window.location.origin : '') + "/blah",
}
This line still results in the following error when running the script via NodeJS:
ReferenceError: window is not defined
I thought it was enough to add the typeof window !== undefined check but clearly that is not the case. What am I missing here? (FWIW the imported module is a UMD module.)
typeof gives you a string so you need to be comparing to "undefined", not undefined. Change your code to this:
{
baseUrl: (typeof window !== "undefined" ? window.location.origin : '') + "/blah",
}
Related
I got a doozie here. In Electron's main process, I require in the function below to setup event handlers with ipcMain. This keeps the main.js file a little more streamlined. All went swimmingly until I wrote some validation code to ensure that the user passes in an object. I use typeof all the time for this purpose, and never have I had an issue. But in Electron I am getting:
A JavaScript error occurred in the main process - TypeError: Cannot
assign to read only property 'exports' of object '# '
The code:
const {ipcMain} = require('electron');
function ipcSetup() {
ipcMain.on('123', function(event, arg) {
// this blows chunks...
if(arg && typeof arg === 'object') {
console.log(`All good....`);
}
// and if you comment that out, this use of "typeof" does the same thing
console.log(typeof arg);
// and to eliminate 'arg' as the issue...
let a = 1;
console.log(typeof a); // expect 'number', get Exception
});
}
module.exports = ipcSetup;
I didn't know if Electron is using Object.defineProperty to make arg read only, but typeof is not making an assignment here anyway, and I eliminated arg so this error makes no sense. Environment is Electron 1.8.4 on Node 8.2.1 using electron-vue
If you're importing that module in another module that uses ES6 import/export syntax, using typeof apparently causes this. I think this is because webpack doesn't support mixing the two syntaxes. But it is quite funny that it would work fine if you didn't use the typeof operator...
Does anyone have any examples of how to use reflect-metadata in nodejs? I am using atom-typescript also. I downloaded using it via npm but i keep getting random errors. I see Reflect is a blank object. Just looking for an example of how to incorporate this into a module or node project.
When I faced the same problem and nothing worked, I opened Reflect.ts file in node_modules. At the end, you can see it hooking Reflect at global level.
// hook global Reflect
(function(__global: any) {
if (typeof __global.Reflect !== "undefined") {
if (__global.Reflect !== Reflect) {
for (var p in Reflect) {
__global.Reflect[p] = (<any>Reflect)[p];
}
}
}
else {
__global.Reflect = Reflect;
}
})(
typeof window !== "undefined" ? window :
typeof WorkerGlobalScope !== "undefined" ? self :
typeof global !== "undefined" ? global :
Function("return this;")());
So, I removed require reflect-metadata from all other files, and moved it to main file.
require('reflect-metadata/Reflect');
Now, I can use it inside all modules (without requiring reflect-metadata) with the following syntax,
(<any>global).Reflect.getMetadata("design:type", target, key); // In Typescript
EDIT:
We can also reference reflect-metadata.d.ts file from node_modules and then use the API directly.
/// <reference path="../../node_modules/reflect-metadata/reflect-metadata.d.ts" />
Reflect.getMetadata("design:type", target, propertyKey);
In TypeScript#2.0+, you can use it like this:
npm i -S reflect-metadata
npm i -D #types/reflect-metadata
// your.ts
import 'reflect-metadata'
Reflect.getMetadata(...)
Reflect.metadata(...)
I'm having trouble rewriting this to work in 'strict' mode. Since 'this' is not defined explicitly I'm getting jshint errors on compile. I'm thinking my brain is just not thinking abstractly enough to find a creative solution. Any help would be appreciated. Code adapted from the Universal Module Definition Github repo: https://github.com/umdjs/umd/blob/master/returnExports.js
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD Module
define([], factory);
} else if (typeof module === 'object' && module.exports) {
// Node Module
module.exports = factory();
} else {
// Browser Global
root.returnExports = factory();
}
}(this, function () {
return {};
}));
Looking at your code, I see that root is only actually used in the case that you are in a browser, which simplifies things.
That means that we can replace this with the following expression:
typeof window !== "undefined" ? window : undefined
This is valid in strict mode (I tried it in Node, it returns undefined, no errors), and JSHint.com allowed it.
If you need the global object in other cases as well, you can chain the ternary expressions.
I'm trying to bring the Underscore.String library in to a Require.js project. The library is setup to support AMD, with the following code:
} else if (typeof define === 'function' && define.amd) {
// Register as a named module with AMD.
define('underscore.string', [], function() {
return _s;
});
But I have a problem: I don't keep the library in my root path, I keep it in "ext/underscore.string". This seems to make it impossible to require the library.
I have tried requiring both "ext/underscore.string" and "underscore.string", with and without defining a path (of "underscore.string": "ext/underscore.string"). When I don't have a path, and I require "underscore.string" the file (unsurprisingly) doesn't load, and in all other cases the file loads but the library doesn't get defined.
If I try to reference the library afterwards I get:
Error: Module name "underscore.string" has not been loaded yet for
context:
... even if I do so immediately after the define line (in the code above)! In other words, if I change the code to
define('underscore.string', [], function() {
return _s;
});
console.log(require('underscore.string'))
Require tells me that "underscore.string" hasn't been loaded yet!
Can anyone help me figure out how I can bring this library in to my codebase?
In your require configuration do:
var require = {
...
map: {
"*": {
"underscore.string": "path/to/file/disregarding/baseUrl"
}
}
};
NOTE: The path to file should include the baseUrl, so in your case and assuming baseUrl="scripts", it would be something like:
"scripts/ext/underscore.string.js"
NOTE 2: It needs the .js extension, i.e. it is exact file name.
This question already has answers here:
Detect if called through require or directly by command line
(8 answers)
Closed 5 years ago.
I'd like to check if my module is being included or run directly. How can I do this in node.js?
The docs describe another way to do this which may be the preferred method:
When a file is run directly from Node, require.main is set to its module.
To take advantage of this, check if this module is the main module and, if so, call your main code:
function myMain() {
// main code
}
if (require.main === module) {
myMain();
}
EDIT: If you use this code in a browser, you will get a "Reference error" since "require" is not defined. To prevent this, use:
if (typeof require !== 'undefined' && require.main === module) {
myMain();
}
if (!module.parent) {
// this is the main module
} else {
// we were require()d from somewhere else
}
EDIT: If you use this code in a browser, you will get a "Reference error" since "module" is not defined. To prevent this, use:
if (typeof module !== 'undefined' && !module.parent) {
// this is the main module
} else {
// we were require()d from somewhere else or from a browser
}