preactjs / wmr

👩‍🚀 The tiny all-in-one development tool for modern web apps.
https://wmr.dev/
MIT License
4.93k stars 110 forks source link

Exports detection fails for UMD bundle like he #304

Closed sastan closed 3 years ago

sastan commented 3 years ago

In twind we are using node-html-parser which uses he (A robust HTML entities encoder/decoder with full Unicode support.).

It seems as wmr does not detect the exports from he and fails with the following error:

'decode' is not exported bynpm/he@1.2.0/he.js, imported bynpm/node-html-parser@2.0.1/dist/esm/nodes/html.js

he uses the UMD format. Below is the relevant code from the entry js of he:

;(function(root) {

    // Detect free variables `exports`.
    var freeExports = typeof exports == 'object' && exports;

    // Detect free variable `module`.
    var freeModule = typeof module == 'object' && module &&
        module.exports == freeExports && module;

    // Detect free variable `global`, from Node.js or Browserified code,
    // and use it as `root`.
    var freeGlobal = typeof global == 'object' && global;
    if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) {
        root = freeGlobal;
    }

        /* snip: implemention code */

    /*--------------------------------------------------------------------------*/

    var he = {
        'version': '1.2.0',
        'encode': encode,
        'decode': decode,
        'escape': escape,
        'unescape': decode
    };

    // Some AMD build optimizers, like r.js, check for specific condition patterns
    // like the following:
    if (
        typeof define == 'function' &&
        typeof define.amd == 'object' &&
        define.amd
    ) {
        define(function() {
            return he;
        });
    }   else if (freeExports && !freeExports.nodeType) {
        if (freeModule) { // in Node.js, io.js, or RingoJS v0.8.0+
            freeModule.exports = he;
        } else { // in Narwhal or RingoJS v0.7.0-
            for (var key in he) {
                has(he, key) && (freeExports[key] = he[key]);
            }
        }
    } else { // in Rhino or a web browser
        root.he = he;
    }

}(this));

As a current workaround we bundle all dependencies in the module that is used by wmr.

developit commented 3 years ago

What's the reason for trying to use named imports from a UMD bundle? UMD does not support named imports, so importing the module will only return its exports as a default export.

sastan commented 3 years ago

You are right. The culprit seems to be this line from node-html-parser: import { decode } from 'he'; (https://github.com/taoqf/node-html-parser/blob/master/src/nodes/html.ts#L1)

I'll open an issue there.

Thank you for your time.

developit commented 3 years ago

All good! FWIW I am currently exploring what it would take to have WMR "patch" the named import issue, the blocker is generally production output. It's the reason some usage of react-is fails in WMR too, so if there ends up being a way to fix it without hurting performance in cases where's the behavior is unused, it's something I'd like to land.