zxcvbn-ts / zxcvbn

Low-Budget Password Strength Estimation
https://www.usenix.org/conference/usenixsecurity16/technical-sessions/presentation/wheeler
MIT License
907 stars 72 forks source link

Dynamic ECMA2020 import not working client-side, only server-side #62

Closed softwarecreations closed 3 years ago

softwarecreations commented 3 years ago

In Meteor, I've been dynamically importing and using zxcvbn and it works great. import('/node_modules/zxcvbn/dist/zxcvbn.js').then( ({default:zxcvbn}) => {

Meteor offers ECMA2020 style dynamic imports. https://docs.meteor.com/packages/dynamic-import.html

However when I try to dynamically import zxcvbn-ts, the import comes through on the server-side during the React SSR (server-side render). But the result of the import() promise is empty on the clientside :( import('/node_modules/@zxcvbn-ts/core/dist/zxcvbn-ts.js').then( foo => { console.log("foo", foo) Foo shows an empty import: { default: {}, Symbol("__esModule"): true, Symbol(Symbol.toStringTag): "Module" }

And simultaneously the same dynamic import code works fine on the server-side during SSR

foo [Object: null prototype] [Module] {
  default: { zxcvbnts: { core: [Object] } },
  zxcvbnts: { core: { ZxcvbnOptions: [Options], zxcvbn: [Function: zxcvbn] } },
  [Symbol(__esModule)]: true
}

So, on the server side, I can do this without issues: import('/node_modules/@zxcvbn-ts/core/dist/zxcvbn-ts.js').then( ({zxcvbnts:{core:{zxcvbn, ZxcvbnOptions}}}) => {

I had a similar problem to this in another package, not sure if seeing the issue and solution there would be helpful https://github.com/center-key/pretty-print-json/issues/41

I wondered if perhaps your @ sign in the module name is causing a problem. But if I put in \\@ in the path then I get an error saying module not found. So the import code above definitely "finds" the module, whatever that means. But the import comes through empty on the clientside.

I'm importing the stuff separately like this.

import('/node_modules/@zxcvbn-ts/core/dist/zxcvbn-ts.js').then( ({zxcvbnts:{core:{zxcvbn, ZxcvbnOptions}}}) => { ...

import('/node_modules/@zxcvbn-ts/language-common/dist/zxcvbn-ts.js').then( ({default:zxcvbnCommonPackage}) => { ...

import('/node_modules/@zxcvbn-ts/language-en/dist/zxcvbn-ts.js').then( ({default:zxcvbnEnPackage}) => { ...

Then updating state when all the imports have come through, etc.

MrWook commented 3 years ago

Is it intended that you import the browser zxcvbn-ts file instead of the esm file? If i understand this correct you should do something like that

import('/node_modules/@zxcvbn-ts/core/dist/index.esm.js').then( ({zxcvbn, ZxcvbnOptions}) => { ...

import('/node_modules/@zxcvbn-ts/language-common/dist/index.esm.js').then( ({default: zxcvbnCommonPackage}) => { ...

import('/node_modules/@zxcvbn-ts/language-en/dist/index.esm.js').then( ({default: zxcvbnEnPackage}) => { ...
softwarecreations commented 3 years ago

@MrWook thank you, I implemented your suggestion. It works :)