swc-project / swc

Rust-based platform for the Web
https://swc.rs
Apache License 2.0
30.95k stars 1.21k forks source link

Usage of uuid(3.4.0) library generates invalid output with spack #5520

Open avra-m3 opened 2 years ago

avra-m3 commented 2 years ago

Describe the bug

The input code when bundled with spack generates TypeError: (0 , _uuid.v4) is not a function.

Input code

import { v4 as uuidv4 } from 'uuid';

console.log(uuidv4())

Config

.swcrc

{
  "jsc": {
    "parser": {
      "syntax": "typescript",
      "tsx": false,
      "decorators": true
    },
    "externalHelpers": true
  },
  "module": {
    "type": "commonjs"
  }
}

spack.config.js

const {config} = require("@swc/core/spack");
const path = require("path");

module.exports = config({
    entry: {bug_test: path.join(__dirname, "test.ts")},
    output: {path: path.join(__dirname, "dist")},
    module: {},
    target: "browser",
});

Playground link

No response

Expected behavior

Output a uuid

Actual behavior

console.log((0, _uuid.v4)());
                         ^

TypeError: (0 , _uuid.v4) is not a function
    at Object.<anonymous> (/<dir>/dist/bug_test.js:167:26)
    at Module._compile (node:internal/modules/cjs/loader:1105:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:77:12)
    at node:internal/main/run_main_module:17:47

Version

1.2.224

Additional context

generated bundle code

function __swcpack_require__(mod) {
    function interop(obj) {
        if (obj && obj.__esModule) {
            return obj;
        } else {
            var newObj = {};
            if (obj != null) {
                for(var key in obj){
                    if (Object.prototype.hasOwnProperty.call(obj, key)) {
                        var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {};
                        if (desc.get || desc.set) {
                            Object.defineProperty(newObj, key, desc);
                        } else {
                            newObj[key] = obj[key];
                        }
                    }
                }
            }
            newObj.default = obj;
            return newObj;
        }
    }
    var cache;
    if (cache) {
        return cache;
    }
    var module = {
        exports: {}
    };
    mod(module, module.exports);
    cache = interop(module.exports);
    return cache;
}
var load = __swcpack_require__.bind(void 0, function(module, exports1) {
    var getRandomValues = typeof crypto != "undefined" && crypto.getRandomValues && crypto.getRandomValues.bind(crypto) || typeof msCrypto != "undefined" && typeof window.msCrypto.getRandomValues == "function" && msCrypto.getRandomValues.bind(msCrypto);
    if (getRandomValues) {
        var rnds8 = new Uint8Array(16);
        module.exports = function whatwgRNG() {
            getRandomValues(rnds8);
            return rnds8;
        };
    } else {
        var rnds = new Array(16);
        module.exports = function mathRNG() {
            for(var i = 0, r; i < 16; i++){
                if ((i & 0x03) === 0) r = Math.random() * 0x100000000;
                rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;
            }
            return rnds;
        };
    }
});
var load1 = __swcpack_require__.bind(void 0, function(module, exports1) {
    var byteToHex = [];
    for(var i = 0; i < 256; ++i)byteToHex[i] = (i + 0x100).toString(16).substr(1);
    function bytesToUuid(buf, offset) {
        var i = offset || 0;
        var bth = byteToHex;
        return [
            bth[buf[i++]],
            bth[buf[i++]],
            bth[buf[i++]],
            bth[buf[i++]],
            "-",
            bth[buf[i++]],
            bth[buf[i++]],
            "-",
            bth[buf[i++]],
            bth[buf[i++]],
            "-",
            bth[buf[i++]],
            bth[buf[i++]],
            "-",
            bth[buf[i++]],
            bth[buf[i++]],
            bth[buf[i++]],
            bth[buf[i++]],
            bth[buf[i++]],
            bth[buf[i++]]
        ].join("");
    }
    module.exports = bytesToUuid;
});
var load2 = __swcpack_require__.bind(void 0, function(module, exports1) {
    var rng = load();
    var bytesToUuid = load1();
    var _nodeId;
    var _clockseq;
    var _lastMSecs = 0;
    var _lastNSecs = 0;
    function v1(options, buf, offset) {
        var i = buf && offset || 0;
        var b = buf || [];
        options = options || {};
        var node = options.node || _nodeId;
        var clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq;
        if (node == null || clockseq == null) {
            var seedBytes = rng();
            if (node == null) node = _nodeId = [
                seedBytes[0] | 0x01,
                seedBytes[1],
                seedBytes[2],
                seedBytes[3],
                seedBytes[4],
                seedBytes[5]
            ];
            if (clockseq == null) clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff;
        }
        var msecs = options.msecs !== undefined ? options.msecs : new Date().getTime();
        var nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1;
        var dt = msecs - _lastMSecs + (nsecs - _lastNSecs) / 10000;
        if (dt < 0 && options.clockseq === undefined) clockseq = clockseq + 1 & 0x3fff;
        if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) nsecs = 0;
        if (nsecs >= 10000) throw new Error("uuid.v1(): Can't create more than 10M uuids/sec");
        _lastMSecs = msecs;
        _lastNSecs = nsecs;
        _clockseq = clockseq;
        msecs += 12219292800000;
        var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000;
        b[i++] = tl >>> 24 & 0xff;
        b[i++] = tl >>> 16 & 0xff;
        b[i++] = tl >>> 8 & 0xff;
        b[i++] = tl & 0xff;
        var tmh = msecs / 0x100000000 * 10000 & 0xfffffff;
        b[i++] = tmh >>> 8 & 0xff;
        b[i++] = tmh & 0xff;
        b[i++] = tmh >>> 24 & 0xf | 0x10;
        b[i++] = tmh >>> 16 & 0xff;
        b[i++] = clockseq >>> 8 | 0x80;
        b[i++] = clockseq & 0xff;
        for(var n = 0; n < 6; ++n)b[i + n] = node[n];
        return buf ? buf : bytesToUuid(b);
    }
    module.exports = v1;
});
var load3 = __swcpack_require__.bind(void 0, function(module, exports1) {
    var rng = load();
    var bytesToUuid = load1();
    function v4(options, buf, offset) {
        var i = buf && offset || 0;
        if (typeof options == "string") {
            buf = options === "binary" ? new Array(16) : null;
            options = null;
        }
        options = options || {};
        var rnds = options.random || (options.rng || rng)();
        rnds[6] = rnds[6] & 0x0f | 0x40;
        rnds[8] = rnds[8] & 0x3f | 0x80;
        if (buf) for(var ii = 0; ii < 16; ++ii)buf[i + ii] = rnds[ii];
        return buf || bytesToUuid(rnds);
    }
    module.exports = v4;
});
var load4 = __swcpack_require__.bind(void 0, function(module, exports1) {
    var v1 = load2();
    var v4 = load3();
    var uuid = v4;
    uuid.v1 = v1;
    uuid.v4 = v4;
    module.exports = uuid;
});
"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
var _uuid = load4();
console.log((0, _uuid.v4)());
avra-m3 commented 2 years ago

Newer uuid versions are not an option due to https://github.com/swc-project/swc/issues/3406

samesfahani-tuplehealth commented 2 years ago

I am facing the same issue. Here is the minimal repro I can produce:

Versions

@swc/cli: 0.1.57
@swc/core: 1.2.242

macOS Monterey

spack.config.js

const { config } = require('@swc/core/spack');

module.exports = config({
  entry: {
    web: __dirname + '/cryptotester.ts',
  },
  output: {
    path: __dirname + '/dist',
  },
  options: {
    swcrc: true,
  },
  target: 'node',
  module: {},
});

cryptotester.ts

import { v4 } from 'uuid';

export function createHash() {
  return v4();
}

swcrc

{
  "$schema": "https://json.schemastore.org/swcrc",
  "jsc": {
    "baseUrl": "./src",
    "parser": {
      "syntax": "typescript",
      "tsx": false,
      "decorators": true,
      "dynamicImport": false
    },
    "transform": {
      "decoratorMetadata": true,
      "legacyDecorator": true
    },
    "target": "es2020",
    "loose": false,
    "externalHelpers": false
  },
  "module": {
    "type": "commonjs"
  },
  "exclude": [".*.test.ts$", ".*.spec.ts$"],
  "minify": false,
  "sourceMaps": true
}

Error after running spack

thread '<unnamed>' panicked at 'internal error: entered unreachable code: module item found but is_es6 is false: ExportNamed(NamedExport { span: Span { lo: BytePos(148), hi: BytePos(188), ctxt: #0 }, specifiers: [Named(ExportNamedSpecifier { span: Span { lo: BytePos(157), hi: BytePos(170), ctxt: #0 }, orig: Ident(Ident { span: Span { lo: BytePos(157), hi: BytePos(164), ctxt: #15 }, sym: Atom('default' type=static), optional: false }), exported: Some(Ident(Ident { span: Span { lo: BytePos(168), hi: BytePos(170), ctxt: #11 }, sym: Atom('v1' type=inline), optional: false })), is_type_only: false })], src: Some(Str { span: Span { lo: BytePos(178), hi: BytePos(187), ctxt: #0 }, value: Atom('./v1.js' type=inline), raw: Some("'./v1.js'") }), type_only: false, asserts: None })', /Users/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/swc_bundler-0.179.0/src/bundler/chunk/cjs.rs:142:29
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
node:internal/process/promises:246
          triggerUncaughtException(err, true /* fromPromise */);
          ^

[Error: panic detected: internal error: entered unreachable code: module item found but is_es6 is false: ExportNamed(NamedExport { span: Span { lo: BytePos(148), hi: BytePos(188), ctxt: #0 }, specifiers: [Named(ExportNamedSpecifier { span: Span { lo: BytePos(157), hi: BytePos(170), ctxt: #0 }, orig: Ident(Ident { span: Span { lo: BytePos(157), hi: BytePos(164), ctxt: #15 }, sym: Atom('default' type=static), optional: false }), exported: Some(Ident(Ident { span: Span { lo: BytePos(168), hi: BytePos(170), ctxt: #11 }, sym: Atom('v1' type=inline), optional: false })), is_type_only: false })], src: Some(Str { span: Span { lo: BytePos(178), hi: BytePos(187), ctxt: #0 }, value: Atom('./v1.js' type=inline), raw: Some("'./v1.js'") }), type_only: false, asserts: None })] {
  code: 'GenericFailure'
}

Not sure if this helps, esbuild was able to build cryptotester.ts just fine. I can provide the built output of the file if need be, but because it is quite long I will hold off...

samesfahani-tuplehealth commented 2 years ago

After some more digging, it seems like if I set module: { type: 'es6' }} in my .swcrc, the error goes away, so it's likely related to CommonJS?