How do I include a JavaScript file in another JavaScript file? Ask Question

How do I include a JavaScript file in another JavaScript file? Ask Question

How do I include a JavaScript file inside another JavaScript file, similar to @import in CSS?

ベストアンサー1

The old versions of JavaScript had no import, include, or require, so many different approaches to this problem have been developed.

But since 2015 (ES6), JavaScript has had the ES6 modules standard to import modules in Node.js, which is also supported by most modern browsers.

For compatibility with older browsers, build tools like Webpack and Rollup and/or transpilation tools like Babel can be used.

ES6 Modules

ECMAScript (ES6) modules have been supported in Node.js since v8.5, with the --experimental-modules flag, and since at least Node.js v13.8.0 without the flag. To enable "ESM" (vs. Node.js's previous CommonJS-style module system ["CJS"]) you either use "type": "module" in package.json or give the files the extension .mjs. (Similarly, modules written with Node.js's previous CJS module can be named .cjs if your default is ESM.)

Using package.json:

{
    "type": "module"
}

Then module.js:

export function hello() {
  return "Hello";
}

Then main.js:

import { hello } from './module.js';
let val = hello();  // val is "Hello";

Using .mjs, you'd have module.mjs:

export function hello() {
  return "Hello";
}

Then main.mjs:

import { hello } from './module.mjs';
let val = hello();  // val is "Hello";

ECMAScript modules in browsers

Browsers have had support for loading ECMAScript modules directly (no tools like Webpack required) since Safari 10.1, Chrome 61, Firefox 60, and Edge 16. Check the current support at caniuse. There is no need to use Node.js' .mjs extension; browsers completely ignore file extensions on modules/scripts.

<script type="module">
  import { hello } from './hello.mjs'; // Or the extension could be just `.js`
  hello('world');
</script>
// hello.mjs -- or the extension could be just `.js`
export function hello(text) {
  const div = document.createElement('div');
  div.textContent = `Hello ${text}`;
  document.body.appendChild(div);
}

Read more at https://jakearchibald.com/2017/es-modules-in-browsers/

Dynamic imports in browsers

Dynamic imports let the script load other scripts as needed:

<script type="module">
  import('hello.mjs').then(module => {
      module.hello('world');
    });
</script>

Read more at https://developers.google.com/web/updates/2017/11/dynamic-import

Node.js require

The older CJS module style, still widely used in Node.js, is the module.exports/require system.

// mymodule.js
module.exports = {
   hello: function() {
      return "Hello";
   }
}
// server.js
const myModule = require('./mymodule');
let val = myModule.hello(); // val is "Hello"   

There are other ways for JavaScript to include external JavaScript contents in browsers that do not require preprocessing.

AJAX Loading

You could load an additional script with an AJAX call and then use eval to run it. This is the most straightforward way, but it is limited to your domain because of the JavaScript sandbox security model. Using eval also opens the door to bugs, hacks and security issues.

Fetch Loading

Like Dynamic Imports you can load one or many scripts with a fetch call using promises to control order of execution for script dependencies using the Fetch Inject library:

fetchInject([
  'https://cdn.jsdelivr.net/momentjs/2.17.1/moment.min.js'
]).then(() => {
  console.log(`Finish in less than ${moment().endOf('year').fromNow(true)}`)
})

jQuery Loading

The jQuery library provides loading functionality in one line:

$.getScript("my_lovely_script.js", function() {
   alert("Script loaded but not necessarily executed.");
});

Dynamic Script Loading

You could add a script tag with the script URL into the HTML. To avoid the overhead of jQuery, this is an ideal solution.

The script can even reside on a different server. Furthermore, the browser evaluates the code. The <script> tag can be injected into either the web page <head>, or inserted just before the closing </body> tag.

Here is an example of how this could work:

function dynamicallyLoadScript(url) {
    var script = document.createElement("script");  // create a script DOM node
    script.src = url;  // set its src to the provided URL
   
    document.head.appendChild(script);  // add it to the end of the head section of the page (could change 'head' to 'body' to add it to the end of the body section instead)
}

<script>この関数は、ページのヘッダー セクションの末尾に新しいタグを追加します。src属性は、関数に最初のパラメーターとして渡される URL に設定されます。

これらの解決策は両方とも、JavaScript の狂気: 動的なスクリプトの読み込み

スクリプトが実行されたことを検出する

ここで、知っておくべき大きな問題があります。これを行うと、コードをリモートで読み込むことになります。最新の Web ブラウザは、パフォーマンスを向上させるためにすべてを非同期で読み込むため、ファイルを読み込み、現在のスクリプトを実行し続けます。(これは、jQuery メソッドと手動の動的スクリプト読み込みメソッドの両方に当てはまります。)

つまり、これらのトリックを直接使用すると、ロードを要求した次の行で新しくロードされたコードを使用できなくなります。まだロード中だからです。

たとえば、次のmy_lovely_script.js内容が含まれますMySuperObject

var js = document.createElement("script");

js.type = "text/javascript";
js.src = jsFilePath;

document.body.appendChild(js);

var s = new MySuperObject();

Error : MySuperObject is undefined

次に、 を押してページをリロードしますF5。すると、うまくいきます! 混乱します...

それでどうすればいいのでしょうか?

そうですね、私が提供したリンクで著者が提案しているハックを使用できます。要約すると、急いでいる人のために、スクリプトがロードされたときにイベントを使用してコールバック関数を実行します。したがって、リモート ライブラリを使用するすべてのコードをコールバック関数に配置できます。たとえば、次のようになります。

function loadScript(url, callback)
{
    // Adding the script tag to the head as suggested before
    var head = document.head;
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = url;

    // Then bind the event to the callback function.
    // There are several events for cross browser compatibility.
    script.onreadystatechange = callback;
    script.onload = callback;

    // Fire the loading
    head.appendChild(script);
}

次に、スクリプトがロードされた後に使用したいコードを記述します。ラムダ関数:

var myPrettyCode = function() {
   // Here, do whatever you want
};

次に、これをすべて実行します。

loadScript("my_lovely_script.js", myPrettyCode);

ブラウザや行が含まれているかどうかに応じて、スクリプトはDOMが読み込まれた後、または読み込まれる前に実行されることに注意してくださいscript.async = false;Javascriptの読み込み全般に関する素晴らしい記事これについて議論します。

ソースコードのマージ/前処理

この回答の冒頭で述べたように、多くの開発者はプロジェクトで Parcel、Webpack、Babel などのビルド/トランスパイル ツールを使用し、今後の JavaScript 構文の使用、古いブラウザーとの下位互換性の提供、ファイルの結合、縮小、コード分割などを可能にしています。

おすすめ記事