So I'm planning on writing a package which a user will hopefully be able to use on both Node.js and in the browser.
On the Node.js side it will use the fs
module. This does not exist in the browser perhaps. This could be accomplished with CommonJS with an if
clause to check which environment the module is in and a simple require
.
This is not the case with import
as it is hoisted.
Does anyone have an idea of how to structure the code or the build environment to satisfy both enviroments in the same package?
It seems there was an improvement in import
support in Node.js. In the docs it says:
The
--experimental-modules
flag can be used to enable support for ECMAScript modules (ES modules).Once enabled, Node.js will treat the following as ES modules when passed to node as the initial input, or when referenced by import statements within ES module code:
Files ending in
.mjs
.Files ending in
.js
, or extensionless files, when the nearest parentpackage.json
file contains a top-level field"type"
with a value of"module"
.Strings passed in as an argument to
--eval
orSTDIN
, with the flag--input-type=module
.
The second listed approach may be useable with node.js. Simply make sure your librarie's package.json
contains "type": "module"
and Node should treat it as a ES6 module instead of CommonJS.
Conditional imports are already available in node but not actually supported. They seem to work in browser. And there's a caveat: the imported module is a promise. What that means is that you can have partially isomorphic code as long as you plan your steps well. Knowing that you can do import("test.js")
in browser and that you can test for window
means you can write conditions in a smart way and have cross-platform code.
For example you can do:
if (typeof window !== 'undefined') const FooPromise = import("foo");
But not the opposite. Good luck. Hopefully more support for the es6 dynamic import will come to node.