The Wayback Machine - https://web.archive.org/web/20210124105423/https://github.com/sql-js/sql.js/issues/406
Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot set property 'exports' of undefined #406

Open
amura11 opened this issue Jun 24, 2020 · 11 comments
Open

Cannot set property 'exports' of undefined #406

amura11 opened this issue Jun 24, 2020 · 11 comments

Comments

@amura11
Copy link

@amura11 amura11 commented Jun 24, 2020

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();
@kaizhu256
Copy link
Member

@kaizhu256 kaizhu256 commented Jun 24, 2020

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();
@amura11
Copy link
Author

@amura11 amura11 commented Jun 24, 2020

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({
@kaizhu256
Copy link
Member

@kaizhu256 kaizhu256 commented Jun 25, 2020

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.

@amura11
Copy link
Author

@amura11 amura11 commented Jun 25, 2020

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 😵

@megahertz
Copy link

@megahertz megahertz commented Jun 26, 2020

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.

@hebronivy
Copy link

@hebronivy hebronivy commented Jul 23, 2020

I have the same problem when call initSqlJs().
enviroment:
electron: ^9.0.0
a react project created by CRA
image
But the code works well in chrome browser.

@kekeqy
Copy link

@kekeqy kekeqy commented Sep 7, 2020

I have the same porblem too.

@gz-95
Copy link

@gz-95 gz-95 commented Sep 8, 2020

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$/,
  },
}
@kekeqy
Copy link

@kekeqy kekeqy commented Sep 8, 2020

module: {
noParse: /sql.js/
}

@lovasoa
Copy link
Member

@lovasoa lovasoa commented Sep 8, 2020

Did you report this bug to webpack ?

@rishabbhattacharyya
Copy link

@rishabbhattacharyya rishabbhattacharyya commented Sep 17, 2020

the issue is still persisting

Uncaught (in promise) TypeError: Cannot set property 'exports' of undefined
at index.js:106
at new Promise ()
at n.r [as sqlite] (index.js:106)
at n. (SqljsDriver.js:273)
at tslib.es6.js:99
at Object.next (tslib.es6.js:80)
at tslib.es6.js:73
at new Promise ()
at Object.o (tslib.es6.js:69)
at n.createDatabaseConnectionWithImport (SqljsDriver.js:263)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
8 participants