electron/electron-quick-start-typescript

Uncaught ReferenceError: exports is not defined

lukejagodzinski opened this issue ยท 18 comments

Thanks for updating this repository to use the newest version of Electron. I was trying to use it but I have a problem with React. When I try to import I get the Uncaught ReferenceError: exports is not defined. I've tried several solutions found on Stackoverflow and GitHub but nothing works. I've also tried nodeIntegration: true but it doesn't seem to work either. It exposes window.require function but it doesn't add module.exports. I don't know what's wrong with that.

Same issue, no updates?

I got the same problem

I have the same problem, and adding <script>var exports = {};</script> before any other script tags in index.html resolves this.

I wish we wouldn't have to do hacks like that, but I doubt it's a fault of this repo. Adding this script tag in the default index.html with a comment about why would probably help a lot of users.

Same problem, it can be resolved if you use webpack.

  • First need to install it with npm install webpack webpack-cli --save-dev
  • Create a file named webpack.config.js (in your project root folder)
  • Add this in your webpack.config.js :
var path = require('path');

module.exports = {
	watch: false,
	target: 'electron-renderer',
	mode: 'development',
	devtool: 'inline-source-map',
	entry: `./src/renderer.ts`,
	output: {
		path: path.resolve(__dirname, 'dist'),
		filename: 'bundle.js'
	},
	resolve: {
		// Add `.ts` and `.tsx` as a resolvable extension.
		extensions: [".ts", ".tsx", ".js"]
	},
	module: {
		rules: [
			// all files with a `.ts` or `.tsx` extension will be handled by `ts-loader`
			{ test: /\.tsx?$/, loader: "ts-loader" }
		]
	}
};
  • In your index.html file, replace :
     <script src="./dist/renderer.js"></script>
    by this :
     <script src="./dist/bundle.js"></script>
  • Generate your js file before build your bundle with npm run build
  • Generate your bundle.js file with npx webpack --config webpack.config.js
  • And now you can npm start

This work for me ๐Ÿ˜„

Same problem, it can be resolved if you use webpack.

@5aitama Is there any way to solve this without using Webpack? Using Webpack for Electron seems a little bit odd to me and I think there has to be some native way to fix this issue... any other ideas?

I have the same problem, and adding <script>var exports = {};</script> before any other script tags in index.html resolves this.

I wish we wouldn't have to do hacks like that, but I doubt it's a fault of this repo. Adding this script tag in the default index.html with a comment about why would probably help a lot of users.

@TTSKarlsson, are you still using these 'hacks' today? Did none of you find a better solution?

I had this same problem, which only happened if my code included an import statement. @5aitama's solution worked for me.

in main.ts activate nodeIntegration like below:

webPreferences: {
      nodeIntegration: true,
      preload: path.join(__dirname, "preload.js"),
    },

in your index.html
replace:

<script src="./dist/renderer.js"></script>

with:

<script>
    require("./dist/renderer.js");
</script>

@saostad's suggestion gives me an error that it violates the content security policy. Removing the CSP warns me that it's insecure.

Same issue with @TTSKarlsson's suggestion of inline script in index.html. However, I put the var exports = {} in a js file and added <script src='set-exports.js'></script> to index.html.

in main.ts activate nodeIntegration like below:

webPreferences: {
      nodeIntegration: true,
      preload: path.join(__dirname, "preload.js"),
    },

in your index.html
replace:

<script src="./dist/renderer.js"></script>

with:

<script>
    require("./dist/renderer.js");
</script>

@saostad, working but very unsafe: electron/electron#9920 (comment)

Still no fix?
I don't want to enable nodeIntegration...
Is there any way to fix this?

@ShlomiRex check this solution initially it didn't work also with nodeintegration: true but ( mysteriously ) after a few restart of electron started to work.

in main.ts activate nodeIntegration like below:

webPreferences: {
      nodeIntegration: true,
      preload: path.join(__dirname, "preload.js"),
    },

in your index.html
replace:

<script src="./dist/renderer.js"></script>

with:

<script>
    require("./dist/renderer.js");
</script>

Also, set contextIsolation to false:

webPreferences: {
    nodeIntegration: true,
    contextIsolation: false,
    preload: path.join(__dirname, "preload.js"),
 }

I couldn't use it just by nodeIntegration.

JoCat commented

This is a dirty hack, but you can do it like this:

set the following settings in main.ts:

webPreferences: {
  preload: path.join(__dirname, "preload.js"),
},

in preload.ts use import like:

import { contextBridge, shell } from 'electron'

function openUrl(url: string) {
  shell.openExternal(url)
}

contextBridge.exposeInMainWorld("openUrl", openUrl);

in renderer.ts use like:

const _window = window as any; // Yes, it's dirty, but I have not yet figured out how to do it better (you can try to build an extended interface from Window, but so far I have not tried it)
_window.openUrl("https://example.com/");

Here's my proposal for fixing this: #152

Any movement on this? @5aitama's solution does not work for me, saying it can't find module 'fs' in the electron node_module, oddly. Tried using an exclude regex to no avail.

Trying again a few hours later, it's also telling me require is not defined. It's trying to require electron.. within the bundle.. oddly. Maybe I'm not configuring it right.

Here's my proposal for fixing this: #152

This is the fix

malept commented

Here's my proposal for fixing this: #152

This is the fix

It's not, see the comments in the PR.

Zena4L commented

This fix it


module.exports = {
	watch: false,
	target: 'electron-renderer',
	mode: 'development',
	devtool: 'inline-source-map',
	entry: `./src/public/fe/index.ts`,
	output: {
		path: path.resolve(__dirname, 'dist','public','fe'),
		filename: 'index.js'
	},
	resolve: {
		// Add `.ts` and `.tsx` as a resolvable extension.
		extensions: [".ts", ".tsx", ".js"]
	},
	module: {
		rules: [
			// all files with a `.ts` or `.tsx` extension will be handled by `ts-loader`
			{ test: /\.tsx?$/, loader: "ts-loader" }
		]
	},
  watch: true,
};```