Bagaimana cara memasukkan file JavaScript di lain file JavaScript?

Apakah ada sesuatu di JavaScript mirip dengan @import di CSS yang memungkinkan anda untuk memasukkan sebuah file JavaScript di dalam yang lain file JavaScript?

Mengomentari pertanyaan (6)
Larutan

Versi lama dari JavaScript tidak impor, termasuk, atau memerlukan, begitu banyak pendekatan yang berbeda untuk masalah ini telah dikembangkan. Tapi sejak 2015 (ES6), JavaScript memiliki ES6 modul standar untuk mengimpor modul di Node.js ini, yang juga didukung oleh sebagian besar browser modern. Untuk kompatibilitas dengan browser lama, membangun dan/atau transpilation alat-alat yang dapat digunakan.

ES6 Modul

ECMAScript (ES6) modul telah didukung dalam Node.js sejak v8.5, dengan --eksperimental-modul bendera. Semua file yang terlibat harus memiliki .mjs ekstensi.

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

ECMAScript modul di browser

Browser memiliki dukungan untuk memuat ECMAScript modul langsung (tidak ada alat-alat seperti Webpack diperlukan) sejak Safari 10.1, Chrome 61, Firefox 60, dan Edge 16. Periksa arus dukungan di 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);
}

Baca lebih lanjut di https://jakearchibald.com/2017/es-modules-in-browsers/

Dinamis impor di browser

Dinamis impor biarkan script load script lain yang diperlukan:

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

Baca lebih lanjut di https://developers.google.com/web/updates/2017/11/dynamic-import

Node.js memerlukan

Gaya lama mengimpor modul, masih banyak digunakan di Node.js, adalah modul.ekspor/require sistem.

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

Ada cara lain untuk JavaScript untuk menyertakan JavaScript eksternal isi di browser yang tidak memerlukan preprocessing.

AJAX Loading

Anda bisa memuat tambahan script dengan AJAX call dan kemudian menggunakan eval untuk menjalankannya. Ini adalah cara yang paling mudah, tetapi terbatas untuk domain anda karena JavaScript sandbox model keamanan. Menggunakan eval juga membuka pintu untuk bug, hacks dan masalah keamanan.

Fetch Loading

Seperti Dinamis Impor anda dapat memuat satu atau banyak script dengan mengambil call menggunakan janji-janji untuk mengontrol urutan eksekusi script dependensi menggunakan Mengambil Inject perpustakaan:

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

jQuery Loading

The jQuery perpustakaan menyediakan fungsi pemuatan dalam satu baris:

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

Dinamis Pemuatan Naskah

Anda bisa menambahkan tag script dengan script URL ke dalam HTML. Untuk menghindari overhead jQuery, ini adalah solusi yang ideal. Script bahkan dapat berada pada server yang berbeda. Selain itu, browser mengevaluasi kode. The <script> tag dapat disuntikkan ke salah satu halaman web <head>, atau dimasukkan sebelum penutupan </body> tag. Berikut adalah contoh bagaimana ini bisa bekerja:

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

Fungsi ini akan menambahkan baru <script> tag ke ujung kepala bagian atas halaman, di mana src atribut diatur untuk URL yang diberikan untuk fungsi sebagai parameter. Kedua solusi ini dibahas dan diilustrasikan di JavaScript Kegilaan: Dinamis Pemuatan Naskah.

Mendeteksi ketika naskah telah dieksekusi

Sekarang, ada masalah besar yang anda harus tahu tentang. Melakukan hal itu berarti bahwa anda dari jarak jauh memuat kode. Web browser Modern akan memuat file dan tetap mengeksekusi anda saat ini script karena mereka memuat segala sesuatu asynchronously untuk meningkatkan kinerja. (Hal ini berlaku untuk kedua metode jQuery dan manual dinamis pemuatan naskah metode.) Itu berarti bahwa jika anda menggunakan trik ini secara langsung, anda tidak't dapat menggunakan yang baru dimuat kode baris berikutnya setelah anda meminta untuk dimuat, karena akan masih loading. Misalnya: my_lovely_script.js berisi 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

Kemudian anda reload halaman memukul F5. Dan itu bekerja! Membingungkan... Jadi apa yang harus dilakukan tentang hal itu ? Nah, anda dapat menggunakan hack penulis menunjukkan di link yang aku berikan padamu. Singkatnya, bagi orang-orang terburu-buru, ia menggunakan sebuah acara untuk menjalankan fungsi callback ketika naskah ini dimuat. Sehingga anda dapat menempatkan semua kode menggunakan remote perpustakaan dalam fungsi callback. Misalnya:

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

Kemudian anda menulis kode yang ingin anda gunakan SETELAH naskah ini dimuat di lambda function:

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

Kemudian anda menjalankan semua bahwa:

loadScript("my_lovely_script.js", myPrettyCode);

Perhatikan bahwa script dapat dieksekusi setelah DOM telah dimuat, atau sebelum, tergantung pada browser dan apakah anda termasuk garis script.async = false;. Ada's artikel yang bagus pada Javascript loading secara umum yang membahas ini.

Source Code Merge/Preprocessing

Seperti yang disebutkan di atas jawaban ini, banyak pengembang menggunakan build/transpilation tool(s) seperti Parcel, Webpack, atau Babel dalam proyek-proyek mereka, yang memungkinkan mereka untuk menggunakan mendatang JavaScript sintaks, memberikan kompatibilitas untuk browser lama, menggabungkan file, mengecilkan, melakukan kode membelah dll.

Komentar (31)

Jika ada orang yang mencari sesuatu yang lebih maju, mencoba RequireJS. Anda'akan mendapatkan manfaat tambahan seperti ketergantungan manajemen, baik concurrency, dan menghindari duplikasi (yaitu, mengambil naskah lebih dari sekali).

Anda dapat menulis file JavaScript di "modul" dan kemudian referensi mereka sebagai dependensi dalam script lain. Atau anda dapat menggunakan RequireJS sebagai sederhana "pergi mendapatkan script ini" solusi.

Contoh:

Menentukan dependensi sebagai modul:

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 anda "main" JavaScript file yang tergantung pada some-dependency.js

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

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

Kutipan dari GitHub README:

RequireJS beban polos file JavaScript serta lebih jelas modul. Hal ini dioptimalkan untuk di-browser yang digunakan, termasuk di Web Pekerja, tetapi dapat digunakan di lain JavaScript lingkungan, seperti Badak dan Node. Menerapkan Asynchronous Module API.

RequireJS menggunakan plain tag script untuk load modul/file, sehingga harus memungkinkan untuk mudah debugging. Hal ini dapat digunakan hanya untuk beban yang ada file JavaScript, jadi anda dapat menambahkannya ke proyek yang sudah ada tanpa harus kembali menulis file JavaScript.

...

Komentar (7)

Ada benar-benar sebuah _is cara untuk me-load file JavaScript not asynchronous, sehingga anda bisa menggunakan fungsi-fungsi yang disertakan dalam file baru file yang dimuat tepat setelah pemuatan itu, dan saya pikir itu bekerja di semua browser.

Anda perlu menggunakan jQuery.append() pada <head> elemen halaman anda, yaitu:

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

Namun, metode ini juga memiliki masalah: jika terjadi kesalahan dalam impor file JavaScript, Firebug (dan juga Firefox Error Console dan Chrome Developer Tools juga) akan melaporkan tempatnya salah, yang merupakan masalah besar jika anda menggunakan Firebug untuk melacak kesalahan JavaScript turun banyak (saya lakukan). Firebug hanya doesn't tahu tentang yang baru dimuat file untuk beberapa alasan, sehingga jika terjadi kesalahan dalam file tersebut, maka laporan bahwa hal itu terjadi di utama anda HTML file, dan anda akan memiliki kesulitan menemukan alasan yang nyata bagi kesalahan.

Tapi jika itu tidak masalah bagi anda, maka metode ini harus bekerja.

Saya telah benar-benar menulis sebuah plugin jQuery yang disebut $.import_js() yang menggunakan metode ini:

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

Jadi semua yang anda akan perlu untuk melakukan impor JavaScript adalah:

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

Saya juga membuat sebuah tes sederhana untuk ini di Contoh.

Ini termasuk main.js file dalam HTML utama dan kemudian script di main.js menggunakan $.import_js() untuk mengimpor file tambahan yang disebut included.js, yang mendefinisikan fungsi ini:

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

Dan tepat setelah termasuk included.js, hello() fungsi dipanggil, dan anda mendapatkan peringatan.

(Jawaban ini adalah dalam menanggapi e-satis' komentar).

Komentar (7)

Cara lain, yang menurut saya jauh lebih bersih, adalah untuk membuat sinkron permintaan Ajax bukan menggunakan <script> tag. Yang ini juga cara [Node.js][1] menangani termasuk.

Berikut ini's contoh menggunakan jQuery:


function require(script) {
    $.ajax({
        url: script,
        dataType: "script",
        async: false,           // 
Komentar (13)

Ada kabar baik untuk anda. Sangat segera anda akan dapat memuat kode JavaScript dengan mudah. Itu akan menjadi cara standar untuk mengimpor modul kode JavaScript dan akan menjadi bagian dari inti JavaScript itu sendiri.

Anda hanya harus menulis impor cond dari &#39;cond.js&#39;; untuk memuat makro yang bernama cond dari file cond.js.

Sehingga anda don't harus mengandalkan JavaScript framework anda juga tidak harus secara eksplisit membuat Ajax panggilan.

Merujuk ke:

Komentar (11)

Hal ini dimungkinkan untuk secara dinamis menghasilkan tag JavaScript dan menambahkannya ke dokumen HTML dari dalam lainnya kode JavaScript. Ini akan memuat ditargetkan file 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");
Komentar (13)

Pernyataan impor dalam ECMAScript 6.

Sintaks

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;
Komentar (4)

Mungkin anda dapat menggunakan fungsi ini yang saya temukan pada halaman ini Bagaimana saya sertakan file JavaScript di file 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)
}
Komentar (7)

Berikut adalah sinkron versi tanpa jQuery:


function myRequire( url ) {
    var ajax = new XMLHttpRequest();
    ajax.open( 'GET', url, false ); // 
Komentar (7)

Saya hanya menulis ini kode JavaScript (menggunakan Prototype DOM manipulasi):

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

Penggunaan:

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

Inti: http://gist.github.com/284442.

Komentar (2)

Berikut ini's versi umum dari bagaimana Facebook itu untuk mereka di mana-mana Seperti tombol:

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

Jika ia bekerja untuk Facebook, itu akan bekerja untuk anda.

Alasan mengapa kita melihat untuk pertama script elemen bukan kepala atau tubuh ini karena beberapa browser don't membuat satu jika hilang, tapi kami're dijamin untuk memiliki script element - satu ini. Baca lebih lanjut di http://www.jspatterns.com/the-ridiculous-case-of-adding-a-script-element/.

Komentar (2)

Jika anda ingin murni JavaScript, anda dapat menggunakan dokumen.menulis.

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

Jika anda menggunakan library jQuery, anda dapat menggunakan $.getScript metode.

$.getScript("another_script.js");
Komentar (1)

Anda juga bisa merakit script anda menggunakan PHP:

File 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
Komentar (2)

Sebagian besar solusi yang ditampilkan di sini berarti dinamis pemuatan. Aku mencari bukan untuk compiler yang merakit semua tergantung file menjadi satu file output. Sama seperti Kurang/Sass preprosesor berurusan dengan CSS @import di-aturan. Karena saya didn't menemukan sesuatu yang layak semacam ini, saya menulis sebuah alat sederhana untuk memecahkan masalah.

Jadi di sini adalah compiler, https://github.com/dsheiko/jsic, yang menggantikan $impor("file-path") dengan berkas yang diminta konten aman. Berikut adalah sesuai Kasar plugin: https://github.com/dsheiko/grunt-jsic.

Pada jQuery menguasai cabang, mereka hanya menggabungkan atom file sumber ke dalam satu dimulai dengan intro.js dan berakhir dengan outtro.js. Itu doesn't cocok untuk saya karena tidak memberikan fleksibilitas pada kode sumber desain. Memeriksa cara kerjanya dengan jsic:

src/main.js

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

src/Form/Input/Tel.js

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

Sekarang kita dapat menjalankan compiler:

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

Dan dapatkan gabungan file

build/main.js

var foo = function() {
    return {
          prop: "",
          method: function(){}
    }
};
Komentar (1)

Jika niat anda untuk load file JavaScript adalah menggunakan fungsi impor/termasuk file, anda juga dapat menentukan objek global dan mengatur fungsi-fungsi sebagai objek item. Misalnya:

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

Anda hanya perlu berhati-hati bila anda termasuk script di file HTML. Order harus seperti di bawah ini:


  <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>
Komentar (0)

Ini harus dilakukan:

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

Atau bukan termasuk saat menjalankan, menggunakan script untuk menggabungkan sebelum meng-upload.

Saya menggunakan Sprocket (I don't tahu jika ada orang lain). Anda membangun kode JavaScript dalam file terpisah dan termasuk komentar yang diproses oleh Sprocket mesin mencakup. Untuk pengembangan anda dapat menyertakan file-file secara berurutan, maka untuk produksi untuk menggabungkan mereka...

Lihat juga:

Komentar (1)

Dalam kasus anda menggunakan Pekerja Web dan ingin memasukkan script tambahan dalam lingkup pekerja, jawaban lain yang disediakan tentang menambahkan script untuk kepala tag, dll. tidak akan bekerja untuk anda.

Untungnya, Web Pekerja mereka sendiri importScripts fungsi yang merupakan fungsi global dalam lingkup Web Pekerja, asli ke browser itu sendiri seperti itu adalah bagian dari spesifikasi.

Atau, sebagai tertinggi kedua sebagai jawaban untuk pertanyaan anda highlight, RequireJS juga dapat menangani termasuk script dalam Web Pekerja (kemungkinan memanggil importScripts itu sendiri, tetapi dengan beberapa fitur berguna lainnya).

Komentar (0)

Saya punya masalah sederhana, tapi saya masih bingung dengan tanggapan terhadap pertanyaan ini.

Aku harus menggunakan variabel (myVar1) didefinisikan dalam satu file JavaScript (myvariables.js) di lain file JavaScript (main.js).

Untuk hal ini saya lakukan sebagai berikut:

Dimuat kode JavaScript dalam HTML file, dalam urutan yang benar, myvariables.js pertama, kemudian main.js:




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



File: myvariables.js

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

File: main.js

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

Seperti yang anda lihat, saya telah menggunakan variabel dalam satu file JavaScript di lain file JavaScript, tapi aku didn't perlu untuk memiliki satu sama lain. Aku hanya perlu memastikan bahwa file JavaScript dimuat sebelum kedua file JavaScript, dan, yang pertama file JavaScript's variabel dapat diakses di kedua file JavaScript, secara otomatis.

Ini menyelamatkan saya di malam hari. Saya harap ini membantu.

Komentar (5)

The @import sintaks untuk mencapai CSS-seperti JavaScript mengimpor mungkin menggunakan alat seperti [Campuran]() melalui special .mix jenis file (lihat di sini). Saya membayangkan aplikasi hanya menggunakan salah satu dari metode tersebut interally, meskipun aku don't tahu.

Dari Campuran dokumentasi .mix file:

Aduk file hanya .js atau .file css dengan .mix. dalam nama file. A aduk file hanya memperluas fungsionalitas dari sebuah gaya normal atau script file dan memungkinkan anda untuk mengimpor dan menggabungkan.

Berikut ini's contoh .mix file yang menggabungkan beberapa .js file menjadi satu:

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

Campuran output ini sebagai scripts-global.js dan juga sebagai versi minified (scripts-global.min.js).

Catatan: saya'm tidak dalam cara apapun berafiliasi dengan Campuran, selain menggunakan itu sebagai front-end development tool. Saya datang di pertanyaan ini setelah melihat .mix file JavaScript dalam tindakan (dalam satu Campuran boilerplates) dan menjadi sedikit bingung dengan hal itu ("anda dapat melakukan hal ini?" saya pikir ke diri sendiri). Kemudian saya menyadari bahwa itu adalah sebuah aplikasi-jenis file tertentu (agak mengecewakan, setuju). Namun demikian, menemukan pengetahuan yang mungkin bermanfaat bagi orang lain.

UPDATE: Campuran gratis (offline).

UPDATE: Campuran sekarang dihentikan. Old campuran rilis masih tersedia

Komentar (2)