简体   繁体   中英

How to conditionally use either a built-in Node.js or a browser API method with ES6-style imports?

Example context

I'm writing a library based on getting crypto-secure random bytes from a native source. I want to make the lib usable both in Node.js and in the browser. This requires using different built-in APIs in the two environments.

The problem

I'm searching for the general solution to use

  1. either Node.js API methods with ES6-style imports
  2. OR browser API methods,

based on environment detection.

The problem applied to the above example context

To make the lib usable both in Node.js and in browser environments, crypto.randomBytes() is used in Node.js, and window.crypto.getRandomValues() is used in the browser as underlying the random source.

The currently working solution is based on Node's dynamic require . The lib detects the environment, then:

  • in Node.js, it uses require('crypto') ,
  • in the browser, it uses window.crypto.getRandomValues() , which is simply available in the global scope and nothing has to be required/imported.

The question

Instead of using require() , I'm wondering if it's possible to use an ES6-style import { randomFill } from 'crypto'; with environment detection. The import would still be run in the browser, but there is no such built-in module in the browser, so that would be a problem.

Do you have any experience how transpilers (like babel) and bundlers (like rollup) handle this kind of problem with static imports?


Note: this is not a duplicate of How can I use an es6 import in node? . I know there are ESM and the --experimental-modules , and it works well. My question regards the case when both browser and Node.js environments are the target of an implementation, but due to the different environments, different platform-provided APIs must be used.

I'm not sure if this answers your question, but the way I solve this is basically through my webpack build.

I might have an import a bit like:

import { base64encode } from './base64';

In this directory I have 2 files:

base64.js
base64.web.js

It's possible to configure webpack to prefer the second one over the first. Other browser build tools have a feature like this as well.

This works really well for me, but this is only really an option if you have a 'build step'.

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