Load WebAssembly module only once / Singleton - javascript

I want to use WebAssembly modules in my React app. The modules are loaded when the app starts. Now I want to reuse this wasm module in another Javascript module.
How can I reuse these wasm modules in other JS modules? Do I really have to load the modules again?
Loading wasm in the main module:
Promise.all([
import("webassembly-tests-rust")
//...
])
.then(modules => {
// how to store the module to make it available in other modules?
wasm["rust"] = modules[0];
//...
})
Other module:
wasm.rust.somefunction();

Would it work like this?
wasm.js
let wasm
export const getWasm = () =>
wasm
? Promise.resolve(wasm)
: import('webassembly-tests-rust').then(_wasm => {
wasm = _wasm;
return wasm;
})
module.js
import getWasm from 'wasm.js'
Promise.all([
getWasm
//...
])
.then(modules => {
modules[0].someFunction = () => console.log('foo')
//...
})
Other module:
import getWasm from 'wasm.js'
getWasm().then(wasm => wasm.somefunction()) // console.log('foo')

Related

How to use a variable from module export

In the server file, I export the variable. How can I use it in another js file? Now in the browser in the console I have an error - require is not defined
// server.js
const firestore = admin.firestore();
module.exports = { firestore };
// script.js
const firestore = require("../../server");
const getAllUsers = () => {
db.listCollections()
.then((snapshot) => {
snapshot.forEach((snaps) => {
console.log(snaps); // LIST OF ALL COLLECTIONS
});
})
.catch((error) => console.error(error));
};
getAllUsers();
Browsers do not support CommonJS modules.
You can either:
Convert the module to an ECMAScript module using import and export and then load the module that is the entry point to your program with <script type="module" src="..."></script>.
Bundle the modules together with a tool like Webpack or Parcel.

How to setup clipboardy in cypress 10?

I'm pretty new to cypress. I tried to install clipboardy to one of my project.
But the guide that I found online like this mostly setup on the older cypress which is using the plugins/index.js file.
I tried something like this and got error
const { defineConfig } = require("cypress");
const createBundler = require("#bahmutov/cypress-esbuild-preprocessor");
const addCucumberPreprocessorPlugin =
require("#badeball/cypress-cucumber-preprocessor").addCucumberPreprocessorPlugin;
const createEsbuildPlugin =
require("#badeball/cypress-cucumber-preprocessor/esbuild").createEsbuildPlugin;
const clipboardy = require("clipboardy");
module.exports = defineConfig({
e2e: {
async setupNodeEvents(on, config) {
const bundler = createBundler({
plugins: [createEsbuildPlugin(config)],
});
on("file:preprocessor", bundler);
await addCucumberPreprocessorPlugin(on, config);
on('task', {
getClipboard () {
return clipboardy.readSync();
}
});
return config;
},
specPattern: "cypress/e2e/features/*.feature",
baseUrl: "XXXXXXXXXXXXX",
chromeWebSecurity: false,
},
});
The error
Error screen
Stack Trace
Error [ERR_REQUIRE_ESM]: require() of ES Module C:\Users\XXXXXXXXXXXXXXXXXXXXXXX\node_modules\clipboardy\index.js from C:\Users\XXXXXXXXXXXXXXXXXXXXXXX\cypress.config.js not supported.
Instead change the require of index.js in C:\Users\XXXXXXXXXXXXXXXXXXXXXXX\cypress.config.js to a dynamic import() which is available in all CommonJS modules.
at Object. (C:\Users\XXXXXXXXXXXXXXXXXXXXXXX\cypress.config.js:8:20)
at async Promise.all (index 0)
at async loadFile (C:\Users\XXXX\AppData\Local\Cypress\Cache\10.4.0\Cypress\resources\app\node_modules\#packages\server\lib\plugins\child\run_require_async_child.js:106:14)
at async EventEmitter. (C:\Users\XXXX\AppData\Local\Cypress\Cache\10.4.0\Cypress\resources\app\node_modules\#packages\server\lib\plugins\child\run_require_async_child.js:116:32)
It's because the clipboardy package has type: "module" in it's 'package.json'.
This tells anything that uses the package that you should use import not require to load the package.
Use dynamic imports, as hinted in the error message
Instead change the require of index.js in ... to a dynamic import()
const clipboard = import('clipboardy')

Building an Nx lib with Rollup does not bundle required dependencies

Question
I'm using the default Rollup executor to build an Nx library that I will later run in a browser-like environment. The resulting bundle cannot contain imports or requires. Running nx run ssr-bundle:build should create a single bundle containing both my application code and dependencies.
How can I bundle all of my code so my imported code is in the same file?
Example
The source file index.ts
import { isBoolean } from 'lodash';
async function handler() {
return new Promise((resolve) => {
setTimeout(() => {
resolve(isBoolean);
}, 1000);
});
}
export default handler;
The output file index.cjs.js
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var lodash = require('lodash'); <--------- this should be the lodash source code
async function handler() {
return new Promise((resolve) => {
setTimeout(() => {
resolve(lodash.isBoolean);
}, 1000);
});
}
exports["default"] = handler;

electron "MAIN" : requiring you own js file and call function from it

I'm can't understand some things here related to electron. I've been searching for hours for the magic answer but couldn't find anything.
My goal is simple. I don't want my main electron.js file to be 5000 lines long without any kind of organization so I'm trying to split the code into multiple js file that make sense.
My idea was to use import { someFunction1, someFunction2 } from './scripts/someScript' in my electron.js and then just creating that file with the arrow function in it and export them.
Then I could call the function as I want in the main file. However, it doesn't seem to be possible. I've read electronjs doesn't support ES6 syntax. I've read about Babel (But from what I read, it implies a bunch of additional configuration and I don't want to spend days trying to add this to the bunch of configuration that are already messy with electron + React (No boiler plate here). And I didn't find anything specifics for this combo.
Question is. Is this doable in 2021? Am I missing anything? What would you guys recommend?
File would look something like this:
import { someNodeModuleFunction } from 'someNodeModule';
const someFunction1 = () => {
return 1;
};
const someFunction2 = () => {
return 2;
};
export { someFunction1, someFunction2 }
EDIT
Here's the actual code I have a problem with. I still get
if the file is .js: "Must use import to load ES Module"
If the file is .mjs: "Cannot use import statement outside a module"
This script is simply using fs to create a directory:
DataManagement.mjs:
import { existsSync, mkdir } from 'fs';
const electron = require('electron');
const app = electron.app;
const documentFolder = app.getPath('documents');
const CreateDataDirectory = () => {
const mainPath = documentFolder + 'AppName'
if (!existsSync(mainPath)) {
mkdir(mainPath);
}
};
module.exports = { CreateDataDirectory }
Calling it like that in electron.js:
const { CreateDataDirectory } = require('./scripts/DataManagement.mjs');
[...]
CreateDataDirectory()
Not sure how dividing the code can be that hard. :)
You may need to use Node.js module syntax (require and module.exports) or Babel (code transpiler).
For example:
import { someNodeModuleFunction } from 'someNodeModule';
const someFunction1 = () => {
return 1;
};
const someFunction2 = () => {
return 2;
};
module.exports = { someFunction1, someFunction2 }
Using your module:
const { someFunction1, someFunction2 } = require ('./FILE.js');
// ...
You could use module.exports:
otherModule.js
const someFunction1 = () => {
return 1;
};
const someFunction2 = () => {
return 2;
};
module.exports = {
someFunction1,
someFunction2
};
main.js
const { someFunction1, someFunction2 } = require('otherModule.js');

Require not behaving as expected

I'm using the proxyquire library, which mocks packages on import.
I'm creating my own proxyquire function, which stubs a variety of packages I use regularly and want to stub regularly (meteor packages, which have a special import syntax):
// myProxyquire.js
import proxyquire from 'proxyquire';
const importsToStub = {
'meteor/meteor': { Meteor: { defer: () => {} } },
};
const myProxyquire = filePath => proxyquire(filePath, importsToStub);
export default myProxyquire;
Now I want to write a test of a file which uses one of these packages:
// src/foo.js
import { Meteor } from 'meteor/meteor'; // This import should be stubbed
export const foo = () => {
Meteor.defer(() => console.log('hi')); // This call should be stubbed
return 'bar';
};
And finally I test it like this:
// src/foo.test.js
import myProxyquire from '../myProxyquire';
// This should be looking in the `src` folder
const { foo } = myProxyquire('./foo'); // error: ENOENT: no such file
describe('foo', () => {
it("should return 'bar'", () => {
expect(foo()).to.equal('bar');
});
});
Note that my last 2 files are nested inside a subfolder src. So when I try to run this test, I get an error saying that the module ./foo couldn't be found, as it is being looked for in the "root" directory, where the myProxyquire.js file is, not the src directory as expected.
You might be able to work around that (expected) behaviour by using a module like caller-path to determine from which file myProxyquire was called, and resolving the passed path relative to that file:
'use strict'; // this line is important and should not be removed
const callerPath = require('caller-path');
const { dirname, resolve } = require('path');
module.exports.default = path => require(resolve(dirname(callerPath()), path));
However, I have no idea of this works with import (and, presumably, transpilers).

Categories

Resources