Hi.
I've been on this for a while now, and cannot figure out why my dynamic module loader does not load files correctly. It simply just returns an empty object for every file.
function loadCommands() {
require('fs').readdirSync(require('path').join(__dirname, 'commands')).forEach(file => {
let commandName = file.substring(0, file.length - 3); // this removes the .js extension off of the file.
commands[commandName] = require('./commands/' + file);
});
}
This code should load each file in the ./commands directory and put it in an object called commands.
The require() function returns an empty object.
A sample command file contains the following:
const Command = require('../Command');
class Ban extends Command {
constructor(options) {
this.description = 'Bans a user.';
}
execute() {
}
}
module.exports = Ban;
Command contains the following:
class Command {
constructor() {
this.description = 'unknown';
}
execute() {
}
}
module.exports = Command;
If I do commands["ban"], it returns an empty object instead of the class I was expecting.
I am really confused onto what is going on here, as there's no circular dependencies at all.
If anyone can help me, it would be appreciated.
Thanks.
Related
I am reading IFC files and ifc.js seemed like a solid option although I am not so experienced with javascript but I thought it could be a good opportunity to learn about it.
I followed the documentation example that can be food here ``https://ifcjs.github.io/info/docs/Hello%20world```.
I packed the app inside of a django project and everything is fine until I try to load up a file.
I am getting the following error:
RuntimeError: abort(LinkError: import object field 'a' is not a Memory). Build with -s ASSERTIONS=1 for more info.
On my browser debugger, the error links to the following class of my bundle.js file
class IFCLoader extends Loader {
constructor(manager) {
super(manager);
this.ifcManager = new IFCManager();
}
load(url, onLoad, onProgress, onError) {
const scope = this;
const loader = new FileLoader(scope.manager);
this.onProgress = onProgress;
loader.setPath(scope.path);
loader.setResponseType('arraybuffer');
loader.setRequestHeader(scope.requestHeader);
loader.setWithCredentials(scope.withCredentials);
loader.load(url, async function (buffer) {
try {
if (typeof buffer == 'string') {
throw new Error('IFC files must be given as a buffer!');
}
onLoad(await scope.parse(buffer));
} catch (e) {
if (onError) {
onError(e);
} else {
console.error(e);
}
I have no clue how to correct this issue and any help would be highly appreciated. I am happy to post additional files or code if needed. Thanks
I have made an extension that opens a file dialog. What I would like to do is after the file is selected, I want a python file to run. What I need is the VS Code command to run a file (or perhaps a python file specifically?).
here is a working example where the command I use is a command that comments the selected line in the currently active editor. It works perfectly so I know this structure is generally correct. I just need the right command to replace the comment line command.
below is the code in questions with the working command I mentioned above. I found it using this resource: where I found the comment line command
// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
const { ChildProcess } = require('child_process');
const vscode = require('vscode');
const { execFile } = require('node:child_process');
const { stdout, stderr } = require('process');
// this method is called when your extension is activated
// your extension is activated the very first time the command is executed
/**
* #param {vscode.ExtensionContext} context
*/
function activate(context) {
let disposable = vscode.commands.registerCommand('fileDialog.openFile', function () {
const options = {
canSelectMany: false,
openLabel: 'Open'
};
vscode.window.showOpenDialog(options).then(fileUri => {
if (fileUri && fileUri[0]) {
console.log('Selected file: ' + fileUri[0].fsPath);
vscode.commands.executeCommand('python.execInInterminal');
}
});
});
context.subscriptions.push(disposable);
}
// this method is called when your extension is deactivated
function deactivate() {}
module.exports = {
activate,
deactivate
}
You can go for child_process' exec or spawn if you only need to run the Python script(s).
If you really prefer to rely on the Python extension, then you'll need to at least feed the script's Uri into the executeCommand's argument - its the 2nd part of what you found.
function activate(context) {
let disposable = vscode.commands.registerCommand('fileDialog.openFile', function () {
const options = {
canSelectMany: false,
openLabel: 'Open',
filters: {
'Python script': ['py']
}
};
vscode.window.showOpenDialog(options).then((fileUris) => {
// This will always get an array of Uris regardless of canSelectMany being false
fileUris?.forEach(async (fileUri) => {
console.log(`Selected file: ${fileUri.fsPath}`);
await vscode.commands.executeCommand('python.execInInterminal', fileUri);
});
});
});
context.subscriptions.push(disposable);
}
If you want to handle more things, you can refer to the thenable unittest code they included in the repo:
https://github.com/microsoft/vscode-python/blob/main/src/test/smoke/runInTerminal.smoke.test.ts#L46-L48
Is there any clean way to check if a path is a file or directory?
Currently I am using this:
exports.isDirectory = (dirPath) => {
return fs.lstatSync(dirPath).isDirectory()
}
But my problem here is that if dirPath does not exist yet, then lstatSync gives out an error.
Then I also tried:
exports.getFileName = (filePath) => {
return filePath.split(/[\\\/]/).pop()
}
exports.isDirectory = (dirPath) => {
return exports.getFileName(dirPath) === ''
}
And call:
const home = require('os').homedir()
const sampleLoc = path.join(home, '/.folder/another'))
isDirectory(sampleLoc)
But it only basically thinks another is the filename and returns false on isDirectory.
Can't really check for the presence of . (like an extension of a file name) since my folders can have dots anywhere on its name.
How can I check if the given path is for a file or directory? (considering it does not exist yet at the point of checking)?
Help!
I am successfully parsing and evaluating a javascript file with Duktape in my Android application using Kotlin.
val file_name = "lib.js"
val js_string = application.assets.open(file_name).bufferedReader().use {
it.readText()
}
val duktape = Duktape.create()
try {
Log.d("Greeting", duktape.evaluate("'hello world'.toUpperCase();").toString())
duktape.evaluate(js_string)
} finally {
duktape.close()
}
The javascript file was created with Browserify, so it is one single file with everything and it is working fine. But I need to request a module and a method from the module, example:
var test = require('testjs-lib');
test.EVPair.makeRandom().toWTF();
I have no idea of how to do it and have not found any example, besides this link: http://wiki.duktape.org/HowtoModules.html
It tells me to use a modsearch, but I don't have a clue how to do it or where it should be placed, not even if it is applicable for the Duktape Android (https://github.com/square/duktape-android).
Has anybody done it successfully that could shed some light on this matter?
in the testjs-lib.js, add the JS code that makes use of the module testjs-lib.js itself exports. For example:
function myModule() {
this.hello = function() {
return 'hello!';
}
this.goodbye = function() {
return 'goodbye!';
}
}
module.exports = myModule;
//You code goes here
console.log(myModule.hello());
console.log(myModule.goodbye());
Then ask Duktape to evaluate the entire file.
Say you want to include Underscore in duktape.
Put your module/library code in a separate js file. In an android project, you can put this js file in Assets folder. In our example, it'd be sth like: underscore.js
Create a java interface that'd be used by duktape to get inputstream to this js file.
Sth like:
```
public interface DuktapeHelper {
#JavascriptInterface
String getUnderScore();
}
````
Bind this java interface to a js interface in your duktape instance.
```
duktape.bind("helper", DuktapeHelper.class, <instance of your DuktapeHelperImplementation>);
```
Implment modSearch function in duktape using helper interface that you injected before.
```
duktape.evaluate("Duktape.modSearch = function (id) {\n" +
" if (id == \"underscore\") {" +
" return helper.getUnderScore();" +
" } " +
" throw new Error('cannot find module: ' + id);" +
" };" +
"var _ = require('underscore')._; ");
```
I have several typescript files, some of them export a const named APIS.
I'm trying to access those exports (I want to concatenated all of them to a single file), but it doesn't seem to work. I'm obviously doing something wrong, but I'm not sure what.
For example, I have a folder named services, with 2 files: service1.ts, service2.ts.
service1.ts:
...
export const APIS = [ { "field1" : "blabla" } ];
service2.ts: does not contain the APIS var.
This is my gulpfile.js:
var gulp = require('gulp');
var concat = require('gulp-concat');
var map = require('gulp-map');
gulp.task('default', function() {
return gulp.src('.../services/*.ts')
.pipe(map(function(file) {
return file.APIS;
}))
.pipe(concat('all.js'))
.pipe(gulp.dest('./test/'));
});
When I run this task, I get nothing. When I added console.log(file.APIS); to the map function, I get undefined for all the values (although it is defined in service1.ts!).
This is following to: Extracting typescript exports to json file using gulp
EDIT: OK, so I tried saving the exports in a .js file instead of a .ts file, and now I can access those vars using require:
gulp.task('default', function() {
return gulp.src('./**/*.service.export.js')
.pipe(map(function(file) {
var fileObj = require(file.path);
...
}))
Now if I try console.log(fileObj.APIS); I get the correct values. What I'm still confused about is how I can pass these value on, and create a single file out of all these vars. Is it possible to push them into an array?
This will not work as you think it would work. Gulp itself knows nothing about typescript files, that file is a vinyl-file and has no knowledge about the typescript code within its content.
Edit
Based on your example, you can do something like this:
var gulp = require('gulp');
var concat = require('gulp-concat');
var map = require('gulp-map');
var fs = require('fs');
gulp.task('test', function ()
{
var allConstants = [];
var stream = gulp.src('./**/*.service.export.js')
.pipe(map(function(file)
{
var obj = require(file.path);
if (obj.APIS != null)
allConstants = allConstants.concat(obj.APIS);
return file;
}));
stream.on("end", function (cb)
{
// Do your own formatting here
var content = allConstants.map(function (constants)
{
return Object.keys(constants).reduce(function (aggregatedString, key)
{
return aggregatedString + key + " : " + constants[key];
}, "");
}).join(", ");
fs.writeFile('filename.txt', content, cb);
});
return stream;
});
Suggestion
If you want to collect multiple variables into a single file i.e. a common variables file I suggest gulp-replace.
Steps
Create a file, require it and use tags within that file to place your variables.
Advice
If you are already using services don't create an array. Instead create an object (JSON) where every property is a constant. i.e.
var constants = {
const_1: 0,
const_2: 1,
const_3: 2,
}