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

'default' is not exported by ... #38

Closed
theurgi opened this issue Dec 18, 2021 · 10 comments
Closed

'default' is not exported by ... #38

theurgi opened this issue Dec 18, 2021 · 10 comments

Comments

@theurgi
Copy link

theurgi commented Dec 18, 2021

In a SvelteKit project (using Vite) I was getting errors derived from dependencies of a package I'm using referencing node globals. Here's my original issue for reference: blocknative/web3-onboard#762.

After much searching I found this package and used it as shown in #14 (comment).

This fixed everything on the dev server, no more ReferenceError: Buffer is not defined etc.

But then when I went to build I ran into another issue that I do not experience without rollup-plugin-polyfill-node...

'default' is not exported by node_modules/js-sha3/src/sha3.js, imported by node_modules/@ethersproject/keccak256/lib.esm/index.js

I can add node_modules/js-sha3/src/sha3.js to the exclude array and it remedies the issue for that particular module but then the next attempted default import fails the build.

I tried @rollup/plugin-node-resolve and @rollup/plugin-commonjs to no avail. Is there another rollup plugin I need?

Here are the relevant parts of my config:

// svelte.config.js
import nodePolyfills from 'rollup-plugin-polyfill-node'

const config = {
  kit: {
    vite: {
      plugins: [
        nodePolyfills({
          include: [
            '*.js',
           'node_modules/**/*.js',
            new RegExp('node_modules/.vite/.*js')
          ],
          // ↓ Not sure if this line is necessary, seems to work without it
          exclude: ['node_modules/polyfill-nodeglobal.js']
        })
      ],
      resolve: {
        alias: {
          // ↓ see https://github.com/vitejs/vite/issues/6085
          '@ensdomains/address-encoder': '@ensdomains/address-encoder/lib/index.umd.js'
        }
      }
    }
  }
}

export default config
@theurgi
Copy link
Author

theurgi commented Dec 18, 2021

Update

I added all files to exclude that do not export 'default' and the build completed. However when I preview the build, nothing loads and Uncaught ReferenceError: require is not defined is logged to the console.

How can this run and work as expected on the dev server but not build?

@theurgi
Copy link
Author

theurgi commented Dec 18, 2021

After trying 100 different configurations like a dumb monkey, I stumbled upon one that finally worked both on the dev server and in the build.

My solution: blocknative/web3-onboard#762 (comment)

@syffs
Copy link

syffs commented Jan 7, 2022

@theurgi I'm having the same issue, but I'm using rollup directly (not vite). Tried to understand the takeaway from your solution, but it doesn't work and I don't get how it would work:
You're simply

import svelte from 'rollup-plugin-svelte'
import commonjs from '@rollup/plugin-commonjs'
import resolve from '@rollup/plugin-node-resolve'
import livereload from 'rollup-plugin-livereload'
import { terser } from 'rollup-plugin-terser'
import sveltePreprocess from 'svelte-preprocess'
import typescript from '@rollup/plugin-typescript'
import nodePolyfills from 'rollup-plugin-polyfill-node'
import path from 'path'

const projectRootDir = path.resolve(__dirname)
const production = !process.env.ROLLUP_WATCH

function serve() {
	let server

	function toExit() {
		if (server) server.kill(0)
	}

	return {
		writeBundle() {
			if (server) return
			server = require('child_process').spawn('npm', ['run', 'start', '--', '--dev'], {
				stdio: ['ignore', 'inherit', 'inherit'],
				shell: true
			})

			process.on('SIGTERM', toExit)
			process.on('exit', toExit)
		}
	}
}

export default {
	input: 'src/main.ts',
	output: {
		sourcemap: !production,
		format: 'iife',
		name: 'SomeSdk',
		file: `public/build/some-sdk${production ? '.min' : ''}.js`,
	},
	plugins: [
		svelte({
			compilerOptions: {
				dev: !production,
				cssHash: ({hash, css}) => `h-${hash(css)}`,
			},
			preprocess: sveltePreprocess({
				sourceMap: !production,
				postcss: {
					plugins: [
						require("autoprefixer")(),
						require("tailwindcss")(),
						...(production ? [require("cssnano")()] : []),
					],

				},
			}),
			emitCss: false,
		}),

                // ↓ had this
		// nodePolyfills(),
                // ↓ updated to this
                ...(process.env.NODE_ENV === 'development' ? [nodePolyfills({ include: ['node_modules/**/*.js'] })] : [nodePolyfills()]),

		resolve({
			browser: true,
			dedupe: ['svelte']
		}),
		commonjs({
                        // ↓ added this
			transformMixedEsModules: true,
		}),
		typescript({
			sourceMap: !production,
			inlineSources: !production
		}),

		!production && serve(),
		!production && livereload('public'),
		production && terser()
	],
	watch: {
		clearScreen: false
	}
}

The error I'm getting is:

[!] Error: 'default' is not exported by node_modules/js-sha3/src/sha3.js, imported by node_modules/@ethersproject/keccak256/lib.esm/index.js
https://rollupjs.org/guide/en/#error-name-is-not-exported-by-module
node_modules/@ethersproject/keccak256/lib.esm/index.js (2:7)
1: "use strict";
2: import sha3 from "js-sha3";

So in short, we'd need import sha3 from "js-sha3" translated to import * as sha3 from "js-sha3". Not sure how to achieve that.

any insight ?

@theurgi
Copy link
Author

theurgi commented Jan 7, 2022

I'm sorry, I don't have any certainty about what might be causing this issue. As I was trying many different configurations I do recall getting the specific error you're running into.

I don't know exactly what Vite does behind the scenes with Rollup, or in what order it does it—the cost of abstraction.

Have you tried various orderings for the nodePolyfills, resolve, and commonjs plugins?

@syffs
Copy link

syffs commented Jan 8, 2022

@theurgi I see, thanks for sharing !

I got fed up by this issue and ended up simply using ethers esm build as a workaround:

import {ethers} from 'ethers/dist/ethers.esm'

@imsys
Copy link
Contributor

imsys commented Jan 25, 2022

I finally understand what's going on, this explain quite well:
evanw/esbuild#1719 (comment)
and in this link too:
https://github.com/rollup/plugins/tree/master/packages/commonjs#defaultismoduleexports
Hopefully I will soon get it working.

@imsys
Copy link
Contributor

imsys commented Jan 25, 2022

My case is explained in this issue: blocknative/web3-onboard#794
And I have a demonstration example at: https://github.com/imsys/sveltekit-onboard-test
I give all the credits to @theurgi for getting most of the working configuration. For me, the production builds fine, but the development I get a problem.
onboard requires the cjs package @gnosis.pm/safe-apps-sdk.

gnosis contains Object.defineProperty(exports, "__esModule", { value: true });
And being so, @rollup/plugin-commonjs has the setting of defaultIsModuleExports to auto, and this will make gnosis import return an object of { default: value } and I would like to set defaultIsModuleExports to false.
But as @rollup/plugin-commonjs is included in rollup-plugin-polyfill-node, it seems that I need to pass the configurations there and I can't.

Maybe if I could pass the config like:

nodePolyfills({
    commonjsOptions: {
        defaultIsModuleExports : false
    }
})

I think in this way I would be able to get it working.

@imsys
Copy link
Contributor

imsys commented Jan 25, 2022

Edit: that invocation of @rollup/plugin-commonjs seems to be to polyfill just a few specific files,.. so,.. my mistake.

@FredKSchott
Copy link
Owner

Fixed by #42

@coolcorexix
Copy link

coolcorexix commented Jul 25, 2023

I still encounter this problem while using Vite, after fixing the problem on buffer I get thrown other errors where vite get import * as from and import from incorrectly. The way I overcome this problem is not to use this plugin at all and instead inject only the nodejs deps I need direcly.

First install buffer deps:

npm install -D buffer

Then. Two way of doing this:

import inject from '@rollup/plugin-inject';

//  vite.config.ts
export default defineConfig({
...
  build: {
    rollupOptions: {
      plugins: [inject({ Buffer: ['Buffer', 'buffer'] })],
    },
  },
...
})

or this

import { NodeGlobalsPolyfillPlugin } from '@esbuild-plugins/node-globals-polyfill'

export default defineConfig({
...
 optimizeDeps: {
    esbuildOptions: {
      // Node.js global to browser globalThis
      define: {
        global: 'globalThis'
      },
      // Enable esbuild polyfill plugins
      plugins: [
        NodeGlobalsPolyfillPlugin({
          process: true,
          buffer: true
        }),
      ]
    },
  },
...
})

I prefer first solution for semantic reason, because this is not an ‘optimize’ at all, without this config the whole build will just break. But sadly, this solution does not work with another project.

UPDATE: another way I found out is to use aliases, like this:

npm install -D rollup-plugin-node-polyfills
// vite.config.ts
resolve: {
    alias: {
  ...
      buffer: 'rollup-plugin-node-polyfills/polyfills/buffer-es6',
      process: 'rollup-plugin-node-polyfills/polyfills/process-es6'
    }
  },

And a notice that this will only suitable for the case you need a few built in deps. In case there is a lot of deps needed, it is better if this plugin can handle that. @FredKSchott can you please take a look at the case of using this plugin in vitejs, I really want to know the root cause of this plugin breaking in this case. Just let me know if you want to triage, have a minimla reproduce repo or a PR. I am more than happy to help out.

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

No branches or pull requests

5 participants