My electron app uses a worker to compile WASM in the background (through worker-loader). However, I get the following error when running it:
How would I solve this error? It looks like the module is trying to use path, so I've added the path fallback in Webpack config:
However, this didn't fix my issue
worker.js
import { Essentia, EssentiaWASM } from 'essentia.js';
let essentia = new Essentia(EssentiaWASM);
self.addEventListener('message', (event) => {
console.log(essentia.version);
})
Related
I have a Next 10 project where I am trying to use WebWorkers. The worker is being initialized like so:
window.RefreshTokenWorker = new Worker(new URL('../refreshToken.worker.js', import.meta.url))
I also have the Worker defined as
self.addEventListener('message', (e) => {
console.info("ON MESSAGE: ", e)
// some logic with e.data
})
Its also being called like this:
const worker = getWorker() // gets worker that is attached at the window level
worker.postMessage('start')
My next.config.js file is defined as
const nextConfig = {
target: 'serverless',
env: getBuildEnvVariables(),
redirects,
rewrites,
images: {
domains: []
},
future: { webpack5: true },
webpack (config) {
config.resolve.alias['#'] = path.join(__dirname, 'src')
return config
}
}
// more definitions
module.exports = nextConfig
The issue I have is the console.info in the Web Worker definition does not receive the message being sent from postMessage on the build version (yarn build && yarn start) but it does on the dev version (yarn dev). Any ways to fix this?
This is not a solution. But can be a messy way to do the job. This turned out to be a nightmare for me.
I have the same setup as yours. I was initializing web worker as you have shown in your question. I got this idea from the nextjs doc itself: https://nextjs.org/docs/messages/webpack5
const newWebWorker = new Worker(new URL('../worker.js', import.meta.url))
Everything working correctly when I work in dev mode. it is picking up the worker.js file correctly and everything looks alright.
But when I build the nextjs and try it, then web worker won't work. When I dive deeply into the issues, I found out that the worker.js chunk file is created directly under the .next folder. It should come under .next/static/chunk/[hash].worker.js ideally.
I could not resolve this issue in a proper way.
So what i did, i placed my worker.js file directly under public directory. I put my worker.js file transpiled and optimized and put the code in the public/worker.js file.
After this, I modified the worker initialization like this:
const newWebWorker = new Worker('/worker.js', { type: 'module' });
it is working in the production build now. I will report once I get a cleaner solution for this.
I am working on this little project for Augmented Reality, ARnft it is based on a lighter version of Jsartoolkit5, JsartoolkitNFT for only NFT markers. The code follows the ES6 standard (partially) and use webpack as bundler. All is fine in development mode but when i go in production mode, the example stuck with this error:
05ff8846-4121-4380-86c3-9612f404732a:1 Uncaught SyntaxError: Function statements require a function name
It stop at the embedded Worker. The app don't enter inside because i otherwise i will receive some messages in the dev console.
I Inject the Worker in a Blob object:
// create a Worker to handle loading of NFT marker and tracking of it
const workerBlob = new Blob(
[workerRunner.toString().replace(/^function .+\{?|\}$/g, '')],
{ type: 'text/js-worker' }
)
const workerBlobUrl = URL.createObjectURL(workerBlob)
worker = new Worker(workerBlobUrl)
https://github.com/kalwalt/ARnft/blob/8322585aa0f863917c6d1cee541356ff3b7c36a0/src/utils/Utils.js#L207-L213
workerRunner defined at this line:
https://github.com/kalwalt/ARnft/blob/8322585aa0f863917c6d1cee541356ff3b7c36a0/src/utils/Utils.js#L272
I think that is a minification issue i tried to add --optimize-minimize in the script:
"build-es6": "webpack --mode production --optimize-minimize",
, but not helped. How can i solve this?
Thank you
This issue can be solved with the worker-loader plugin.
Instead of inlining the worker in a Blob as explained in the question:
create an external Worker.js and import in the file (in this case Utils.js):
import Worker from './Worker.js'
use the worker as usual:
let worker
// other code
worker = new Worker()
// other code with postMessage and onmesssage...
in wepback.config.js
{
test: /\worker\.js$/,
use: {
loader: 'worker-loader',
options: { inline: true, fallback: false }
}
}
You can also see this commit and the issue on webpack.
A user tries to use my package for nuxt.js, but gets the error: document is not defined.
I found the first issue. When I build the bundle with "build-bundle": "vue-cli-service build --target lib --name index ./src/index.js",
vue-style-loader is being used. This, however, results in the error for using nuxt projects. This part is failing:
function addStyle (obj /* StyleObjectPart */) {
var update, remove
var styleElement = document.querySelector('style[' + ssrIdKey + '~="' + obj.id + '"]')
Document is not defined since we are using server rendering. But the question is how can I build up my package so that I can use it with nuxt?
I need:
index.common.js
index.umd.js
index.umd.min.js
This is due to the server-side rendering. If you need to specify that you want to import a resource only on the client-side, you need to use the process.client variable.
For example, in your .vue file:
if (process.client) {
require('external_library')
// do something
}
The above is the fundamental solution to document is not defined.
I checked some information and found that, this problem is not caused by your package. In fact, the problem lies on the cache-loader package in the user’s nuxt project.
For some reason cache-loader incorrectly determined the current environment as browser and not node so that vue-style-loader is confused and used client implementation instead.
So try to let users add the following configuration to the nuxt.config.js file to disable stylesheet caches on server-side:
build: {
...
cache: true,
extend(config, { isServer, isDev, isClient }) {
...
if (isServer) {
for (const rules of config.module.rules.filter(({ test }) =>
/\.((c|le|sa|sc)ss|styl.*)/.test(test.toString())
)) {
for (const rule of rules.oneOf || []) {
rule.use = rule.use.filter(
({ loader }) => loader !== 'cache-loader'
)
}
}
}
...
}
...
}
I found a solution but it is not using the vue-cli service. Instead, the files are compiled by rollup. I found using the cli service much easier. The only problem with the cli service is it will adjust the "flow" of your repo. However, you can modify the rollup.config.js to amend the folder structure.
The problem with rollup is that it isn't webpack. Therefore, all components using a webpack configuration need to be adjusted or rollup.config.js needs to be amended to include the additional functionality
I am fairly new to using PubSubJS (along with jQuery, Webpack, React) in a project, and my local server throws the following error
Uncaught TypeError: _pubsubJs2.default.subscribe is not a function
at Object.componentDidMount (SideNavContainer.js?eb9e:44)
...
this line
import PubSub from 'pubsub-js';
...
PubSub.subscribe(OPEN_LAYERS, (_, isOpen) => {
this.setState({ active: isOpen });
this.props.isOpen(isOpen);
});
I've successfully run PubSubJS in a blank test project, and so maybe there's an issue with how Webpack is building? My webpack.config.js file compiles using babel. I'll include more source code if need be!
I try to get the ipcRenderer module from electron in typescript to send informations from the current component to the core and to get informations back to the window (electron-chromium-browser).
All I get is a error "Module not found" by transcoding the ts-code to ES5.
const ipc = require('electron').ipcRenderer;`
Update: The Error is switching between the "Module not found" and this one:
ERROR in ./~/electron/index.js
Module build failed: Error: ENOENT, open '/.../node_modules/electron/index.js'
# ./app/components/search/search.ts 12:10-29
That is from the current electron-api. I have also tried to use the import syntax from typescript but the result is the same.
Than I tried to use the electron.ipcRenderer module in a ES5-file, loaded/linked directly in the html-file.
There it worked. Why?
Solved the problem after 10h searching.
Problem was the webpack-transcoder.
https://github.com/chentsulin/webpack-target-electron-renderer
https://github.com/chentsulin/electron-react-boilerplate/blob/master/webpack.config.development.js
Since electron dependency in the browser app is not real, meaning it's not webpacked from node_modules but instead loaded in runtime, the require statement caused errors such as "fs" not found for me.
However you can trick the typescript with this:
if (typeof window['require'] !== "undefined") {
let electron = window['require']("electron");
let ipcRenderer = electron.ipcRenderer;
console.log("ipc renderer", ipcRenderer);
}
Also if you are writing a web app, which only is augmented by electron when it's running inside, this is a better way since you don't have to add electron as a dependency to your webapp just when using the communication parts.
Than I tried to use the electron.ipcRenderer module in a ES5-file, loaded/linked directly in the html-file.
If it works in html but fails in ts it means the error is not in const ipc = require('electron').ipcRenderer;. The error is most likey in the import you have to load your file from html (and not require('electron')).
This solved the problem for me:
You can fix it, just add to the "package.json"
"browser": {
"fs": false,
"path": false,
"os": false }
Source: https://github.com/angular/angular-cli/issues/8272#issuecomment-392777980
You can trick ts with this (dirty hack, but it works):
const { ipcRenderer } = (window as any).require("electron");