vercel / ncc

Compile a Node.js project into a single file. Supports TypeScript, binary addons, dynamic requires.
https://npmjs.com/@vercel/ncc
MIT License
9.1k stars 288 forks source link

ReferenceError: Invalid left-hand side in assignment when using 'Kubernetes-client' model #500

Open darlenya opened 4 years ago

darlenya commented 4 years ago

Hello Team,

I added the module 'Kubernetes-client' to my project. Since then I got the error when using ncc:

ReferenceError: Invalid left-hand side in assignment at Object.<anonymous> (demo-ncc-error/dist/index.js:203847:1) at __webpack_require__ (demo-ncc-error/dist/index.js:22:30)

The error was caused by ` ... var utils = __webpack_require__(201)(require); var fn = require;

webpack_require(905) = utils; // The line which caused the error webpack_require(905)('is-plain-object', 'isObject'); webpack_require(905)('shallow-clone', 'clone'); webpack_require(905)('kind-of', 'typeOf'); webpack_require(973); webpack_require(905) = fn; ... `

Here is an example project showing the issue. To reproduce the issue execute: npm install npm run build node dist/index.js

demo-ncc-error.zip

With kind regards

Torsten

itsdarrylnorris commented 4 years ago

@darlenya , I am running to the same issue on a project that I am working on. Did you figure out how to fix this problem?

itsdarrylnorris commented 4 years ago

I am having similar issue with puppeteer-extra and their stealth plugin

Here is the code:

const puppeteer = require("puppeteer-extra");

// add stealth plugin and use defaults (all evasion techniques)
const StealthPlugin = require("puppeteer-extra-plugin-stealth");
puppeteer.use(StealthPlugin());

// puppeteer usage as normal
puppeteer.launch({ headless: true }).then(async (browser) => {
  console.log("Running tests..");
  const page = await browser.newPage();
  await page.goto("https://bot.sannysoft.com");
  await page.waitFor(5000);
  await page.screenshot({ path: "testresult.png", fullPage: true });
  await browser.close();
  console.log(`All done, check the screenshot. ✨`);
});
av commented 4 years ago

After a bit of investigation, the issue comes from a lazy-cache library use in the ancient version of the clone-deep library: https://github.com/jonschlinkert/clone-deep/blob/0.2.4/utils.js

In case of puppeteer-extra, that library is an indirect dep of an abstract plugin implementation:

└─┬ puppeteer-extra-plugin-adblocker@2.11.5
  └─┬ puppeteer-extra-plugin@3.1.6
    └─┬ merge-deep@3.0.2
      └── clone-deep@0.2.4 

I'm yet to find out what would be the way to affect ncc builds to fix the actual code generated.

av commented 4 years ago

For anyone stumbling upon this: As there were no easy or robust way to alter's ncc Webpack config to tweak this behavior, I've opted into using @vercel/node or @now/now-node build tooling directly in a following fashion:

const path = require('path');
const fs = require('fs');
const nowNode = require('@vercel/node');
const buildUtils = require('@vercel/build-utils');

(async () => {
  process.env.NOW_BUILDER_DEBUG = true;
  const projectPath = path.resolve(process.env.LAMBDA_DIR);
  const entrypoint = process.env.ENTRYPOINT;

  const workPath = await buildUtils.getWriteableDirectory();
  const inputFiles = await buildUtils.glob('**', projectPath);

  const result = await nowNode.build({
    files: inputFiles,
    workPath,
    entrypoint,
    meta: {
      awsLambdaHandler: entrypoint
    }
  });

  console.log("Storing the archive...");
  fs.writeFileSync(path.resolve(projectPath, 'code.zip'), result.output.zipBuffer);
})();

Where LAMBDA_DIR is a full path to the source folder of a function to be packed, ENTRYPOINT is a path to the file to serve as lambda handler, relative to LAMBDA_DIR.

It worked because @vercel/node works in a different fashion compared to ncc, compiling individual files, rather than bundling them all together, so it quite defeats the purpose of using ncc.

itsdarrylnorris commented 4 years ago

so it quite defeats the purpose of using ncc.

Yes, the project I am currently working on it's essential for me to compile everything into one file.

nathancahill commented 3 years ago

The version of clone-deep can be pinned to a recent release that doesn't do the funky utils = require code:

"resolutions": {
    "clone-deep": "4.0.1"
}
doerme commented 2 years ago

if (global.GENTLY) __nccwpck_require__(94120) = GENTLY.hijack(require);

doerme commented 2 years ago

if (global.GENTLY) __nccwpck_require__(94120) = GENTLY.hijack(require); ^

SyntaxError: Invalid left hand side for assignment at wrapSafe (internal/modules/cjs/loader.js:979:16) at Module._compile (internal/modules/cjs/loader.js:1027:27) at Object. (internal/modules/cjs/loader.js:1092:10) at Module.load (internal/modules/cjs/loader.js:928:32) at Function._load (internal/modules/cjs/loader.js:769:14) at Function.executeUserEntryPoint (internal/modules/run_main.js:72:12) at internal/main/run_main_module.js:17:47

Chheung commented 2 years ago

Is there any update on this?

itsdarrylnorris commented 2 years ago

@Chheung , It's tough for NCC to support all these early node js ways to do autoloading. I do not think it's going to happen. I spent quite a bit of time making it work for a project I was working on, and the issues are the autoloading from old/very popular packages.

If you must use NCC, my recommendation is to figure out which packages it's having issues with and try to implement them yourself, but it's a nightmare/rabbit hole.