I cannot find an accurate answer to this anywhere. I understand the browser doesn't recognise commonJS syntax hence why if require() is loaded into the browser a reference error occurs like this
let isEven = require('is-even') // ReferenceError: Can't find variable: require
console.log(isEven(6)); // this doesn't run
So I try to use ES6 modules like this:
import isEven from "is-even";
console.log(isEven(6));
I then get this error in the console:
TypeError: Module specifier, 'is-even' does not start with "/", "./", or "../".
My fix at the moment is to run a module bundler like Webpack which allows me to use both of these syntax's effectively and I have no problems. However I would rather find an alternative because I find it harder to fix bugs when using a module bundler as it can be quite difficult to locate the code causing the error. Is there an alternative other than using a module bundler to transform to older Javascript modules before served to the browser ?
CodePudding user response:
import
in a browser does not allow importing from a plain filename. You must at least construct some kind of path starting with "/"
, "./"
, or "../"
or even a full URL as import
in the browser does not have a "default" place to load a plain filename from. You must be explicit about what the path is.
And, keep in mind that import
from a browser will make a request to your server and your server must be configured to provide that file to the browser when requested.
So, depending upon how you have your server configured, you may want something like this:
import isEven from "/is-even.js";
console.log(isEven(6));
Or, if your server handles scripts separately, you might even have this:
import isEven from "/scripts/is-even.js";
console.log(isEven(6));
And, then it is the web server's responsibility to know how to receive one of these requests, know where that actual script file is in the server's file system, get it and send it back to the browser.
Keep in mind that the main reason client-side code uses bundlers is that it is not efficient to have a web page that loads tons of script modules, each loaded separately because each script load is an http round-trip request to your server. Loading can benefit some from client-side caching, but you still don't want your web-site's home page to have to load 50 separate modules the first time a user hits your home page just to get all your scripts loaded into the browser.
So, it would generally not be efficient in client-side code to import a script just for one function like isEven()
. This is why bundlers exist so that you can write the code in nice, modular, separately testable modules and then have the bundler go grab all the code that is needed for a particular client-side operation and collect it into one common script file that can then be loaded more efficiently into the client-side environment.
CodePudding user response:
try this
export { isEven }; // module exports a function:
module imports the function from is-even.mjs
import { isEven } from './is-even.mjs';
console.log(is-even(6));