it-swarm.asia

كيف يمكنني تضمين ملف JavaScript في ملف JavaScript آخر؟

هل هناك شيء في JavaScript يشبه @import في CSS يسمح لك بتضمين ملف JavaScript داخل ملف JavaScript آخر؟

4635
Alec Smart

لم يكن للإصدارات القديمة من JavaScript أي استيراد أو تضمين أو طلب ، لذا تم تطوير العديد من الطرق المختلفة لهذه المشكلة.

ولكن منذ عام 2015 (ES6) ، أصبح لدى JavaScript ES6 modules القياسي لاستيراد الوحدات النمطية في Node.js ، وهو مدعوم أيضًا بـ معظم المتصفحات الحديثة .

للتوافق مع المتصفحات القديمة ، build و/أو transpilation يمكن استخدام الأدوات.

وحدات ES6

تم دعم وحدات ECMAScript (ES6) في 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 الخارجية في المتصفحات التي لا تتطلب معالجة مسبقة.

اجاكس التحميل

يمكنك تحميل برنامج نصي إضافي بمكالمة AJAX ثم استخدام eval لتشغيله. هذه هي الطريقة الأكثر مباشرة ، ولكنها تقتصر على المجال الخاص بك بسبب طراز أمان JavaScript sandbox. يؤدي استخدام eval أيضًا إلى فتح باب الأخطاء والتطفل ومشكلات الأمان.

جلب التحميل

مثل Dynamic Imports ، يمكنك تحميل واحد أو أكثر من البرامج النصية باستخدام مكالمة fetch باستخدام الوعود للتحكم في ترتيب تنفيذ تبعيات البرنامج النصي باستخدام مكتبة Fetch Inject :

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 توفر المكتبة وظيفة التحميل في سطر واحد :

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

تحميل البرنامج النصي الديناميكي

يمكنك إضافة علامة برنامج نصي بعنوان URL للبرنامج النصي في HTML. لتجنب النفقات العامة من مسج ، وهذا هو الحل الأمثل.

يمكن أن يقيم البرنامج النصي حتى على خادم آخر. علاوة على ذلك ، يقوم المتصفح بتقييم الكود. يمكن حقن العلامة <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> جديدة إلى نهاية قسم الرأس بالصفحة ، حيث يتم تعيين سمة src على عنوان URL الذي يتم إعطاءه إلى الوظيفة كمعلمة أولى.

كل من هذه الحلول تمت مناقشتها وتوضيحها في JavaScript Madness: Dynamic Script Loading .

اكتشاف متى تم تنفيذ البرنامج النصي

الآن ، هناك مشكلة كبيرة يجب أن تعرفها. القيام بذلك يعني أنك قمت بتحميل الكود عن بعد. ستقوم متصفحات الويب الحديثة بتحميل الملف والاستمرار في تنفيذ البرنامج النصي الحالي لأنها تقوم بتحميل كل شيء بشكل غير متزامن لتحسين الأداء. (ينطبق هذا على طريقة 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;. هناك مقالة رائعة حول تحميل جافا سكريبت بشكل عام والتي تناقش هذا.

شفرة المصدر دمج/قبل المعالجة

كما هو مذكور في الجزء العلوي من هذه الإجابة ، يستخدم العديد من المطورين أدوات (أدوات) الإنشاء/التحويل مثل Parcel أو Webpack أو Babel في مشاريعهم ، مما يسمح لهم باستخدام بناء جملة جافا سكريبت القادم ، وتوفير التوافق مع الإصدارات السابقة للمتصفحات القديمة ، والجمع بين الملفات ، والتقليل ، أداء تقسيم رمز الخ.

4044
e-satis

إذا كان أي شخص يبحث عن شيء أكثر تقدمًا ، فجرّب RequireJS . ستحصل على مزايا إضافية مثل إدارة التبعية ، وتزامن أفضل ، وتجنب الازدواجية (أي استرداد نص أكثر من مرة).

يمكنك كتابة ملفات JavaScript الخاصة بك في "وحدات" ومن ثم الرجوع إليها على أنها تبعيات في البرامج النصية الأخرى. أو يمكنك استخدام RequireJS كحل بسيط "go get this script".

مثال:

تحديد التبعيات كوحدات نمطية:

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

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

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

مقتطف من جيثب README:

يتطلب RequireJS تحميل ملفات جافا سكريبت عادي وكذلك وحدات أكثر تحديدًا. تم تحسينه للاستخدام داخل المتصفح ، بما في ذلك في Web Worker ، ولكن يمكن استخدامه في بيئات JavaScript الأخرى ، مثل Rhino و Node. ينفذ API غير متزامن الوحدة النمطية.

يستخدم RequireJS علامات البرامج النصية العادية لتحميل الوحدات/الملفات ، لذلك يجب أن يسمح لتصحيح الأخطاء بسهولة. يمكن استخدامه ببساطة لتحميل ملفات JavaScript الحالية ، لذلك يمكنك إضافتها إلى مشروعك الحالي دون الحاجة إلى إعادة كتابة ملفات JavaScript الخاصة بك.

...

540
John Strickler

في الواقع توجد طريقة لتحميل ملف JavaScript لا بشكل غير متزامن ، لذلك يمكنك استخدام الوظائف المضمنة في الملف الذي تم تحميله حديثًا فور تحميله ، وأعتقد أنه يعمل في جميع المتصفحات .

تحتاج إلى استخدام jQuery.append() في عنصر <head> في صفحتك ، وهو:

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

ومع ذلك ، تواجه هذه الطريقة أيضًا مشكلة: إذا حدث خطأ في ملف JavaScript المستوردة ، فسوف يقوم { Firebug _ (وكذلك Firefox Error Console و Chrome Developer Tools أيضًا) بالإبلاغ عن مكانه بشكل غير صحيح ، وهي مشكلة كبيرة إذا كنت تستخدم Firebug لتتبع أخطاء JavaScript كثيرًا (أفعل). لا يعرف Firebug ببساطة عن الملف الذي تم تحميله حديثًا لسبب ما ، لذلك إذا حدث خطأ في هذا الملف ، فإنه يشير إلى أنه قد حدث في ملفك الرئيسي HTML ، وسوف تواجه مشكلة في اكتشافه السبب الحقيقي للخطأ.

ولكن إذا لم تكن هذه مشكلة بالنسبة لك ، فيجب أن تعمل هذه الطريقة.

لقد كتبت فعلاً مكوّن إضافي jQuery يسمى $ .import_js () والذي يستخدم هذه الطريقة:

(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');

لقد أجريت أيضًا اختبارًا بسيطًا لهذا في مثال .

يتضمن ملف main.js في HTML الرئيسي ثم يستخدم البرنامج النصي في main.js$.import_js() لاستيراد ملف إضافي يسمى included.js ، والذي يحدد هذه الوظيفة:

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

مباشرة بعد تضمين included.js ، يتم استدعاء وظيفة hello() ، وستحصل على التنبيه.

(هذه الإجابة هي استجابة لتعليقات satis الإلكترونية).

176
Kipras

هناك طريقة أخرى ، في رأيي أكثر نظافة ، وهي تقديم طلب Ajax متزامن بدلاً من استخدام علامة <script>. وهي أيضًا كيفية تضمين Node.js handles.

إليك مثال باستخدام 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(); 
140
Ariel

هناك أخبار جيدة لك. قريبا جدا سوف تكون قادرة على تحميل رمز جافا سكريبت بسهولة. ستصبح طريقة قياسية لاستيراد وحدات من شفرة JavaScript وستكون جزءًا من JavaScript الأساسي.

عليك ببساطة كتابة import cond from 'cond.js'; لتحميل ماكرو باسم cond من ملف cond.js.

لذلك لا يتعين عليك الاعتماد على أي إطار جافا سكريبت ولا يلزم إجراء مكالمات Ajax بشكل صريح.

تشير إلى:

90
Imdad

من الممكن إنشاء علامة JavaScript بشكل حيوي وإلحاقها بمستند HTML من داخل شفرة JavaScript الأخرى. سيؤدي هذا إلى تحميل ملف 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");
81
Svitlana Maksymchuk

العبارة 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)
}
52
Arnaud Gouder de Beauregard

هنا متزامن version بدون مسج :

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 manipulation):

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>

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

43
nornagon

فيما يلي الإصدار المعمم لكيفية قيام Facebook بذلك من خلال زر الإعجاب في كل مكان:

<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 ، فسوف يعمل من أجلك.

السبب وراء بحثنا عن أول عنصر script بدلاً من head أو body هو أن بعض المتصفحات لا تنشئ واحدًا في حالة فقده ، لكننا نضمن أن لدينا عنصر script - هذا واحد. اقرأ المزيد في http://www.jspatterns.com/the-ridiculous-case-of-adding-a-script-element/ .

37
Dan Dascalescu

إذا كنت تريد جافا سكريبت خالص ، يمكنك استخدام document.write.

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

إذا كنت تستخدم مكتبة jQuery ، فيمكنك استخدام الأسلوب $.getScript.

$.getScript("another_script.js");
32
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
25
Calmarius

معظم الحلول الموضحة هنا تعني التحميل الديناميكي. كنت أبحث بدلاً من ذلك عن مترجم يقوم بتجميع جميع الملفات التابعة في ملف إخراج واحد. نفس أقل / Sass preprocessors تتعامل مع CSS @import في القاعدة. بما أنني لم أجد شيئًا لائقًا من هذا النوع ، فقد كتبت أداة بسيطة لحل المشكلة.

لذلك هنا المترجم ، https://github.com/dsheiko/jsic ، والذي يستبدل $import("file-path") بمحتوى الملف المطلوب بشكل آمن. إليك المقابلة Grunt plugin: 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

أو بدلاً من التضمين في وقت التشغيل ، استخدم برنامج نصي للتسلسل قبل التحميل.

يمكنني استخدام أسنان العجلة (لا أعرف إذا كان هناك آخرون). يمكنك إنشاء رمز JavaScript في ملفات منفصلة وتتضمن التعليقات التي تتم معالجتها بواسطة محرك Sprockets كما تتضمن. للتطوير ، يمكنك تضمين الملفات بالتتابع ، ثم للإنتاج لدمجها ...

أنظر أيضا:

17
JMawer

في حالة استخدام Web Workers وترغب في تضمين برامج نصية إضافية في نطاق العامل ، فإن الإجابات الأخرى المقدمة حول إضافة برامج نصية إلى العلامة head ، لن تعمل من أجلك.

لحسن الحظ ، لدى عمال الويب وظيفة importScripts الخاصة بهم وهي وظيفة عالمية في نطاق Web Worker ، وهي موطن للمستعرض نفسه لأنه جزء من المواصفات .

بدلاً من ذلك ، كثاني أعلى صوت تمت إجابته على أبرز سؤالك ، RequireJS يمكن أيضًا التعامل مع تضمين البرامج النصية داخل Web Worker (من المحتمل الاتصال بـ importScripts ، لكن مع بعض الميزات المفيدة الأخرى).

14
Turnerj

كانت لدي مشكلة بسيطة ، لكنني شعرت بالحيرة من الردود على هذا السؤال.

اضطررت إلى استخدام متغير (myVar1) محدد في ملف JavaScript واحد (myvariables.js) في ملف JavaScript آخر (main.js).

لهذا فعلت على النحو التالي:

قم بتحميل كود JavaScript في ملف HTML ، بالترتيب الصحيح ، 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 الثاني ، ومتغيرات ملف JavaScript الأول يمكن الوصول إليها في ملف JavaScript الثاني ، تلقائيًا.

هذا أنقذ يومي. آمل أن يساعد هذا.

14
Manohar Reddy Poreddy

بناء جملة @import لتحقيق استيراد JavaScript يشبه CSS ممكن باستخدام أداة مثل Mixture عبر نوع ملف .mix الخاص (انظر هنا ). أتصور أن التطبيق يستخدم ببساطة إحدى الطرق المذكورة أعلاه داخليًا ، على الرغم من أنني لا أعرف.

من وثائق المزيج على ملفات .mix:

مزيج الملفات هي ببساطة ملفات .js أو .css مع .mix. في اسم الملف. يمزج ملف المزيج ببساطة وظيفة النمط العادي أو ملف البرنامج النصي ويسمح لك بالاستيراد والجمع.

فيما يلي مثال لملف .mix الذي يجمع عدة ملفات .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";

يقوم المزيج بإخراج هذا كـ scripts-global.js وأيضًا كإصدار مصغر (scripts-global.min.js).

ملاحظة: لا أتبع بأي حال من الأحوال مع Mixture ، بخلاف استخدامه كأداة تطوير للجهة الأمامية. صادفت هذا السؤال عند رؤية ملف جافا سكريبت .mix قيد التنفيذ (في أحد مراجل المزيج) وكوني مرتبكًا بعض الشيء ("يمكنك القيام بذلك؟" فكرت في نفسي). ثم أدركت أنه كان نوع ملف خاص بالتطبيق (مخيب للآمال إلى حد ما ، متفق عليه). ومع ذلك ، برزت المعرفة قد تكون مفيدة للآخرين.

UPDATE: Mixture هو الآن مجاني (غير متصل).

UPDATE: المزيج متوقف الآن. الإصدارات القديمة خليط لا تزال متاحة

12
Isaac Gregson
var js = document.createElement("script");

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

document.body.appendChild(js);
11
Sam4Code

طريقتي المعتادة هي:

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 (أحد الإجابات الأخرى) ولكن لا يبدو أنه يعمل بشكل جيد بالنسبة لي.

فيما يلي شرح لكيفية عمل الشفرة لأولئك الذين لديهم فضوليين: بشكل أساسي ، يقوم بإنشاء علامة نصية جديدة (بعد العلامة الأولى) لعنوان URL. إنه يعينها على الوضع غير المتزامن بحيث لا يحظر بقية الكود ، لكنه يستدعي رد اتصال عندما يتغير readyState (حالة المحتوى المراد تحميله) إلى "تحميل".

11
Christopher Dumas

كتبت وحدة نمطية بسيطة تعمل على أتمتة مهمة استيراد/بما في ذلك البرامج النصية للوحدة النمطية في JavaScript. للحصول على شرح مفصل للرمز ، يرجى الرجوع إلى منشور المدونةتتطلب جافا سكريبت/استيراد/تضمين وحدات.

// ----- 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

في اللغة الحديثة سيكون

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

لقد جئت إلى هذا السؤال لأنني كنت أبحث عن طريقة بسيطة للحفاظ على مجموعة من مكونات جافا سكريبت المفيدة. بعد رؤية بعض الحلول هنا ، توصلت إلى هذا:

  1. قم بإعداد ملف يسمى "plugins.js" (أو extensions.js أو ماذا لديك). احتفظ بملفات البرنامج المساعد مع هذا الملف الرئيسي.

  2. سيتضمن plugins.js صفيفًا يسمى "pluginNames []" سنقوم بتكراره على كل () ، ثم نضيف علامة إلى الرأس لكل مكون إضافي

    // set array يتم تحديثها عندما نضيف أو نزيل ملفات المكونات الإضافية var pluginNames = ["lettering"، "fittext"، "butterjam"، إلخ]؛ // علامة برنامج نصي واحدة لكل مكون إضافي $ .each (pluginNames ، function () {$ ('head'). append ('')؛})؛

  3. اتصل يدويًا بملف واحد فقط في رأسك:
    <script src="js/plugins/plugins.js"></script>

لقد وجدت أنه على الرغم من أن جميع المكونات الإضافية كانت تُسقط في علامة الرأس بالطريقة التي يجب عليها ، فإنها لم تكن دائمًا قيد التشغيل من قبل المتصفح عند النقر فوق الصفحة أو التحديث.

لقد وجدت أنه من الأكثر موثوقية فقط كتابة علامات النص في PHP. ما عليك سوى كتابته مرة واحدة وهذا مجرد عمل كثير مثل الاتصال بالبرنامج المساعد باستخدام JavaScript.

9
rgb_life

سيضيف هذا البرنامج النصي ملف JavaScript إلى أعلى أي علامة <script> أخرى:

(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 للتحقق من مجموعة من الكائنات المؤجلة ، لكنك الآن تقوم بذلك في كل ملف وسيتم اعتبار تحميل file2 بمجرد أن يتم تنفيذ $.when ليس عند تنفيذ رد الاتصال ، لذلك يستمر file1 في التنفيذ قبل file3 محمل. هذا حقا لا يزال لديه نفس المشكلة.

قررت العودة إلى الوراء بدلا من الأمام. شكرا document.writeln. أعلم أنه من المحرمات ، لكن طالما تم استخدامه بشكل صحيح فإن هذا يعمل بشكل جيد. ينتهي بك المطاف مع رمز يمكن تصحيحه بسهولة ، ويظهر في DOM بشكل صحيح ، ويمكن ضمان ترتيب يتم تحميل التبعيات بشكل صحيح.

يمكنك بالطبع استخدام $ ("body"). append () ، ولكن بعد ذلك لم يعد بإمكانك تصحيح الأخطاء بشكل صحيح.

ملاحظة: يجب استخدام هذا فقط أثناء تحميل الصفحة ، وإلا ستحصل على شاشة فارغة. بمعنى آخر ، ضع هذا دائمًا قبل/خارج المستند. جاهزة . لم أختبر استخدام هذا بعد تحميل الصفحة في حدث النقر أو أي شيء من هذا القبيل ، لكنني متأكد من أنها ستفشل.

أعجبتني فكرة تمديد مسج ، ولكن من الواضح أنك لست بحاجة إلى ذلك.

قبل الاتصال بـ 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;
    }
});

الاستعمال:

File3:

var f3obj = "file3";

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

FILE2:

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

FILE1:

$.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
curlyhairedgenius

على الرغم من أن هذه الإجابات رائعة ، يوجد "حل" بسيط موجود منذ تحميل البرنامج النصي ، وسيغطي 99.999٪ من حالات استخدام معظم الأشخاص. فقط قم بتضمين البرنامج النصي الذي تحتاجه قبل البرنامج النصي الذي يتطلبه. بالنسبة لمعظم المشاريع ، لا يستغرق الأمر وقتًا طويلاً لتحديد البرامج النصية المطلوبة وبأي ترتيب.

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

إذا كان script2 يتطلب script1 ، فهذه هي الطريقة الأسهل المطلقة للقيام بشيء كهذا. أنا مندهش جدًا لأن أحداً لم يطرح هذا الأمر ، لأنه الجواب الأكثر وضوحًا والأبسط الذي سيتم تطبيقه في كل حالة تقريبًا.

7
KthProg

لقد قمت بإنشاء وظيفة تسمح لك باستخدام لغة مشابهة لـ C #/Java لتضمين ملف JavaScript. لقد اختبرت ذلك قليلاً حتى من داخل ملف آخر ملف جافا سكريبت ويبدو أنه يعمل. أنها تتطلب مسج على الرغم من أن قليلاً من "السحر" في النهاية.

أضع هذا الرمز في ملف في جذر دليل البرنامج النصي الخاص بي (قمت بتسميته global.js ، لكن يمكنك استخدام كل ما تريد. ما لم أكن مخطئًا في ذلك ، يجب أن يكون jQuery البرامج النصية الوحيدة المطلوبة في صفحة معينة. ضع في اعتبارك هذا لم يتم اختباره إلى حد كبير بعد بعض الاستخدامات الأساسية ، لذلك قد توجد أو لا تكون هناك أي مشكلات بالطريقة التي قمت بها ؛ والاستخدام على مسؤوليتك الخاصة yadda yadda لست مسؤولاً إذا قمت برفع أي شيء عن 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

هناك عدة طرق لتطبيق الوحدات النمطية في Javascript ، وإليك أكثرها شيوعًا:

وحدات 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'). المهم هنا هو إدراك أن هذه الوحدات النمطية يتم تخزينها مؤقتًا ، لذا إذا كنت 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
Willem van der Veen

إليك حلاً للمتصفحات (وليس Node.js) باستخدام عمليات استيراد HTML.

أولاً ، ليست جميع فئات JavaScript والبرامج النصية في ملفات .js ، ولكن في ملفات .js.html ( .js .html هي فقط للتمييز بين صفحات HTML وإكمال سكريبت/فئات JavaScript) ، داخل علامات <script> ، مثل هذا :

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 modules كلاهما مطبق بالفعل بشكل جيد في معظم المستعرضات عبر العالم . لكن نظرًا لأن واردات HTML لن تكون بالتأكيد جزءًا من المعايير ، على عكس الوحدات النمطية ES6 ، سيتم إسقاط تطويرها ، ثم يجب أن تبدأ بالتأكيد في استخدام وحدات ES6.

6
Yairopro

فيما يلي Grunt plugin يسمح لك باستخدام بناء جملة @import "path/to/file.js"; في أي ملف بما في ذلك ملفات JavaScript. يمكن إقرانها بـ uglify أو watch أو أي مكون إضافي.

يمكن تثبيته مع تثبيت npm: 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]);
    }
}

هذا الرمز هو مجرد مثال وظيفي قصير أن يمكن يتطلب وظائف ميزة إضافية للحصول على الدعم الكامل على أي منصة (أو معينة).

6
tfont

أفضل استخدام مسج الطريق. لتأخير الحدث الجاهز ، اتصل أولاً $.holdReady(true). مثال ( المصدر ):

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

أفعل ذلك بشكل أساسي كما يلي ، حيث أنشئ عنصرًا جديدًا وأرفقه رأسًا على عقب:

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

في مسج :

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

ل NodeJS فقط ، وهذا عملت بالنسبة لي الأفضل!

لقد جربت معظم الحلول هنا ، لكن لم يساعدني أي شيء في مجرد التمكن من تحميل ملف آخر دون تغيير النطاق. وأخيرا اعتدت هذا. الذي يحافظ على نطاق وكل شيء. انها جيدة مثل التعليمات البرمجية الخاصة بك في تلك المرحلة.

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

انه بسيط جدا. افترض أنك تريد استيراد الملف A.js في الملف B.js.

من المؤكد الآن أنك قمت بربط B.js في ملف HTML ، ثم قم فقط بربط A.js قبل B.js في ملف HTML هذا. بعد ذلك ، ستكون المتغيرات العامة لـ A.js متاحة داخل B.js

هذا لا يتطلب إجابة معقدة.

4
Akshay Vijay Jain

أحتاج إلى تحميل مجموعة من ملفات 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); });

لن يتم تحميل البرنامج النصي الثاني حتى يتم تحميل الأول بالكامل ، وهكذا ...

النتائج:

 Result

4
MiBol

إذا كنت تستخدم Angular ، فإن وحدة البرنامج المساعد $ ocLazyLoad يمكن أن تساعدك على القيام بذلك.

فيما يلي بعض علامات الاقتباس من وثائقها:

قم بتحميل وحدة أو أكثر من الوحدات والمكونات بملفات متعددة:

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

قم بتحميل وحدة أو أكثر من ملفات متعددة وحدد نوعًا عند الضرورة: ملاحظة: عند استخدام تنسيق نمط requireJS (مع js! في البداية على سبيل المثال) ، لا تحدد امتداد الملف. استخدام واحد أو آخر.

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

يمكنك تحميل libs الخارجية (غير الزاوي):

$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

نعم ، هناك ...

استمر في القراءة ، في ES6 ، يمكننا export و import أو ملف 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 أقدم ، فيمكنك استخدام requjs :

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>

هناك أيضًا غير متزامن و تأجيل سمة يجب أن أذكرها هنا ...

ملاحظة: هناك عدة طرق يمكن بها تنفيذ برنامج نصي خارجي:

  • في حالة عدم التزامن: يتم تنفيذ البرنامج النصي بشكل غير متزامن مع بقية الصفحة (سيتم تنفيذ البرنامج النصي بينما تستمر الصفحة في التحليل)
  • إذا لم يكن المتزامن غير موجود وكان التأجيل موجودًا: يتم تنفيذ البرنامج النصي عندما تنتهي الصفحة من التحليل
  • في حالة عدم وجود مزامنة أو تأجيل: يتم جلب البرنامج النصي وتنفيذه على الفور ، قبل أن يواصل المستعرض تحليل الصفحة
4
Alireza

استيراد وتصدير الوحدات باستخدام ES6 التي تعمل مع Node.js

تسمية الملفات ذات امتداد .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 لذلك يحدث التضمين على أي حال. الغرض من إرجاع الأحرف هو أن السطر الأول من جافا سكريبت المضمّن لم يتم التعليق عليه.

من الناحية الفنية ، لا تحتاج إلى التعليق ، لكنه ينشر أخطاء في 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

في مشروع سابق ، حققت نجاحًا كبيرًا في استخدام ajile للقيام بواردات ملفات JavaScript القابلة لإعادة الاستخدام. كنت أتمنى دائمًا أن يكون هناك ميزة لهذا المضمّن في 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 لمزيد من التفاصيل.

لسوء الحظ ، هذا يعمل فقط في Chrome.

2
gabriel211

حاولت هذه المشكلة مع نهج آخر ،

ترتيب استيراد البرنامج النصي ، ليس له أي تأثير هنا.

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
2
Milton Ain

لا يمكنك الاستيراد ، لكن يمكنك الرجوع.

PhpShtorm IDE. للإشارة ، في ملف .js واحد إلى .js ، قم فقط بإضافة هذا إلى الجزء العلوي من الملف:

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

بالطبع ، يجب عليك استخدام PATH الخاص بك إلى ملف JavaScript.

لا أعرف ما إذا كان سيعمل في بيئة تطوير متكاملة أخرى. ربما نعم ، فقط حاول. يجب أن تعمل في Visual Studio أيضا.

2
Evgeniy Miroshnichenko

هنا ربما طريقة أخرى! في 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

إذا وجدت أن هناك نصين أو أكثر تشغلهما الوظيفة نفسها عند استدعائهما ، فلا يمكننا تضمينهما في الأوقات نفسها ، فنحن بحاجة إلى القيام بذلك بشكل حيوي بواسطة اختيار المستخدم.

تضمين ملفات أخرى في jQuery باستخدام $.getScript يعمل منذ أن البرنامج النصي لن يتم تخزينه مؤقتًا بشكل افتراضي . لذلك نحن حفظ لاستدعاء البرامج النصية الأخرى. يمكن ترتيب المكالمات مثل هذا:

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

يرجى ملاحظة أننا عادة نستخدم نصوص ثابتة . لذلك نحن نريد أن تؤخذ من ذاكرة التخزين المؤقت قدر الإمكان. هذا يحفظ حركة مرور الشبكة ويسرع الهبوط.

الاستخدام

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

ذاكرة التخزين المؤقت: صواب تمت إضافة الخيار إلى طريقة اياكس

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

يمكنك استخدام loadScript ES module لتحميل ملفات جافا سكريبت.

الاستعمال:

في علامة رأسك ، قم بتضمين الكود التالي:

<script src="https://raw.githack.com/anhr/loadScriptNodeJS/master/build/loadScript.js"></script>

أو

<script src="https://raw.githack.com/anhr/loadScriptNodeJS/master/build/loadScript.min.js"></script>

يمكنك الآن استخدام window.loadScript لتحميل ملفات JavaScript الخاصة بك.

loadScript.async (src ، [خيارات])

تحميل ملف جافا سكريبت غير متزامن.

src: عنوان URL لملف البرنامج النصي الخارجي أو مجموعة من أسماء ملفات البرنامج النصي.

خيارات: الخيارات المتبعة متاحة

onload: function () The onload event occurs when a script has been loaded. Default is undefined.

onerror: function ( str, e ) The onerror event occurs when an error has been occured. Default is undefined.

    str: error details

    e: event

appendTo: The node to which the new script will be append. Default is head node.

فمثلا

loadScript.async( "JavaScript.js",
        {
            onload: function () {

                var str = 'file has been loaded successfully';
                console.log( str );

            },
            onerror: function ( str, e ) {

                console.error( str );

            },

        } );

مثال على الاستخدام

0
Andrej

ديناميكي تحميل البرامج النصية متعددة في النظام

تعمل الوظيفة أعلاه بشكل جيد إذا كنت تقوم بتحميل برنامج نصي واحد فقط أو إذا كنت لا تهتم بترتيب تحميل البرامج النصية المتعددة. إذا كان لديك بعض البرامج النصية التي تعتمد على الآخرين ، فأنت بحاجة إلى استخدام وعد لتحديد ترتيب التحميل. السبب وراء ذلك هو تحميل Javascript موارد مثل النصوص والصور بشكل غير متزامن. لا يعتمد تسلسل التحميل على تسلسل المكالمات غير المتزامنة ، مما يعني أنه لن يتم ضمان تحميل البرنامج النصي 1 قبل البرنامج النصي 2 حتى إذا اتصلت بـ dynamicallyLoadScript("scrip1") قبل الاتصال dynamicallyLoadScript("scrip2")

لذلك ، يوجد إصدار آخر من DynamicallyLoadScript يضمن ترتيب التحميل:

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

لمعرفة المزيد عن الوعود ، راجع هذه الصفحة الممتازة .

استخدام هذا DynamicallyLoadScript الجديد بسيط للغاية:

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