web-dev-qa-db-ja.com

JavaScriptファイルを別のJavaScriptファイルに含める方法

他のJavaScriptファイルの中にJavaScriptファイルを含めることを可能にするCSSの@importのようなJavaScriptの何かがありますか?

4635
Alec Smart

JavaScriptの旧バージョンにはインポート、インクルード、または必要性がなかったため、この問題に対するさまざまなアプローチが開発されています。

しかし2015年(ES6)以来、JavaScriptはNode.jsにモジュールをインポートするための ES6モジュール 標準を持っています。これは 最近のブラウザー でもサポートされています。

古いブラウザとの互換性のために、 build および/または transpilation ツールを使用できます。

ES6モジュール

ECMAScript(ES6)モジュールは、v8.5からNode.jsで--experimental-modulesフラグ付きでサポートされています。関係するすべてのファイルは.mjs拡張子を持つ必要があります。

// module.mjs
export function hello() {
  return "Hello";
}
// main.mjs
import { hello } from 'module'; // or './module'
let val = hello();  // val is "Hello";

ブラウザのECMAScriptモジュール

ブラウザはECMAScriptモジュールを直接ロードすることをサポートしています(Webpackのようなツールは必要ありません) 以降 Safari 10.1、Chrome 61、Firefox 60、およびEdge 16。現在のサポートを確認する caniuse

<script type="module">
  import { hello } from './hello.mjs';
  hello('world');
</script>
// hello.mjs
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でもまだ広く使用されているモジュールのインポートの古いスタイルは、 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を使用すると、バグ、ハック、セキュリティ問題への扉も開かれます。

読み込み中

動的インポートと同様に、 Fetch Inject ライブラリを使用してスクリプト依存関係の実行順序を制御するためにpromiseを使用してfetch呼び出しで1つまたは複数のスクリプトをロードできます。

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 ライブラリはロード機能を提供します 1行で

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

動的スクリプトロード

スクリプトURLを含むスクリプトタグをHTMLに追加できます。 jQueryのオーバーヘッドを回避するために、これは理想的な解決策です。

スクリプトは別のサーバーに配置することもできます。さらに、ブラウザはコードを評価します。 <script>タグは、Webページの<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)
}

この関数は、ページのheadセクションの最後に新しい<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);

スクリプトは、ブラウザの種類やscript.async = false;の行が含まれているかどうかによって、DOMのロード後または実行前に実行されることがあります。これについて議論している Javascriptのロード全般に関する素晴らしい記事 があります。

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

この答えの冒頭で述べたように、多くの開発者は彼らのプロジェクトでParcel、Webpack、またはBabelのようなビルド/変換ツールを使用します。コード分​​割などを行う.

4044
e-satis

誰かがもっと高度なものを探しているなら、 RequireJS を試してみてください。依存関係管理、同時実行性の向上、重複の回避(つまり、スクリプトを複数回取得する)などの追加の利点が得られます。

JavaScriptファイルを「モジュール」で記述してから、それらを他のスクリプトの依存関係として参照できます。あるいは、RequireJSを単純な「このスクリプトを入手する」ソリューションとして使用することもできます。

例:

依存関係をモジュールとして定義します。

some-dependency.js

define(['lib/dependency1', 'lib/dependency2'], function (d1, d2) {

     //Your actual script goes here.   
     //The dependent scripts will be fetched if necessary.

     return libraryObject;  //For example, jQuery object
});

implementation.js は、 some-dependency.js に依存する "メイン" JavaScriptファイルです。

require(['some-dependency'], function(dependency) {

    //Your script goes here
    //some-dependency.js is fetched.   
    //Then your script is executed
});

GitHub READMEからの抜粋:

RequireJSは普通のJavaScriptファイルともっと定義されたモジュールをロードします。 Webワーカーを含むブラウザ内での使用に最適化されていますが、RhinoやNodeなどの他のJavaScript環境でも使用できます。これは非同期モジュールAPIを実装しています。

RequireJSはプレーンなスクリプトタグを使ってモジュール/ファイルをロードするので、簡単にデバッグできるようにする必要があります。それは単に既存の JavaScriptファイルをロードするために使用することができるので、 あなたはあなたのJavaScriptファイルを書き直す必要なしにあなたの既存のプロジェクトにそれを追加することができます。

... 

533
John Strickler

実際には、isJavaScriptファイルを読み込む方法notなので、新しく読み込んだファイルを読み込んだ直後に、そのファイルに含まれている関数を使用することができ、すべてのブラウザーで機能すると思います。

ページの<head>要素でjQuery.append()を使用する必要があります。

$("head").append('<script type="text/javascript" src="' + script + '"></script>');

ただし、この方法にも問題があります。インポートされたJavaScriptファイルでエラーが発生した場合、 Firebug (およびFirefoxエラーコンソールと Chrome Developer Tools も)が報告しますFirebugを使用してJavaScriptエラーを大幅に追跡する場合、これは大きな問題です(私はそうします)。 Firebugは、何らかの理由で新しくロードされたファイルを単に知らないため、そのファイルでエラーが発生した場合、メインの HTML ファイルで発生したことを報告し、見つけるのに苦労しますエラーの本当の理由を突き止めてください。

ただし、それが問題にならない場合は、このメソッドが機能するはずです。

このメソッドを使用する$。import_js()というjQueryプラグインを実際に作成しました。

(function($)
{
    /*
     * $.import_js() helper (for JavaScript importing within JavaScript code).
     */
    var import_js_imported = [];

    $.extend(true,
    {
        import_js : function(script)
        {
            var found = false;
            for (var i = 0; i < import_js_imported.length; i++)
                if (import_js_imported[i] == script) {
                    found = true;
                    break;
                }

            if (found == false) {
                $("head").append('<script type="text/javascript" src="' + script + '"></script>');
                import_js_imported.Push(script);
            }
        }
    });

})(jQuery);

したがって、JavaScriptをインポートするために必要なことは次のとおりです。

$.import_js('/path_to_project/scripts/somefunctions.js');

で、このための簡単なテストも行いました。

メインHTMLにmain.jsファイルが含まれており、main.jsのスクリプトは$.import_js()を使用して、この関数を定義するincluded.jsという追加ファイルをインポートします。

function hello()
{
    alert("Hello world!");
}

そして、included.jsをインクルードした直後に、hello()関数が呼び出され、アラートを受け取ります。

(この回答は、e-satisのコメントに対する回答です)。

181
Kipras

私の考えでは、もう1つの方法は、<script>タグを使用するのではなく、同期Ajaxリクエストを作成することです。これは Node.js が扱う方法でもあります。

これがjQueryを使った例です。

function require(script) {
    $.ajax({
        url: script,
        dataType: "script",
        async: false,           // <-- This is the key
        success: function () {
            // all good...
        },
        error: function () {
            throw new Error("Could not load script " + script);
        }
    });
}

通常はインクルードを使用するのと同じように、コードで使用できます。

require("/scripts/subscript.js");

次の行で必要なスクリプトから関数を呼び出せるようにします。

subscript.doSomethingCool(); 
138
Ariel

あなたには良い知らせがあります。すぐにあなたは簡単にJavaScriptコードをロードすることができるでしょう。これはJavaScriptコードのモジュールをインポートする標準的な方法になり、コアJavaScript自体の一部になります。 

ファイルimport cond from 'cond.js';からcondという名前のマクロをロードするには、単にcond.jsを記述するだけです。

ですから、JavaScriptフレームワークに頼る必要も、明示的に Ajax 呼び出しを行う必要もありません。

参照する:

90
Imdad

JavaScriptタグを動的に生成し、それを他のJavaScriptコード内からHTMLドキュメントに追加することは可能です。これにより、ターゲットのJavaScriptファイルがロードされます。

function includeJs(jsFilePath) {
    var js = document.createElement("script");

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

    document.body.appendChild(js);
}

includeJs("/path/to/some/file.js");
79

ステートメント import はECMAScript 6にあります。

構文

import name from "module-name";
import { member } from "module-name";
import { member as alias } from "module-name";
import { member1 , member2 } from "module-name";
import { member1 , member2 as alias2 , [...] } from "module-name";
import name , { member [ , [...] ] } from "module-name";
import "module-name" as name;
62
draupnie

多分あなたは私がこのページで見つけたこの機能を使用することができますどのように私はJavaScriptファイルにJavaScriptファイルを含めるのですか?

function include(filename)
{
    var head = document.getElementsByTagName('head')[0];

    var script = document.createElement('script');
    script.src = filename;
    script.type = 'text/javascript';

    head.appendChild(script)
}

これは 同期 バージョン jQueryなし :です。

function myRequire( url ) {
    var ajax = new XMLHttpRequest();
    ajax.open( 'GET', url, false ); // <-- the 'false' makes it synchronous
    ajax.onreadystatechange = function () {
        var script = ajax.response || ajax.responseText;
        if (ajax.readyState === 4) {
            switch( ajax.status) {
                case 200:
                    eval.apply( window, [script] );
                    console.log("script loaded: ", url);
                    break;
                default:
                    console.log("ERROR: script not loaded: ", url);
            }
        }
    };
    ajax.send(null);
}

このクロスドメインを機能させるには、サーバーは応答にallow-Originヘッダーを設定する必要があります。

47
heinob

私はちょうどこのJavaScriptコードを書いた( Prototype for _ dom _ 操作を使って):

var require = (function() {
    var _required = {};
    return (function(url, callback) {
        if (typeof url == 'object') {
            // We've (hopefully) got an array: time to chain!
            if (url.length > 1) {
                // Load the nth file as soon as everything up to the
                // n-1th one is done.
                require(url.slice(0, url.length - 1), function() {
                    require(url[url.length - 1], callback);
                });
            } else if (url.length == 1) {
                require(url[0], callback);
            }
            return;
        }
        if (typeof _required[url] == 'undefined') {
            // Haven't loaded this URL yet; gogogo!
            _required[url] = [];

            var script = new Element('script', {
                src: url,
                type: 'text/javascript'
            });
            script.observe('load', function() {
                console.log("script " + url + " loaded.");
                _required[url].each(function(cb) {
                    cb.call(); // TODO: does this execute in the right context?
                });
                _required[url] = true;
            });

            $$('head')[0].insert(script);
        } else if (typeof _required[url] == 'boolean') {
            // We already loaded the thing, so go ahead.
            if (callback) {
                callback.call();
            }
            return;
        }

        if (callback) {
            _required[url].Push(callback);
        }
    });
})();

使用法:

<script src="prototype.js"></script>
<script src="require.js"></script>
<script>
    require(['foo.js','bar.js'], function () {
        /* Use foo.js and bar.js here */
    });
</script>

要旨: http://Gist.github.com/284442

43
nornagon

これがFacebookが彼らのいたるところにあるLikeボタンのためにどのようにそれをするかの一般化されたバージョンです:

<script>
  var firstScript = document.getElementsByTagName('script')[0],
      js = document.createElement('script');
  js.src = 'https://cdnjs.cloudflare.com/ajax/libs/Snowstorm/20131208/snowstorm-min.js';
  js.onload = function () {
    // do stuff with your dynamically loaded script
    snowStorm.snowColor = '#99ccff';
  };
  firstScript.parentNode.insertBefore(js, firstScript);
</script>

それがFacebookのために働くならば、それはあなたのために働くでしょう。

scriptheadの代わりに最初のbody要素を探すのは、ブラウザによっては見つからない場合は作成されないためですが、script要素があることが保証されています - これ。詳しくは http://www.jspatterns.com/the-ridiculous-case-of-adding-a-script-element/ をご覧ください。

36
Dan Dascalescu

純粋なJavaScriptを使用したい場合は、document.writeを使用できます。

document.write('<script src="myscript.js" type="text/javascript"></script>');

JQueryライブラリを使用している場合は、$.getScriptメソッドを使用できます。

$.getScript("another_script.js");
31
Venu immadi

_ php _ を使用してスクリプトを組み立てることもできます。

ファイルmain.js.php

<?php
    header('Content-type:text/javascript; charset=utf-8');
    include_once("foo.js.php");
    include_once("bar.js.php");
?>

// Main JavaScript code goes here
24
Calmarius

ここに示されている解決策のほとんどは動的負荷を意味します。代わりに、依存しているすべてのファイルを単一の出力ファイルにまとめるコンパイラを探していました。 Less / Sass プリプロセッサはCSSの@import at-ruleを扱います。私はこの種の適当なものを見つけることができなかったので、私は問題を解決する簡単な道具を書きました。

そのため、ここにコンパイラ https://github.com/dsheiko/jsic があります。これは$import("file-path")を要求されたファイルの内容で安全に置き換えます。これは対応する Grunt プラグインです: https://github.com/dsheiko/grunt-jsic

JQueryマスターブランチでは、アトミックソースファイルをintro.jsで始まりouttro.jsで終わる単一のファイルに単純に連結します。ソースコード設計に柔軟性がないため、これは私には適していません。 jsicとどのように連携するのかを調べてください。

src/main.js

var foo = $import("./Form/Input/Tel");

src/Form/Input/Tel.js

function() {
    return {
          prop: "",
          method: function(){}
    }
}

これでコンパイラを実行できます。

node jsic.js src/main.js build/mail.js

そして、結合ファイルを入手してください

build/main.js

var foo = function() {
    return {
          prop: "",
          method: function(){}
    }
};
24
Dmitry Sheiko

JavaScriptファイルをロードする意図が インポートされた/インクルードされたファイルからの関数を使用すること である場合、グローバルオブジェクトを定義し、その関数をオブジェクト項目として設定することもできます。例えば:

global.js

A = {};

file1.js

A.func1 = function() {
  console.log("func1");
}

file2.js

A.func2 = function() {
  console.log("func2");
}

main.js

A.func1();
A.func2();

HTMLファイルにスクリプトを含める場合は、注意が必要です。順序は以下のようになります。

<head>
  <script type="text/javascript" src="global.js"></script>
  <script type="text/javascript" src="file1.js"></script>
  <script type="text/javascript" src="file2.js"></script>
  <script type="text/javascript" src="main.js"></script>
</head>
20
Adem İlhan

これはする必要があります:

xhr = new XMLHttpRequest();
xhr.open("GET", "/soap/ajax/11.0/connection.js", false);
xhr.send();
eval(xhr.responseText);
18
tggagne

実行時に含めるのではなく、スクリプトを使用してアップロード前に連結します。

Sprockets を使用します(他に存在するかどうかはわかりません)。 JavaScriptコードを別々のファイルに作成し、Sprocketsエンジンによってインクルードとして処理されるコメントを含めます。開発のためにはファイルを順番にインクルードすることができます、そしてプロダクションのためにそれらをマージするために...

また見なさい:

17
JMawer

Web Workers を使用していて、ワーカーの範囲内に追加のスクリプトを含めたい場合は、headタグへのスクリプトの追加などに関する他の回答は役に立ちません。

幸いなことに、 Webワーカーには独自のimportScripts関数 があります。これは、Webワーカーのスコープ内にあるグローバル関数で、ブラウザ自体に固有のものです。 は仕様の一部です

あるいは、 あなたの質問に対する2番目に高い投票の答えとしてRequireJS はWebワーカー内にスクリプトを含めることも処理できます(おそらくimportScripts自身を呼び出しますが、他の便利な機能もあります)。

14
Turnerj

私は簡単な問題を抱えていましたが、この質問に対する回答に困惑しました。

あるJavaScriptファイル(myvariables.js)で定義されている変数(myVar1)を別のJavaScriptファイル(main.js)で使用する必要がありました。

このために私は以下のようにしました:

HTMLファイル内のJavaScriptコードを正しい順序で、最初はmyvariables.js、次にmain.jsの順にロードしました。

<html>
    <body onload="bodyReady();" >

        <script src="myvariables.js" > </script>
        <script src="main.js" > </script>

        <!-- Some other code -->
    </body>
</html>

ファイル:myvariables.js

var myVar1 = "I am variable from myvariables.js";

ファイル:main.js

// ...
function bodyReady() {
    // ...
    alert (myVar1);    // This shows "I am variable from myvariables.js", which I needed
    // ...
}
// ...

ご覧のとおり、あるJavaScriptファイル内の変数を別のJavaScriptファイル内で使用していましたが、別のJavaScriptファイルに変数を含める必要はありませんでした。最初のJavaScriptファイルが2番目のJavaScriptファイルの前にロードされ、最初のJavaScriptファイルの変数に2番目のJavaScriptファイルから自動的にアクセスできるようにする必要があります。

これは私の日を救った。これが役に立つことを願っています。

13

CSS風のJavaScriptインポートを実現するための@import構文は、Mixtureなどのツールを使用して、特別な.mixファイルタイプで使用できます( here を参照)。私は知りませんが、アプリケーションが前述の方法の1つを単純に使用していると思います。 

.mixファイルに関するMixtureドキュメントから: 

ミックスファイルは、単に.mixを持つ.jsファイルまたは.cssファイルです。ファイル名に。 ミックスファイルは、通常のスタイルまたはスクリプトファイルの機能を単純に拡張したもので、インポートと結合を可能にします。

これは、複数の.mixファイルを1つにまとめた.jsファイルの例です。

// scripts-global.mix.js
// Plugins - Global

@import "global-plugins/headroom.js";
@import "global-plugins/retina-1.1.0.js";
@import "global-plugins/isotope.js";
@import "global-plugins/jquery.fitvids.js";

Mixtureはこれをscripts-global.jsおよび縮小版(scripts-global.min.js)として出力します。

注意:フロントエンド開発ツールとして使用する以外、私はMixtureと提携していません。 .mix JavaScriptファイルが(Mixtureボイラープレートの1つで)実際に動作しているのを見て、少し混乱していたときにこの質問に遭遇しました(「あなたはこれを行うことができますか?」。それから私はそれがアプリケーション特有のファイルタイプであることに気づきました(やや残念、同意しました)。それにもかかわらず、知識が他の人に役立つかもしれないと考えました。

_ update _ :混合は 現在無料 (オフライン)です。

_ update _ :混合は中止されました。 古い混合リリース はまだ利用可能です

12
Isaac Gregson

私のいつもの方法は:

var require = function (src, cb) {
    cb = cb || function () {};

    var newScriptTag = document.createElement('script'),
        firstScriptTag = document.getElementsByTagName('script')[0];
    newScriptTag.src = src;
    newScriptTag.async = true;
    newScriptTag.onload = newScriptTag.onreadystatechange = function () {
        (!this.readyState || this.readyState === 'loaded' || this.readyState === 'complete') && (cb());
    };
    firstScriptTag.parentNode.insertBefore(newScriptTag, firstScriptTag);
}

それは素晴らしい仕事と私のためにページのリロードを使用しません。私はAJAXメソッド(他の答えの1つ)を試しましたが、それは私にとってはうまく動作しないようです。

好奇心旺盛な人のためにコードがどのように機能するかを説明します。基本的に、URLの新しいスクリプトタグ(最初のタグの後)を作成します。これを非同期モードに設定して残りのコードをブロックしないようにしますが、readyState(ロードされるコンテンツの状態)が 'loaded'に変わったときにコールバックを呼び出します。

11

私はJavaScriptでモジュールスクリプトをインポート/インクルードする仕事を自動化する簡単なモジュールを書きました。コードの詳細な説明については、ブログ記事JavaScript require/import/includeモジュールを参照してください。

// ----- USAGE -----

require('ivar.util.string');
require('ivar.net.*');
require('ivar/util/array.js');
require('http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js');

ready(function(){
    //Do something when required scripts are loaded
});

    //--------------------

var _rmod = _rmod || {}; //Require module namespace
_rmod.LOADED = false;
_rmod.on_ready_fn_stack = [];
_rmod.libpath = '';
_rmod.imported = {};
_rmod.loading = {
    scripts: {},
    length: 0
};

_rmod.findScriptPath = function(script_name) {
    var script_elems = document.getElementsByTagName('script');
    for (var i = 0; i < script_elems.length; i++) {
        if (script_elems[i].src.endsWith(script_name)) {
            var href = window.location.href;
            href = href.substring(0, href.lastIndexOf('/'));
            var url = script_elems[i].src.substring(0, script_elems[i].length - script_name.length);
            return url.substring(href.length+1, url.length);
        }
    }
    return '';
};

_rmod.libpath = _rmod.findScriptPath('script.js'); //Path of your main script used to mark
                                                   //the root directory of your library, any library.


_rmod.injectScript = function(script_name, uri, callback, prepare) {

    if(!prepare)
        prepare(script_name, uri);

    var script_elem = document.createElement('script');
    script_elem.type = 'text/javascript';
    script_elem.title = script_name;
    script_elem.src = uri;
    script_elem.async = true;
    script_elem.defer = false;

    if(!callback)
        script_elem.onload = function() {
            callback(script_name, uri);
        };
    document.getElementsByTagName('head')[0].appendChild(script_elem);
};

_rmod.requirePrepare = function(script_name, uri) {
    _rmod.loading.scripts[script_name] = uri;
    _rmod.loading.length++;
};

_rmod.requireCallback = function(script_name, uri) {
    _rmod.loading.length--;
    delete _rmod.loading.scripts[script_name];
    _rmod.imported[script_name] = uri;

    if(_rmod.loading.length == 0)
        _rmod.onReady();
};

_rmod.onReady = function() {
    if (!_rmod.LOADED) {
        for (var i = 0; i < _rmod.on_ready_fn_stack.length; i++){
            _rmod.on_ready_fn_stack[i]();
        });
        _rmod.LOADED = true;
    }
};

_.rmod = namespaceToUri = function(script_name, url) {
    var np = script_name.split('.');
    if (np.getLast() === '*') {
        np.pop();
        np.Push('_all');
    }

    if(!url)
        url = '';

    script_name = np.join('.');
    return  url + np.join('/')+'.js';
};

//You can rename based on your liking. I chose require, but it
//can be called include or anything else that is easy for you
//to remember or write, except "import", because it is reserved
//for future use.
var require = function(script_name) {
    var uri = '';
    if (script_name.indexOf('/') > -1) {
        uri = script_name;
        var lastSlash = uri.lastIndexOf('/');
        script_name = uri.substring(lastSlash+1, uri.length);
    } 
    else {
        uri = _rmod.namespaceToUri(script_name, ivar._private.libpath);
    }

    if (!_rmod.loading.scripts.hasOwnProperty(script_name)
     && !_rmod.imported.hasOwnProperty(script_name)) {
        _rmod.injectScript(script_name, uri,
            _rmod.requireCallback,
                _rmod.requirePrepare);
    }
};

var ready = function(fn) {
    _rmod.on_ready_fn_stack.Push(fn);
};
11
stamat
var js = document.createElement("script");

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

document.body.appendChild(js);
10
Sam4Code

現代の言語では 

function loadJs( url ){
  return new Promise( resolve => {
    const script = document.createElement( "script" );
    script.src = url;
    script.onload = resolve;
    document.head.appendChild( script );
  });
}
10
Dmitry Sheiko

Head.js もあります。対処するのはとても簡単です。

head.load("js/jquery.min.js",
          "js/jquery.someplugin.js",
          "js/jquery.someplugin.css", function() {
  alert("Everything is ok!");
});

ご覧のとおり、これはRequire.jsよりも簡単で、jQueryの$.getScriptメソッドと同じくらい便利です。また、条件付きロード、機能の検出、 はるかに多くの などの高度な機能もあります。

9
Ale

私は便利なJavaScriptプラグインのコレクションを維持する簡単な方法を探していたので、私はこの質問に来ました。ここでいくつかの解決策を見た後、私はこれを思い付きました:

  1. "plugins.js"(またはextensions.jsまたはあなたが持っているもの)というファイルを設定します。その1つのマスターファイルと一緒にあなたのプラグインファイルを保管してください。

  2. plugins.jsは "pluginNames []"と呼ばれる配列を持ち、それをeach()に対して繰り返し、そして各プラグインの先頭にタグを追加します

    //プラグインファイルを追加または削除したときに更新される配列を設定する var pluginNames = ["lettering"、 "fittext"、 "butterjam"など]; //スクリプトタグ1つ各プラグイン $ .each(pluginNames、function(){ $( 'head')。append( ''); });

  3. 頭の中の1つのファイルだけを手動で呼び出します。
    <script src="js/plugins/plugins.js"></script>

すべてのプラグインが本来の方法でheadタグにドロップされていたとしても、ページをクリックしたり更新したりしたときにブラウザによって常に実行されているわけではありません。

スクリプトタグをPHPインクルードに記述するだけのほうが信頼性が高いことがわかりました。あなたは一度だけそれを書く必要があり、それはJavaScriptを使ってプラグインを呼び出すのと同じくらい多くの仕事です。

9
rgb_life

このスクリプトは、他の<script>タグの先頭にJavaScriptファイルを追加します。

(function () {
    var li = document.createElement('script'); 
    li.type = 'text/javascript'; 
    li.src= "http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"; 
    li.async=true; 
    var s = document.getElementsByTagName('script')[0]; 
    s.parentNode.insertBefore(li, s);
})();
9
Vicky Gonsalves

この質問に対する多くの潜在的な答えがあります。私の答えは明らかにそれらの数に基づいています。これは私がすべての答えを読んだ後に終わったものです。

$.getScriptやロード完了時にコールバックを必要とする他のソリューションの問題は、それを使用して互いに依存している複数のファイルがある場合、すべてのスクリプトがいつロードされたかを知る方法がもうないことです。複数のファイルにネストされています。

例:

file3.js

var f3obj = "file3";

// Define other stuff

file2.js:

var f2obj = "file2";
$.getScript("file3.js", function(){

    alert(f3obj);

    // Use anything defined in file3.
});

file1.js:

$.getScript("file2.js", function(){
    alert(f3obj); //This will probably fail because file3 is only guaranteed to have loaded inside the callback in file2.
    alert(f2obj);

    // Use anything defined in the loaded script...
});

Ajaxを指定して同期的に実行することも、 XMLHttpRequest を使用することもできますが、現在の傾向では同期要求は推奨されないため、現在または将来完全なブラウザサポートが得られない場合があります。

$.whenを使って据え置きオブジェクトの配列をチェックすることもできますが、今度はすべてのファイルでこれを行っているので、コールバックの実行時ではなく$.whenが実行されるとすぐにfile2がロードされたと見なされます。ロードされます。これにはまだ同じ問題があります。

私は前進ではなく後退することにしました。 document.writelnありがとうございます。私はそれがタブーであることを知っています、しかしそれが正しく使用される限りこれはうまくいきます。簡単にデバッグできるコード、DOMに正しく表示されるコード、そして依存関係が正しくロードされる順序を保証できるコードが得られます。

あなたはもちろん$( "body")。append()を使うことができますが、それからもう正しくデバッグすることはできません。

注:ページの読み込み中にのみこれを使用する必要があります。それ以外の場合は空白の画面が表示されます。言い換えれば、 は常にこれをdocument.ready の前に配置します。クリックイベントなどでページが読み込まれた後は、これを使用したテストは行っていませんが、失敗することは間違いありません。

私はjQueryを拡張するという考えが好きでしたが、明らかにそうする必要はありません。

document.writelnを呼び出す前に、すべてのスクリプト要素を評価して、スクリプトがまだロードされていないことを確認します。

document.readyイベントが実行されるまで、スクリプトは完全には実行されません。 (私はdocument.readyの使用は必須ではないことを知っていますが、多くの人がそれを使用しています、そしてこれを取り扱うことは安全装置です。)

追加ファイルがロードされると、document.readyコールバックは間違った順序で実行されます。スクリプトが実際にロードされたときにこれに対処するために、それをインポートしたスクリプトはそれ自身を再インポートして実行を停止します。これにより、元のファイルはdocument.readyコールバックをインポートしたスクリプトから実行された後に実行します。

このアプローチの代わりにjQueryのreadyListを修正しようと試みることができます、しかしこれはより悪い解決策のように見えました。

溶液:

$.extend(true,
{
    import_js : function(scriptpath, reAddLast)
    {
        if (typeof reAddLast === "undefined" || reAddLast === null)
        {
            reAddLast = true; // Default this value to true. It is not used by the end user, only to facilitate recursion correctly.
        }

        var found = false;
        if (reAddLast == true) // If we are re-adding the originating script we do not care if it has already been added.
        {
            found = $('script').filter(function () {
                return ($(this).attr('src') == scriptpath);
            }).length != 0; // jQuery to check if the script already exists. (replace it with straight JavaScript if you don't like jQuery.
        }

        if (found == false) {

            var callingScriptPath = $('script').last().attr("src"); // Get the script that is currently loading. Again this creates a limitation where this should not be used in a button, and only before document.ready.

            document.writeln("<script type='text/javascript' src='" + scriptpath + "'></script>"); // Add the script to the document using writeln

            if (reAddLast)
            {
                $.import_js(callingScriptPath, false); // Call itself with the originating script to fix the order.
                throw 'Readding script to correct order: ' + scriptpath + ' < ' + callingScriptPath; // This halts execution of the originating script since it is getting reloaded. If you put a try / catch around the call to $.import_js you results will vary.
            }
            return true;
        }
        return false;
    }
});

使用法:

ファイル3:

var f3obj = "file3";

// Define other stuff
$(function(){
    f3obj = "file3docready";
});

ファイル2:

$.import_js('js/file3.js');
var f2obj = "file2";
$(function(){
    f2obj = "file2docready";
});

ファイル1:

$.import_js('js/file2.js');

// Use objects from file2 or file3
alert(f3obj); // "file3"
alert(f2obj); // "file2"

$(function(){
    // Use objects from file2 or file3 some more.
    alert(f3obj); //"file3docready"
    alert(f2obj); //"file2docready"
});
8

JavaScriptファイルをインクルードするためにC#/ Javaに似た言葉遣いを使用できるようにする関数を作成しました。 another / JavaScriptファイルの内部からでも少しテストしたところ、うまくいったようです。それはjQueryを必要としますが、最後には少し「魔法」が必要です。

このコードを私のスクリプトディレクトリのルートにあるファイルに入れました(私はglobal.jsと名前を付けましたが、あなたは好きなものを使うことができます。これは基本的な使い方以外にはほとんどテストされていないので、私のやり方には問題があるかもしれないし、ないかもしれません;あなた自身の責任で使ってくださいyadda yadda

/**
* @fileoverview This file stores global functions that are required by other libraries.
*/

if (typeof(jQuery) === 'undefined') {
    throw 'jQuery is required.';
}

/** Defines the base script directory that all .js files are assumed to be organized under. */
var BASE_DIR = 'js/';

/**
* Loads the specified file, outputting it to the <head> HTMLElement.
*
* This method mimics the use of using in C# or import in Java, allowing
* JavaScript files to "load" other JavaScript files that they depend on
* using a familiar syntax.
*
* This method assumes all scripts are under a directory at the root and will
* append the .js file extension automatically.
*
* @param {string} file A file path to load using C#/Java "dot" syntax.
*
* Example Usage:
* imports('core.utils.extensions');
* This will output: <script type="text/javascript" src="/js/core/utils/extensions.js"></script>
*/
function imports(file) {
    var fileName = file.substr(file.lastIndexOf('.') + 1, file.length);

    // Convert PascalCase name to underscore_separated_name
    var regex = new RegExp(/([A-Z])/g);
    if (regex.test(fileName)) {
        var separated = fileName.replace(regex, ",$1").replace(',', '');
        fileName = separated.replace(/[,]/g, '_');
    }

    // Remove the original JavaScript file name to replace with underscore version
    file = file.substr(0, file.lastIndexOf('.'));

    // Convert the dot syntax to directory syntax to actually load the file
    if (file.indexOf('.') > 0) {
        file = file.replace(/[.]/g, '/');
    }

    var src = BASE_DIR + file + '/' + fileName.toLowerCase() + '.js';
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = src;

    $('head').find('script:last').append(script);
}
7
Wayne Molina

これらの答えは素晴らしいですが、スクリプトのロードが存在してからずっと続いている単純な「解決策」があり、それはほとんどの人の使用例の99.999%をカバーするでしょう。必要なスクリプトを必要とするスクリプトの前に含めるだけです。ほとんどのプロジェクトでは、どのスクリプトがどの順序で必要かを判断するのに時間はかかりません。

<!DOCTYPE HTML>
<html>
    <head>
        <script src="script1.js"></script>
        <script src="script2.js"></script>
    </head>
    <body></body>
</html>

Script2がscript1を必要とする場合、これは本当にこのようなことをするための絶対に最も簡単な方法です。ほとんど明白な最も単純な答えがほとんどすべての場合に当てはまるので、だれもこれを思い付かなかったことに私は非常に驚いています。

6
KthProg

Javascriptでモジュールを実装するにはいくつかの方法があります。これが最も人気のある2つの方法です。

ES6モジュール

ブラウザはまだこのモジュール方式をサポートしていないので、この構文を使用するには、webpackのようなバンドラーを使用する必要があります。とにかくバンドラーを使うほうがよいでしょう。なぜならこれはあなたの異なるファイルの全てを一つの(あるいはカップルに関連した)ファイルにまとめることができるからです。各HTTP要求には付随するオーバーヘッドがあるため、これによりサーバーからクライアントへのファイルの配信が早くなります。したがって、HTTP要求全体を減らすことで、パフォーマンスが向上します。 ES6モジュールの例はここにあります: 

// main.js file

export function add (a, b) {
  return a + b;
}

export default function multiply (a, b) {
  return a * b;
}


// test.js file

import {add}, multiply from './main';   // for named exports between curly braces {export1, export2}
                                        // for default exports without {}

console.log(multiply(2, 2));  // logs 4

console.log(add(1, 2));  // logs 3

CommonJS (NodeJSで使用されます)

この調整システムはNodeJSで使用されています。あなたは基本的にあなたのエクスポートをmodule.exportsと呼ばれるオブジェクトに追加します。それからrequire('modulePath')を通してこのオブジェクトにアクセスすることができます。ここで重要なのは、これらのモジュールがキャッシュされていることを認識することです。そのため、あるモジュールを2回require()すると、作成済みのモジュールが返されます。

// main.js file

function add (a, b) {
  return a + b;
}

module.exports = add;  // here we add our add function to the exports object


// test.js file

const add = require('./main'); 

console.log(add(1,2));  // logs 3
6

HTMLインポートを使用した回避策browser(Node.jsではない)の場合)があります。

まず、すべてのJavaScriptクラスとスクリプトは.jsファイルにはありませんが、.js.htmlファイルには(<script>タグ内で、.js.htmlは単にHTMLページと完全なJavaScriptスクリプト/クラスを区別するため)

MyClass.js.html

<script>
   class MyClass {

      // Your code here..

   }

</script>

その後、クラスをインポートしたい場合は、HTMLインポートを使用するだけです。

<link rel="import" href="relative/path/to/MyClass.js.html"/>

<script>
   var myClass = new MyClass();
   // Your code here..
</script>

編集:HTMLのインポートはドロップされます

HTMLインポートとES6モジュール どちらもすでに世界中のほとんどのブラウザでうまく実装されていますしかしHTMLのインポートは間違いなく標準の一部になることはないので、ES6モジュールとは異なり、その開発は中止されます、そしてあなたは間違いなくES6モジュールを使い始めるべきです。

6
Yairopro

JavaScriptファイルを含むあらゆるファイルで@import "path/to/file.js";構文を使用できるようにする Grunt プラグインがあります。それはuglifyやwatchあるいは他のプラグインとペアにすることができます。

Npm install: https://npmjs.org/package/grunt-import にインストールできます。

6
Marcin

素敵で、短く、シンプルで、保守しやすいものにしてください! :]

// 3rd party plugins / script (don't forget the full path is necessary)
var FULL_PATH = '', s =
[
    FULL_PATH + 'plugins/script.js'      // Script example
    FULL_PATH + 'plugins/jquery.1.2.js', // jQuery Library 
    FULL_PATH + 'plugins/crypto-js/hmac-sha1.js',      // CryptoJS
    FULL_PATH + 'plugins/crypto-js/enc-base64-min.js'  // CryptoJS
];

function load(url)
{
    var ajax = new XMLHttpRequest();
    ajax.open('GET', url, false);
    ajax.onreadystatechange = function ()
    {
        var script = ajax.response || ajax.responseText;
        if (ajax.readyState === 4)
        {
            switch(ajax.status)
            {
                case 200:
                    eval.apply( window, [script] );
                    console.log("library loaded: ", url);
                    break;
                default:
                    console.log("ERROR: library not loaded: ", url);
            }
        }
    };
    ajax.send(null);
}

 // initialize a single load 
load('plugins/script.js');

// initialize a full load of scripts
if (s.length > 0)
{
    for (i = 0; i < s.length; i++)
    {
        load(s[i]);
    }
}

このコードは、couldのプラットフォーム(または特定のプラットフォーム)で完全にサポートするために追加の機能を必要とする短い機能的な例です。

6
tfont

jQuery の方法を使ってください。 readyイベントを遅らせるには、まず$.holdReady(true)を呼び出します。例( source ):

$.holdReady(true);
$.getScript("myplugin.js", function() {
    $.holdReady(false);
});
6
weageoo

基本的には次のようにして、新しい要素を作成し、それをheadに添付します。

var x = document.createElement('script');
x.src = 'http://example.com/test.js';
document.getElementsByTagName("head")[0].appendChild(x);

jQuery :に

// jQuery
$.getScript('/path/to/imported/script.js', function()
{
    // Script is now loaded and executed.
    // Put your dependent JavaScript code here.
});
5

NodeJSの場合のみ、これは私にとって最高の結果をもたらしました!

私はここでほとんどの解決策を試してみましたが、スコープを変更せずに他のファイルをロードすることができるだけのことができなかった。最後にこれを使いました。これは範囲とすべてを維持します。それはあなたのコードがその点でそうであるのと同じくらい良いです。

const fs = require('fs');
eval(fs.readFileSync('file.js')+'');
5
rturkek

とても簡単です。ファイルA.jsをファイルB.jsにインポートしたいとします。

HTMLファイルでB.jsをリンクしたことを確認したら、そのHTMLファイルでB.jsの前にA.jsをリンクするだけです。そうすればA.jsのパブリック変数はB.jsの中で利用可能になるでしょう

これは複雑な答えを必要としません。

4

私はJavaScriptファイルの配列を非同期的にロードし、最後にコールバックをするという要件があります。基本的に私の最善のアプローチは次のとおりです。

// Load a JavaScript file from other JavaScript file
function loadScript(urlPack, callback) {
    var url = urlPack.shift();
    var subCallback;

    if (urlPack.length == 0) subCallback = callback;
    else subCallback = function () {
        console.log("Log script: " + new Date().getTime());
        loadScript(urlPack, callback);
    }

    // Adding the script tag to the head as suggested before
    var head = document.getElementsByTagName('head')[0];
    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 = subCallback;
    script.onload = subCallback;

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

例:

loadScript(
[
    "js/DataTable/jquery.dataTables.js",
    "js/DataTable/dataTables.bootstrap.js",
    "js/DataTable/dataTables.buttons.min.js",
    "js/DataTable/dataTables.colReorder.min.js",
    "js/DataTable/dataTables.fixedHeader.min.js",
    "js/DataTable/buttons.bootstrap.min.js",
    "js/DataTable/buttons.colVis.min.js",
    "js/DataTable/buttons.html5.min.js"
], function() { gpLoad(params); });

2番目のスクリプトは最初のスクリプトが完全にロードされるまでロードされないので、...

結果:

Result

4
MiBol

Angularを使用している場合は、プラグインモジュール $ ocLazyLoad を使用すると便利です。 

これがその文書からの引用です。

複数のファイルを持つ1つ以上のモジュールとコンポーネントをロードします。

$ocLazyLoad.load(['testModule.js', 'testModuleCtrl.js', 'testModuleService.js']);

複数のファイルを含む1つまたは複数のモジュールをロードし、必要に応じてタイプを指定します。注:requireJS形式のフォーマットを使用する場合(たとえば先頭にjs!を付けて)、ファイル拡張子を指定しないでください。どちらかを使用してください。

$ocLazyLoad.load([
  'testModule.js',
   {type: 'css', path: 'testModuleCtrl'},
   {type: 'html', path: 'testModuleCtrl.html'},
   {type: 'js', path: 'testModuleCtrl'},
   'js!testModuleService',
   'less!testModuleLessFile'
]);

あなたは外部ライブラリをロードすることができます(角度ではありません):

$ocLazyLoad.load(['testModule.js', 
   'bower_components/bootstrap/dist/js/bootstrap.js', 'anotherModule.js']);

Cssファイルとテンプレートファイルを読み込むこともできます。

 $ocLazyLoad.load([
     'bower_components/bootstrap/dist/js/bootstrap.js',
     'bower_components/bootstrap/dist/css/bootstrap.css',
     'partials/template1.html'
 ]);
4
gm2008

Node.jsで動作するES6を使用したモジュールのインポートとエクスポート

.mjsの代わりに.js拡張子でファイルに名前を付け

ファイルを作成する

touch main.mjs lib.mjs

main.js

import { add } from './lib.mjs';
console.log(add(40, 2));

lib.mjs

export let add = (x,y) => {
  return x + y
}

実行する

node --experimental-modules main.js
3
jasonleonhard

今、私は完全に誤解されているかもしれませんが、ここに私が最近始めたものがあります... キャリッジリターンであなたのJavaScriptファイルを始めそして終わり、PHPスクリプトに置き、その後に続きます。キャリッジリターン JavaScriptのコメント "//"はPHPによって無視されるため、いずれにせよ包含は起こります。キャリッジリターンの目的は、含まれているJavaScriptの最初の行がコメントアウトされていないようにすることです。

技術的には、コメントは必要ありませんが、 Dreamweaver にエラーが表示されます。エラーを投稿しないIDEでスクリプトを作成している場合は、コメントやキャリッジリターンは不要です。

\n
//<?php require_once("path/to/javascript/dependency.js"); ?>

function myFunction(){
    // stuff
}
\n
3
Duncan
var s=["Hscript.js","checkRobert.js","Hscript.js"];
for(i=0;i<s.length;i++){
  var script=document.createElement("script");
  script.type="text/javascript";
  script.src=s[i];
  document.getElementsByTagName("head")[0].appendChild(script)
};
3
Robert A

忘れずに LAB.js をチェックしてください。

<script type="text/javascript">
       $LAB
       .script("jquery-1.8.3.js").wait()
       .script("scripts/clientscript.js");      
</script>
3
emolaus

過去のプロジェクトで、再利用可能なJavaScriptファイルのインポートに ajile を使用することでかなり成功しました。私はいつもJavaScript自体に組み込まれたこれのための機能があることを望みました。

3
jpierson

別のアプローチはHTMLインポートを使うことです。これらはスタイルシート参照と同様にスクリプト参照を含むことができます。

あなただけのようなHTMLファイルをリンクすることができます

<link rel="import" href="vendorScripts.html"/>

vendorScripts.htmlファイル内に、次のようなスクリプト参照を含めることができます。

<script src="scripts/vendors/jquery.js"></script>
<script src="scripts/vendors/bootstrap.js"></script>
<script src="scripts/vendors/angular.js"></script>
<script src="scripts/vendors/angular-route.js"></script>

詳細については HTML Imports をご覧ください。

残念ながら、これはChromeでしか機能しません。

2
gabriel211

インポートすることはできませんが、参照することはできます。

PhpShtorm IDE。参照するには、ある.jsファイルから別の.jsに、これをファイルの先頭に追加します。

<reference path="../js/file.js" />

もちろん、JavaScriptファイルへのあなた自身のPATHを使うべきです。

他のIDEでも動作するかどうかわかりません。おそらくそう、試してみてください。 Visual Studioでも動作するはずです。

はい、 あります...

ES6 で読み続けて、exportname__とimportname__の一部または全体のJavaScriptファイルを別のファイルに変換できます。

しかし、 ES6 はすべてのブラウザでサポートされているわけではないので、必要なのはbabel.jsを使用して変換することです。

それで、あなたは以下のようなクラスを作成します:

class Person {
  constructor(name) {
    this.name = name;
  }

  build() {
    return new Person(this);
  }
}

module.exports = Person;

別のJavaScriptファイルで、次のようにインポートします。

import { Person } from 'Person';

次のようなファイルも要求できます。

const Person = require('./Person');

古いバージョンのJavaScriptを使用している場合は、 requirejs を使用できます。

requirejs(["helper/util"], function(util) {
    //This function is called when scripts/helper/util.js is loaded.
    //If util.js calls define(), then this function is not fired until
    //util's dependencies have loaded, and the util argument will hold
    //the module value for "helper/util".
});

jQuery のように古いバージョンのものに固執したい場合は、 getScript のようなものを使用することもできます。

jQuery.getScript('./another-script.js', function() {
    // Call back after another-script loaded
});

大事なことを言い忘れましたが、<script>タグを使用してスクリプトをまとめる従来の方法を実行できることを忘れないでください。

<script src="./first-script.js"></script>
<script src="./second-script.js"></script>
<script src="./third-script.js"></script>

async および defer 属性もありますが、ここでそれらについて説明します。

注: 外部スクリプトを実行する方法はいくつかあります。

  • Asyncが存在する場合:スクリプトはページの残りの部分と非同期に実行されます(スクリプトはページが解析を続けている間に実行されます)。
  • Asyncが存在せず、deferが存在する場合:スクリプトは、ページが解析を終了したときに実行されます。
  • Asyncもdeferも存在しない場合:スクリプトはフェッチされ、ブラウザがページの解析を続ける前に直ちに実行されます。
2
Alireza

これはおそらく別の方法です。 Node.jsでは、次のようにします。 http://requirejs.org/docs/node.html

sub.js

module.exports = {
  log: function(string) {
    if(console) console.log(string);
  }
  mylog: function(){
    console.log('just for log test!');
  }
}

main.js

var mylog =require('./sub');

mylog.log('Hurray, it works! :)');
mylog.mylog();
2
xgqfrms

私はこの問題を別の方法で試しました、

スクリプトインポートの順序は、ここでは効果がありません。

index.html

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Trials</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src="main.js"></script>
    <script src="scriptA.js"></script>
</head>

<body>
<h3>testing js in js (check console logs)</h3>
<button onclick="fnClick()">TEST</button>
</body>

</html>

main.js

function fnClick() {
  console.log('From\tAAAAA');
  var pro = myExpo.hello();
  console.log(pro);
}

scriptA.js

myExpo = {
    hello: function () {
        console.log('From\tBBBBB');
        return "Hello";
    }
}

そして 結果

From    AAAAA
From    BBBBB
Hello
1
Milton Ain

ES6:YES scriptタグでtype = "module"を使用(- support

<script type="module" src="script.js"></script>

そして、script.jsファイルには、そのような別のファイルが含まれます。

import { hello } from './module.js';
...
// alert(hello());

「module.js」では、 export function/class インポートする必要があります

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

動作中 ここの例

1

2つ以上のスクリプトが呼び出されたときに同じ関数を占有していることがわかった場合は、それらを同じ時間に含めることはできません。ユーザー選択によって 動的 にする必要があります。

$.getScriptを使用してjQueryに別のファイルをインクルードすることは、スクリプト デフォルトではキャッシュされません 以降で機能します。だから我々は別のスクリプトを呼び出すために保存されています。呼び出しは次のように整理できます。

HTML

<select class="choice">
  <option value="script1" selected>Script-1</option>
  <option value="script2">Script-2</option>
</select>

JS 

  $(".choice").change(on_change);

    var url = "https://example.com";
    $.url1 = url + "/script1.js";
    $.url2 = url + "/script2.js";

  function on_change() {
    if ($(".choice").val()=="script1") {
        script1();
    } else {
        script2();
    }

    // script1
    function script1() {   
      $.getScript($.url1, function( data, textStatus, jqxhr ) {
          //excecute here
      });  
    }

    // script2
    function script2() {
       $.getScript($.url2, function( data, textStatus, jqxhr ) {
          //excecute here
      });  
    }
0
Chetabahana

Facebookのアイデアから取られた回答@Dan Dascalescuからlibに少し拡張します。

(function() {   
var __ = {};
this._ = function(name, callback) {
    if(__[name]==undefined) {
        __[name] = true;
        var firstScript = document.getElementsByTagName('script')[0],
          js = document.createElement('script');
          js.src =  name;
          js.onload = callback;
          firstScript.parentNode.insertBefore(js, firstScript);
    }
}
})();

(new _('https://cdnjs.cloudflare.com/ajax/libs/Snowstorm/20131208/snowstorm-min.js', function() {
 snowStorm.snowColor = '#99ccff';
}));
0

通常、 静的スクリプト を使用します。それで、私たちは cache からできるだけ多くのものを取得したいのです。

使用方法

$.cachedScript( "ajax/test.js" ).done(function( script, textStatus ) {
  console.log( textStatus );
});

cache:true オプションがajaxメソッドに追加されました

0
Adam111p
var xxx = require("../lib/your-library.js")

または

import xxx from "../lib/your-library.js" //get default export
import {specificPart} from '../lib/your-library.js' //get named export
import * as _name from '../lib/your-library.js'  //get full export to alias _name
0
Mesut Yiğit
0
Andrej

順番に複数のスクリプトを動的にロードする

1つのスクリプトだけをロードしている場合、または複数のスクリプトのロード順序を気にしていない場合は、上記の関数はうまく機能します。他に依存するスクリプトがある場合は、 Promise を使用してロードの順序を指定する必要があります。その背後にある理由は、Javascriptがスクリプトやイメージなどのリソースを非同期的に読み込むためです。ロードの順序は非同期呼び出しの順序には依存しません。つまり、dynamicallyLoadScript("scrip1")を呼び出す前にdynamicallyLoadScript("scrip2")を呼び出しても、script1がscript2の前にロードされることは保証されません。

それで、ロード順を保証するdynamicLoadScriptのもう一つのバージョンがあります:

// Based on: https://javascript.info/promise-basics#example-loadscript
function dynamicallyLoadScript(url) {
        return new Promise(function(resolve, reject) {
        var script = document.createElement("script");
        script.src = url;
        script.onload = resolve;
        script.onerror = () => reject(new Error(`Error when loading ${url}!`));
        document.body.appendChild(script);
    });

Promiseの詳細については、 この優れたページ を参照してください。

この新しいdynamicLoadScriptの使い方はとても簡単です。

dynamicallyLoadScript("script1.js")
.then(() => dynamicallyLoadScript("script2.js"))
.then(() => dynamicallyLoadScript("script3.js"))
.then(() => dynamicallyLoadScript("script4.js"))
.then(() => dynamicallyLoadScript("script5.js"))
//...

これで、スクリプトはscript1.js、script2.js、script3.jsなどの順序でロードされました。

スクリプトのロード後に依存コードを実行する

さらに、スクリプトをロードした後にそのスクリプトを使用するコードをすぐに実行できます。スクリプトをロードした後に.thenを追加するだけです。

dynamicallyLoadScript("script1.js")
.then(() => dynamicallyLoadScript("script2.js"))
.then(() => foo()) // foo can be a function defined in either script1, script2
.then(() => dynamicallyLoadScript("script3.js"))
.then(() => {
     if (var1){ // var1 can be a global variable defined in either script1, script2, or script3
          bar(var1); // bar can be a function defined in either script1, script2, or script3
     } else {
          foo(var1);
     }
})
//more .then chains...

読み込みエラーを処理する

未処理の約束拒否(スクリプトのロードエラーなど)を表示するには、このunhandledrejectionイベントリスナをコードの先頭に配置します。

// Based on: https://javascript.info/promise-error-handling#unhandled-rejections
window.addEventListener('unhandledrejection', function(event) {
     // the event object has two special properties:
     console.error(event.promise);// the promise that generated the error
     console.error(event.reason); // the unhandled error object
});

これでスクリプトロードエラーが通知されます。


ショートカット機能

ロード直後にコードを実行せずに多数のスクリプトをロードする場合は、この短縮形の関数が便利です。

function dynamicallyLoadScripts(urls){
        if (urls.length === 0){
            return;
        }
        let promise = dynamicallyLoadScript(urls[0]);
        urls.slice(1).forEach(url => {
            promise = promise.then(() => dynamicallyLoadScript(url));
        });
    }

それを使用するには、単に次のようなスクリプトURLの配列を渡します。

const scriptURLs = ["dist/script1.js", "dist/script2.js", "dist/script3.js"];
dynamicallyLoadScripts(scriptURLs);

スクリプトは配列に表示される順序でロードされます。

0
AlienKevin