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

Could not use static es6 import 'gun/sea' ? #636

Closed
Kirpich634 opened this issue Nov 14, 2018 · 19 comments
Closed

Could not use static es6 import 'gun/sea' ? #636

Kirpich634 opened this issue Nov 14, 2018 · 19 comments

Comments

@Kirpich634
Copy link

If you do this:

import 'gun/sea';

we'll get:

Uncaught Error: Cannot find module './gun.js'

but if:

require('gun/sea');

everything will be OK.

With this, is possible to do somethingcan so that I could use static es6 import?

@amark
Copy link
Owner

amark commented Nov 15, 2018

@Kirpich634 interesting, could you try import 'gun/sea.js ? It looks like ES6 is grabbing from directory, not full file. I might be wrong...

Thanks for pointing this out.

@Kirpich634
Copy link
Author

Kirpich634 commented Nov 15, 2018

@amark No, I also thought about it immediately, but no. Does it work for you?

@amark
Copy link
Owner

amark commented Dec 6, 2018

you in browser or NodeJS?

Browser still requires you add SEA script tag, because import is kinda stupid like that.

@ikeyboard
Copy link

Hi, I test in react-native and it crash when import "gun/sea.js". I try to add crypto, text-encoding, node-webcrypto-ossl... but it still crash. Any advice for react-native?

@amark
Copy link
Owner

amark commented Apr 17, 2019

@ikeyboard React-Native doesn't seem to have WebCrypto spec or allow for polyfills.

To get SEA working in React-Native (I don't use React, so I'm guessing and need community help here) you will need to have React-Native bridge RPC calls to a JS webview (where WebCrypto exists) and execute it there, then pass the values back to React-Native.

I know some people have successfully gotten SEA working in React-Native, so this is possible!

@amark
Copy link
Owner

amark commented May 10, 2019

Unless somebody in the community who has ES6 experience volunteers to debug this, I don't have enough bandwidth/capacity (or ES6-know-how-knowledge, I can't even figure out how to get ANY import statement working for ANY tool/project/library, GUN or not, this is how dumb I am) to figure this out, meaning the defacto answer will remain as "use require('gun/sea');" and I'll be closing.

This is an area where somebody in the community that has ES6 knowledge should know exactly what is going on (unless import is magic???) and contribute + explain + document how to get it to work (or explain to me why my module.export doesn't work so I can fix it, or if simple enough, they PR a fix without breaking unbuild), and be able to do so quickly and easily. If somebody is willing to volunteer on that, please re-open with explanation.

@amark amark closed this as completed May 10, 2019
@r14c
Copy link

r14c commented May 10, 2019 via email

@amark
Copy link
Owner

amark commented May 10, 2019

@r14c I appreciate your comment! import doesn't work without additional tooling?? I thought it was in the spec. Nevermind, :P I'll just trust what you say!

  • I write code to work in the Browser first.
  • No build step, no toolchain.
  • This code also works in NodeJS.
  • Optionally, I then unbuild the single well-organized browser file, into a bunch of sub-files that are NodeJS require dependent on each other.

In SEA, I do:

var Gun = (SEA.window||{}).Gun || require('./gun');

I don't know why import gun/sea would make a difference compared to require gun/sea, it shouldn't it should only matter depending on environment (browser vs nodejs).

In browser, Gun attaches itself to window so should NOT cause || require('./gun') to happen.

In nodejs, {}.Gun will not exist thus || require('./gun.js') (both gun.js and sea.js are in top level - but there is a sea/ folder, which is why I asked about import gun/sea.js to make sure it wasn't getting confused).

The only way this should go wrong is if:

  1. In browser, if Gun does not exist, but this means it should error on require not say "can't find module".
  2. In nodejs, if pulling from sea/* but we know it is not because they said import 'gun/sea.js' doesn't work - ./gun.js from gun/* would go to gun/gun.js which is correct.
  3. In nodejs, if require has been tampered with by some build tool, but even then, it should be able to find it!

@r14c
Copy link

r14c commented May 10, 2019

es6 is spec, but afaik there aren't any stable native implementations. i'll try setting up a demo project with babel 7 one of these days to see what i can find.

@amark
Copy link
Owner

amark commented May 10, 2019

@r14c then how are other people using import with GUN already??? Like Babel still? So is Babel transpiling things wrong (if require works but import doesn't)?

@r14c
Copy link

r14c commented May 10, 2019 via email

@amark
Copy link
Owner

amark commented May 10, 2019

@r14c this is very enlightening, thank you for explaining!

@Kuirak
Copy link

Kuirak commented Jun 17, 2019

Actually ES modules are useable without tooling and flag since Edge 16, Firefox 60, Chrome 61, Safari 11 and Opera 48 (17/06/2019, Source)

you need to set type="module" on the script tag, sample:

<script type="module">
  import { tag } from './html.js'

  const h1 = tag('h1', ' Hello Modules!')
  document.body.appendChild(h1)
</script>

You need tooling if you are trying to consume commonjs or umd modules with es module syntax.
That's why a lot of library use a build step to generate a es module build and a umd build for commonjs and script tag usage.

require and import are two different types of module system. require is dynamic import is static and explicitly dynamic if use import().then(module => ....)

There are some subtile differences with scopes between both system, which transpilers like Babel or Typescript try to normalize. Why are es modules in node hard?

@amark
Copy link
Owner

amark commented Aug 12, 2019

Maybe @Kuirak can lead us blind people forward.

Looks like the conclusion is that it is normal for most projects to support 2 different versions, 1 for require and 1 for import?

All of GUN core should be static (altho I had to proxy require because webpack complained, so things are being reported as being dynamic, but this isn't necessary).

There might be 1 optional module that does do something dynamic, but that can either be dropped (as it is not necessary), or ... good to know! ... import().then I would have never known that was possible.

@mitra42
Copy link

mitra42 commented Aug 13, 2019

I think the support for two versions thing is a transientary effect of the current situation - we are facing this even with our own internal libraries (like dweb-archivecontroller).

Until recently, you could just use 'require', this worked fine in nodejs and webpack, and irrelevant in browsers which couldnt handle modules split across multiple files.

Now - and for a short time - you've got ES6 module support in browsers (i.e. import) but not require and you've got support for require in nodejs but not for import except with the --experimental option. Webpack has supported both for a long time.

That gives us a current oddity where shifting to import means not only people explicitly importing Gun have to use --experimental , but also anyone including a package that includes GUN (e.g. dweb-transports) and they might not even realize they are including Gun .

Once node fully supports import in its default version, I'd expect everyone to shift over to import.

@amark
Copy link
Owner

amark commented Aug 15, 2019

@mitra42 that was a very useful summary, thank you.

@rm-rf-etc
Copy link

ES modules in node are not hard. It's literally just 2 steps.
npm install esm --save-dev
node -r esm whatever.js

ES modules are the spec but they aren't yet implemented natively in nodejs.

@rm-rf-etc
Copy link

Quick example, how to use ES modules. Should take only a minute to try.
https://gist.github.com/rm-rf-etc/ded65ccf885e256df419bef799ed5809

@davidmaxwaterman
Copy link

In case anyone else ends up here wondering how to import gun into an es6 module, I had success with the following at the top of my module:

import * as Gun from "./node_modules/gun/gun.js";

then, in the browser console, I see:

Hello wonderful person! :) Thanks for using GUN, please ask for help on http://chat.gun.eco/ if anything takes you longer than 5min to figure 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

8 participants