Is Entry Point, ES6 Modules

Viewed 685

In node, in order to determine if I'm in the entry file, the file referenced directly by node, I can use __file__ === process.argv[1]. process.argv is an array containing the arguments I used to call the node script. Therefore, the first argv is usually node, the second is the file I'm using. This is useful if I'm creating a library and I want to know whether I'm calling the library directly, for example for testing. This would typically get minified out in a production build.

How can I do the same thing in a browser? Before ES6 modules, all JavaScript files were effectively global, meaning the <script> tags were all called directly by the HTML. However, now, with ES6 modules, it is possible to import another JavaScript file. How do I determine whether I am in a file directly sourced by the browser, with <script src="..."></script>, or whether I am in a file that was imported by another script?

This could be useful for react components, especially in libraries. If I am in the "entry" file, I can render myself in a tag that I choose, perhaps <main>. If not, I can assume I'm being imported by another component, which will presumably render itself or be rendered in some other way. The same concept applies to other component-based libraries, like angular 2+, aurelia, etc. For example,

import React from 'react';
import {render} from 'react-dom';

if(isEntryPoint()) {
    const main = document.querySelector('main');
    render(<App />, main);
}

function App() {
    return <div>Hello World!<div>;
}

So how do I find out if a file is directly referenced by the browser via <script src="..."></script>, or if it was imported by another JavaScript file? How should the isEntryPoint function look?

1 Answers

I don't believe there's any reasonable way for a browser-hosted module to know that it's been loaded directly rather than by another module. The unreasonable way I can think to do it is to compare the last segment of the URL in import.meta.url with the script elements present in the DOM and seeing if one matches.

I don't recommend it.

In fact, even then, if for some reason I have

<script type="module" src="./myfile.js"></script>
<script type="module" src="./your-library.js"></script>

and myfile.js does:

import /* stuff */ from "./your-library.js";

That would make your library think it was loaded directly when it fact it was loaded via myfile.js.

So I really don't recommend it. ;-)

Instead, you're probably better off providing your library (your-library.js) with a setup call the code using it can use, and an optional additional module (auto-your-library.js or whatever) that A) loads your library, and B) does the setup call. (If you want to provide the automatic setup feature at all.)

Note: import.meta is new in ES2020.

Related