Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Import node module conditionally based on node version

Tags:

node.js

I'm in a situation where we have different environments running different versions of Node and I would like to be able to conditionally import certain modules based on the version of node that is running.

I tried doing this with the following block of code, but it results in an error

'import' and 'export' may only appear at the top level

let ver = process.version.slice(1,ver.length).split('.');
if (parseInt(ver[0]) < 7) {
  import 'babel-polyfill'
}
like image 350
bigtunacan Avatar asked Jul 23 '26 08:07

bigtunacan


2 Answers

There is a babel-preset for this - https://babeljs.io/docs/en/babel-plugin-syntax-dynamic-import. You can use it as following -

let ver = process.version.slice(1,ver.length).split('.');
if (parseInt(ver[0] < 7)) {
    import('babel-polyfill')
    .then(result => {
       console.log(result);
    });
}
like image 177
Rishikesh Dhokare Avatar answered Jul 25 '26 01:07

Rishikesh Dhokare


Conditional import is only allowed as dynamic imports, which are supported with Node.js experimental ES module support. The problem with dynamic imports is that they are asynchronous. Since a polyfill should be applied to all application, this propagates dynamic imports to all module imports. I.e.

import 'babel-polyfill';

import * as foo from './foo';
import * as bar from './bar';
...

becomes

(async () => {
  let ver = process.version.slice(1,ver.length).split('.');
  if (parseInt(ver[0]) < 7) {
    await import 'babel-polyfill';
  }

  const foo = await import('./foo');
  const bar = await import('./bar');
  ...
})()
.catch(console.error);

So it's still a good idea to use require for conditional imports in Node.js non-native ES modules, because ES modules are supposed to be transpiled to CommonJS and require with Babel:

let ver = process.version.slice(1,ver.length).split('.');
if (parseInt(ver[0]) < 7) {
  require('babel-polyfill');
}

import * as foo from './foo';
import * as bar from './bar';
...

Most importantly, a polyfill shouldn't be conditionally imported because it's purpose is to polyfill missing features. It does nothing with features that don't need to be polyfilled. If some parts of babel-polyfill are unused but cause problems in later Node versions, import only parts that are needed in current application. babel-polyfill is just a wrapper around core-js polyfill which is fine-grained and can be narrowed down to polyfilling specific features.

like image 21
Estus Flask Avatar answered Jul 25 '26 00:07

Estus Flask



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!