sql.js
sql.js copied to clipboard
Cannot set property 'exports' of undefined
I'm trying to get Sql.js working with TypeORM inside Electron as part of the renderer but I'm running into an error I don't know how to handle. I'm getting the error: TypeError: Cannot set property 'exports' of undefined
. I'm not sure if this is a configuration issue on my end or if there's some sort of bug. It seems like the error happens somewhere in initSqlJs
before it gets to locating the wasm binary.
My setup is as follows:
WebPack Config
module.exports = {
entry: {main: './main.ts'},
output: {/*Removed for brevity*/},
target: 'electron-renderer',
module: {/*Removed for brevity*/},
plugins: [
/*Other plugins removed for brevity*/
new Webpack.NormalModuleReplacementPlugin(/typeorm$/, function (result) {
result.request = result.request.replace(/typeorm/, "typeorm/browser");
}),
new Webpack.ProvidePlugin({
'window.SQL': 'sql.js/dist/sql-wasm.js'
}),
new CopyPlguin({
patterns: [
{from: './node_modules/sql.js/dist/sql-wasm.wasm'}
]
})
]
}
Main Code
const initSqlJs = require('sql.js');
const SQL = await initSqlJs({
locateFile: (file: any) => {
console.log(file); //This line is never printed
return `https://cdnjs.cloudflare.com/ajax/libs/sql.js/1.1.0/dist/${file}`}
});
var db = new SQL.Database();
likely either in webpack
or sqljs
, the statement module.exports = ...
is failing (because module is null).
if you change your code to the following, you can figure out where the problem is:
+console.log("webpack module.exports is ok");
const initSqlJs = require('sql.js');
+console.log("sqljs module.exports is ok");
const SQL = await initSqlJs({
locateFile: (file: any) => {
console.log(file); //This line is never printed
return `https://cdnjs.cloudflare.com/ajax/libs/sql.js/1.1.0/dist/${file}`}
});
var db = new SQL.Database();
Hey @kaizhu256, thanks for the suggestion. I tried putting the logging statements and they both work fine (which is confusing and annoying). I checked the stack trace of the error and I'm seeing the error when I call initSqlJs
, specifically this line:
const SQL = await initSqlJs({
searching thru the source code, the only place where module.exports
is assigned (besides tests) is here. but that happens during the require-call which succeeded, not initSqljs.
so i'm stumped as well.
After doing some more digging I'm even more confused. The error was coming from sql-asm-debug.js
at line 1213, looking at the source in the Electron devs tools, I see the following block:
if (true) {
module['exports'] = Module;
}
Which is weird, so I checked the original file in the dist
folder and the block at that line is:
if (typeof module !== 'undefined') {
module['exports'] = Module;
}
The latter block makes perfect sense, this is what I'd expect. The first block is really strange but it does explain why my code is failing. For whatever reason module
is undefined at that point and would cause the error I'm getting. My guess is this is some sort of optimization that WebPack is performing on code that it bundles. However, what I don't understand is why the optimized (or whatever it would be considered) code is changing the meaning of the if statement and why module
is undefined.
On a semi-related note, I originally was testing this code with source maps enabled, which would show the latter block of code but behind the scenes it must have actually been running the first block of code. So while debugging I was seeing the code enter the if statement despite the fact that the expression evaluated to false. I was starting to question everything I knew about software development 😵
The same issue.
Quick and dirty workaround which works for my project:
- Set SINGLE_FILE=1 in Makefile
- Comment
module = undefined;
in shell-pre.js
Than I recompilled sql.js and imported the single sql-wasm.js to the project.
I have the same problem when call initSqlJs().
enviroment:
electron: ^9.0.0
a react project created by CRA
But the code works well in chrome browser.
I have the same porblem too.
I just ran into this problem as well. Comment by @amura11 pretty much nailed the issue with Webpack trying to be smart by statically optimize if (typeof module !== 'undefined') { ... }
into if (true) { ... }
at compile time. This issue was then further obfuscated by the presence of sourcemaps.
In my Webpack config, I added the following lines to bundle sql.js
without extra preprocessing:
{
module: {
noParse: /node_modules\/sql\.js\/dist\/sql-wasm\.js$/,
},
}
module: { noParse: /sql.js/ }
Did you report this bug to webpack ?
the issue is still persisting
Uncaught (in promise) TypeError: Cannot set property 'exports' of undefined
at index.js:106
at new Promise (
I’m still experiencing this issue. Any update / workaround ?
Oh man, I finally got this working. Turned out to be a few things that made it work. First, I had to do what @kekeqy suggested:
module: {
noParse: /sql.js/
}
Then I also had to add the wasm directly to my output directory:
plugins: [
new CopyPlugin({
patterns: [
{from: './node_modules/sql.js/dist/sql-wasm.wasm'}
],
}),
],
这是一封自动回复邮件。已经收到您的来信,我会尽快回复。
I just ran into this problem as well. Comment by @amura11 pretty much nailed the issue with Webpack trying to be smart by statically optimize
if (typeof module !== 'undefined') { ... }
intoif (true) { ... }
at compile time. This issue was then further obfuscated by the presence of sourcemaps.In my Webpack config, I added the following lines to bundle
sql.js
without extra preprocessing:{ module: { noParse: /node_modules\/sql\.js\/dist\/sql-wasm\.js$/, }, }
I owe you a beer
这是一封自动回复邮件。已经收到您的来信,我会尽快回复。