简体   繁体   中英

Can't compile an optional Node.js dependency with Angular compiler

I've created an npm library containing code that looks like this:

let _Buffer: typeof Buffer;
let _require: NodeRequire;
let _readFile: (path: string, callback: (err: (NodeJS.ErrnoException | null), data: Buffer) => void) => void;

try {
  _Buffer = typeof Buffer !== undefined && Buffer;
  _require = typeof require !== undefined && require;

  if (_Buffer && _require)
    _readFile = _require('fs').readFile;
}
catch {}

I've managed to make parts of the above code work in other projects, like the optional dependency on Buffer . The use of require wasn't something I'd tried before, and this is what's now causing me grief. Angular is determined to try to resolve the dependency on fs , no matter how I try to hide it (including silly things like _require('f' + 's') ), causing an error like this:

./node_modules/@tubular/astronomy/dist/fesm2015/index.js:3:300-4:1 - Error: Module not found: Error: Can't resolve 'fs' in '/Users/kshetline/programming_projects/svc-ng/node_modules/@tubular/astronomy/dist/fesm2015'

What I'd most like to do is figure out a way to design the npm library so this isn't an issue at all.

A less satisfactory solution would be to find a way to tell the Angular compiler to ignore this particular external dependency. That's a difficult subject to google, however, because searches all come up with information regarding the Angular dependency injection system, not about this type of compile-time dependency.

The goal is to allow the library to have extra Node.js features when used in a Node.js environment, but still run smoothly in a browser when those features are not available.

Interesting... my above code actually does work quite well to hide the fs dependency.

What happened is that an earlier attempt did not succeed, and somehow, somewhere in node_modules or package-lock.json or in IntelliJ IDEA's cache system or Angular's cache system, the unwanted dependency on fs got locked in, and merely installing updated npm library that previously had the dependency wasn't cutting it.

After clearing away all of the above suspected sources of the unwanted memory of the bad dependency, finally my code would compiler and run.

With a bit more effort I came up with an improved version of the code, in that it works better with rollup and webpack, avoiding the need to declare fs as an external dependency.

let _Buffer: typeof Buffer;
let _readFile: (path: string, callback: (err: (NodeJS.ErrnoException | null), data: Buffer) => void) => void;

try {
  _Buffer = typeof Buffer !== undefined && Buffer;
  // eslint-disable-next-line no-new-func
  _readFile = !!_Buffer && (new Function('req', 'return req("fs").readFile'))(typeof require !== 'undefined' && require);
}
catch {}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM