Use node module instead of extra file - javascript

With the IFCjs vue example (https://github.com/IFCjs/examples/tree/main/simple-vue), the IfcManager.js references the IFCWorker.js file path to use here:
async setupIfcLoader() {
let self = this;
await self.ifcLoader.ifcManager.useWebWorkers(true, '../IFCjs/IFCWorker.js')
await self.ifcLoader.ifcManager.applyWebIfcConfig({
COORDINATE_TO_ORIGIN: true,
USE_FAST_BOOLS: false
});
self.setupThreeMeshBVH();
}
But this means that the IFCWorker.js file has to be in the project directory, while it is also in the web-ifc node module.
I was wondering if I can reference the IFCWorker.js that is in the node module, so it can be removed from the project directory.

Related

I keep seeing await require is OK, but I cannot make it work

Ok, so there are answers here such as this one that state that I should be able to export a promise and then await on said promise whenever I require the module. Well, I cannot make it work. I always get the error message SyntaxError: await is only valid in async functions and the top level bodies of modules. But guess what: As far as I can tell I am putting in at the top level of a module!
Here's some code:
const wjConfig = require('wj-config');
const fs = require('fs');
const loadJsonFile = (fileName, isRequired) => {
const fileExists = fs.existsSync(fileName);
if (fileExists) {
const data = fs.readFileSync(fileName);
return JSON.parse(data);
}
else if (isRequired) {
throw new Error(`Configuration file ${fileName} is required but was not found.`);
}
// Return an empty object.
return {};
};
const env = new wjConfig.Environment(process.env.NODE_ENV);
const config = wjConfig()
.addObject(loadJsonFile('./config/config.json', true))
.name('Main Configuration')
.addObject(loadJsonFile(`./config/config.${env.value}.json`))
.name('Env Configuration')
.addEnvironment(process.env)
.includeEnvironment(env)
.createUrlFunctions()
.includeValueTrace()
.build();
// Is this not part of the top level of this module??
module.exports = await config;
I have also done const config = await wjConfig() with the same result.
I have also tried removing await from this config.js module and putting it in the main entry point file index.js. Same error. Bottomline: No matter where I put the await, I cannot make this work. Any pointers?
I am using NodeJS v18.1.0. Many thanks.
At the top level, you can only use await in ESM modules (that use import not require()), not in CommonJS modules which is what your code is.
So, as long as your code is in a CommonJS module, you can't use await at the top level.
As for the error message:
SyntaxError: await is only valid in async functions and the top level bodies of modules
That is indeed not entirely clear. Apparently when they say "modules", they mean type: "module" as one would specify it in package.json which is an ESM module, not a CommonJS module.
It could also be that this error message is from the V8 JS engine where the error messages are targeted more at the browser environment where the only type of Javascript "module" in the browser is an ESM module as there is no other type of "module" in a browser.

Cannot find module Error While js files are located in same Directory

I have added a js Module called mongoUtil, which contains the code hereafter, following a suggestion found at this link.
const MongoClient = require( 'mongodb' ).MongoClient;
const url = "mongodb://localhost:27017";
var _db;
module.exports = {
connectToServer: function(callback) {
MongoClient.connect(url, {useNewUrlParser: true}, function(err, client) {
_db = client.db('MyDB');
return callback(err);
});
},
getDb: function() {
return _db;
}
};
I have furthermore used the following line in my app.js Module:
const mongoUtil = require('mongoUtil')
However, I am obtaining the following error while the 2 Modules are located in the same Directory:
Error: Cannot find module 'mongoUtil'
What am I missing?
If you provide a module name to require it will search node_modules for it.
If you want to read a module from the current directory, you need to use the file path. This can be relative: require("./mongoUtil")
The exact documentation is here including a (rather long) pseudocode explanation of how the algorithm of locating a module works.
But in short, there are two basic ways of loading a module:
Using the name of an installed module (may be globally or locally installed), for example require('mongodb'). This would look for the (global or local) node_modules/mongodb folder.
Using a path (absolute or relative), for example require('./mongoUtil'). This would look for a file at the given path - if it's relative, then it is relative to the current file.
So, the solution is to use require('./mongoUtil') and not require('mongoUtil').
This will work:
const mongoUtil = require('./mongoUtil.js');
Or even just the following, since the extension is automatically resolved:
const mongoUtil = require('./mongoUtil');

Error: Module name "#google-cloud/vision" has not been loaded yet for context: _. Use require([])

I am getting this error Module name "#google-cloud/vision" has not been loaded yet for context: _. Use require([]) ,when I run my project I have included require.js in my project and also the script tag in my html file <script data-main = "./app.js" src = "./libs/require.js"></script> , I went through many articles on require.js but couldn't understand what is the actual use of it and how I can resolve this error .
I also went through this thread on StackOverFlow but couldn't understand
Dynamic require in RequireJS, getting "Module name has not been loaded yet for context" error?
Here's my code
///////////////////////////////////////////////////////////////
//UPLOAD IMAGE to cloud bucket
function showResults(){
const bucketName = //name-of-bucket;
const filename = './img2.jpg';
// Imports the Google Cloud client library
const {Storage} = require('#google-cloud/storage');
// Creates a client
const storage = new Storage();
async function uploadFile() {
// Uploads a local file to the bucket
await storage.bucket(bucketName).upload(filename, {
// Support for HTTP requests made with `Accept-Encoding: gzip`
gzip: true,
// By setting the option `destination`, you can change the name of the
// object you are uploading to a bucket.
metadata: {
// Enable long-lived HTTP caching headers
// Use only if the contents of the file will never change
// (If the contents will change, use cacheControl: 'no-cache')
cacheControl: 'public, max-age=31536000',
},
});
console.log(`${filename} uploaded to ${bucketName}.`);
}
uploadFile().catch(console.error);
}
///////////////////////////////////////////////////////////////////
Your code is not compatible with RequireJS which uses AMD - Asynchronous Module Definition.
AMD format looks like this:
define(['#google-cloud/storage'], (storage) {
// body of your module here
});
The question is whether '#google-cloud/storage' is AMD compatible.
The simplest solution here would be to use more modern tooling like webpack or just use native ES6 modules if you support Chrome browser only

Manual mocking using __mocks__ not working

I'm trying to add some tests to the node application I'm developing. I went through jest documentation for manual mocking and tried creating mocks folder as instructed. Please find the folder structure below.
app
- firebase
- fb.js
- __mocks__
- fb.js
- firebase-admin.js
- resolvers
- mutation.js
__tests__
- user.spec.js
As you can see, I have tried to mock two modules, fb.js (user module) and firebase-admin.js (node_modules module). firebase-admin.js mocking works without any problem. But user module mock is not even getting picked up by jest. The actual fb.js module is getting invoked all the time.
I have tried creating mocks directory for various user modules in my project but none of it is getting picked up. Is there any extra configuration I'm missing ??. currently I'm working around this problem by mocking firebase-admin node module only. But I want to mock the user module instead of firebase-admin module so that my firebase configurations are also mocked. Please let me know if any more information is needed.
__mocks__/fb.js
module.exports = {
auth: jest.fn(() => "testing")
};
__mocks__/fb-admin.js
module.exports = {};
__tests__/user.spec.js
const request = require('supertest');
const server = require('../app').createHttpServer({});
const app = request(server);
describe('login resolvers', () => {
test('should sign up user', async () => {
const response = await app.post('/')
.send({
query: `mutation {
signUp(idToken: "esd45sdfd...") {
user {
id
locked
revoked
}
}
}
`,
})
.set('Accept', 'application/json')
.expect(200);
console.log(response.text);
});
});
app/resolvers/mutation.js
const admin = require('../firebase/fb');
/* other app code here */
From the docs on Manual Mocks:
When we require that module in our tests, then explicitly calling jest.mock('./moduleName') is required.
If the module you are mocking is a Node module (e.g.: lodash), the mock should be placed in the __mocks__ directory adjacent to node_modules (unless you configured roots to point to a folder other than the project root) and will be automatically mocked. There's no need to explicitly call jest.mock('module_name').
I had to read the documentation very carefully. Especially the part about "unless you configured roots to point to a folder other than the project root". Double-check that you set up the __mocks__ folder in the source folder you specified for Jest.

NodeJS module executing user script with external function not found

I am quite new to nodeJS.
I am using the nodeJS module node-workflow
Basically, this module is an orchestrator that takes a custom javascript script (=workflow definition), then serialize it and store it in a REDIS db (for example), and execute on-demand later on by the node-workflow module.
A workflow definition is composed of task, like this:
var my_external_module = require('my_external_module');
var workflow = module.exports = {
name: 'Workflow Test',
chain: [{
name: 'TASK 1',
timeout: 30,
retry: 1,
body: function(job, cb) {
// Execute external function
my_external_module.hello("Monkey");
return cb(null)
},
},
...
First I put my function my_external_module.hello() in a .js file beside the workflow script.
When I run the node-workflow module I get the following error:
Error initializing runner:
[ReferenceError: my_external_module is not defined]
So I have created a module my_external_module,
and in: ./node_modules/my_external_module/index.js
module.exports = {
hello: function(name) {
console.log("Hello, " + name);
}
};
When I run the node-workflow module I get the same error:
Error initializing runner:
[ReferenceError: my_external_module is not defined]
It seems that the require(...) shall stands in one of the .js files of the node-workflow module, so I would have to hack one of the files of the module, but it is a bit dirty.
Is there something I missed?
Or is there a way to define a $PATH like in Python in order to my function to be accessible from everywhere.
You have to require it as:
var my_external_module = require('./my_external_module');
Notice the ./ this means Node should search for a file like ./my_external_module.js
If you omit the ./ Node looks at the installed modules on (usually) node_modules directory

Categories

Resources