1. ホーム
  2. javascript

[解決済み] あるJavaScriptファイルを他のJavaScriptファイルにインクルードするにはどうすればよいですか?

2022-03-15 15:54:24

質問内容

JavaScriptには、次のようなものがありますか? @import CSS で、ある JavaScript ファイルを別の JavaScript ファイルの中に含めることができますか?

どのように解決するのですか?

古いバージョンのJavaScriptにはimport, include, requireがなかったため、この問題に対するさまざまなアプローチが開発されました。

しかし、2015年(ES6)以降、JavaScriptには ES6モジュール 規格に対応し、Node.jsのモジュールをインポートすることができます。 ほとんどのモダンブラウザ .

古いブラウザとの互換性を確保するために、以下のようなツールを構築します。 ウェブパック ロールアップ のようなトランスパイルツールや バベル を使用することができます。

ES6モジュール

ECMAScript (ES6) モジュールが Node.jsでサポートされている は、v8.5 以降で --experimental-modules フラグがあり、少なくとも Node.js v13.8.0 からはフラグ無しで使用できます。ESMを有効にするには(Node.jsの以前のCommonJSスタイルのモジュールシステム["CJS"]に対して)、次のどちらかを使用します。 "type": "module"package.json または、ファイルに拡張子 .mjs . (同様に、Node.jsの以前のCJSモジュールで書かれたモジュールは、その名前を .cjs デフォルトがESMの場合)

使用方法 package.json :

{
    "type": "module"
}

次に module.js :

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

次に main.js :

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

使用方法 .mjs であれば module.mjs :

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

次に main.mjs :

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

ブラウザのECMAScriptモジュール

ブラウザは ECMAScript モジュールを直接読み込むことをサポートしていました (Webpack のようなツールは必要ありません)。 以来 Safari 10.1、Chrome 61、Firefox 60、Edge 16。現在のサポート状況は以下のサイトでご確認ください。 カニース . Node.js' を使用する必要はありません。 .mjs 拡張子です。ブラウザはモジュールやスクリプトのファイル拡張子を完全に無視します。

<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);
}

詳しくはこちら https://jakearchibald.com/2017/es-modules-in-browsers/

ブラウザでの動的インポート

動的インポートにより、スクリプトは必要に応じて他のスクリプトを読み込むことができます。

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

詳しくはこちら https://developers.google.com/web/updates/2017/11/dynamic-import

Node.jsの要求

Node.jsで今でも広く使われている古いCJSモジュールのスタイルは module.exports / require システムで使用されます。

// mymodule.js
module.exports = {
   hello: function() {
      return "Hello";
   }
}

// server.js
const myModule = require('./mymodule');
let val = myModule.hello(); // val is "Hello"   

JavaScriptがブラウザに外部のJavaScriptコンテンツを取り込むには、前処理を必要としない他の方法があります。

AJAXローディング

AJAX呼び出しで追加のスクリプトをロードし、その後に eval を実行します。これは最も簡単な方法ですが、JavaScriptのサンドボックスのセキュリティモデルのため、自分のドメインに限定されます。使用方法 eval また、バグやハッキング、セキュリティの問題への扉を開いてしまいます。

フェッチローディング

ダイナミックインポートと同様、1つまたは複数のスクリプトを fetch を使用してスクリプトの依存関係の実行順序を制御するために、プロミスを使用して呼び出します。 フェッチ・インジェクト ライブラリを使用します。

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の読み込み

jQuery ライブラリは、ローディング機能を提供します。 一行で :

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

動的なスクリプトの読み込み

HTMLの中にスクリプトのURLを記載したscriptタグを追加すればよい。jQueryのオーバーヘッドを避けるために、これは理想的な解決策です。

スクリプトは別のサーバーに置くこともできます。さらに、ブラウザがコードを評価する。そのため <script> タグは、ウェブページに注入することができます。 <head> の前に挿入するか、あるいは </body> タグを使用します。

以下はその例です。

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> タグをページのheadセクションの最後に追加します。 src 属性には、この関数に最初のパラメータとして渡される URL が設定されます。

この2つの解決策については、図解入りで解説しています。 JavaScriptの狂気。動的なスクリプトの読み込み .

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

さて、ここで知っておかなければならない大問題があります。それをやると、暗に リモートでコードを読み込む . 最近のウェブブラウザは、パフォーマンスを向上させるためにすべてを非同期に読み込むので、ファイルを読み込んで現在のスクリプトを実行し続けることになります。(これは、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構文の使用、古いブラウザの後方互換性の提供、ファイルの結合、最小化、コード分割などを行うことができます。