Apakah ada sesuatu dalam JavaScript yang mirip dengan @import
di CSS yang memungkinkan Anda untuk memasukkan file JavaScript ke dalam file JavaScript lain?
script
tag yang dipesan ?
Apakah ada sesuatu dalam JavaScript yang mirip dengan @import
di CSS yang memungkinkan Anda untuk memasukkan file JavaScript ke dalam file JavaScript lain?
script
tag yang dipesan ?
Jawaban:
Versi lama JavaScript tidak mengimpor, memasukkan, atau mengharuskan, begitu banyak pendekatan berbeda untuk masalah ini telah dikembangkan.
Tetapi sejak 2015 (ES6), JavaScript telah memiliki standar modul ES6 untuk mengimpor modul di Node.js, yang juga didukung oleh sebagian besar peramban modern .
Untuk kompatibilitas dengan browser yang lebih lama, alat build seperti Webpack dan Rollup dan / atau alat transpilasi seperti Babel dapat digunakan.
Modul ECMAScript (ES6) telah didukung di Node.js sejak v8.5, dengan --experimental-modules
flag, dan setidaknya Node.js v13.8.0 tanpa flag. Untuk mengaktifkan "ESM" (vs. sistem modul CommonJS-gaya sebelumnya Node.js ini [ "CJS"]) Anda baik menggunakan "type": "module"
di package.json
atau memberikan file ekstensi .mjs
. (Demikian pula, modul yang ditulis dengan modul CJS Node.js sebelumnya dapat dinamai .cjs
jika default Anda adalah ESM.)
Menggunakan package.json
:
{
"type": "module"
}
Lalu module.js
:
export function hello() {
return "Hello";
}
Lalu main.js
:
import { hello } from './module.js';
let val = hello(); // val is "Hello";
Dengan menggunakan .mjs
, Anda harus module.mjs
:
export function hello() {
return "Hello";
}
Lalu main.mjs
:
import { hello } from './module.mjs';
let val = hello(); // val is "Hello";
Browser telah mendapat dukungan untuk memuat modul ECMAScript secara langsung (tidak diperlukan alat seperti Webpack) sejak Safari 10.1, Chrome 61, Firefox 60, dan Edge 16. Periksa dukungan saat ini di caniuse . Tidak perlu menggunakan .mjs
ekstensi Node.js ; browser sepenuhnya mengabaikan ekstensi file pada modul / skrip.
<script type="module">
import { hello } from './hello.mjs'; // Or it could be simply `hello.js`
hello('world');
</script>
// hello.mjs -- or it could be simply `hello.js`
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/
Impor dinamis membiarkan skrip memuat skrip lain sesuai kebutuhan:
<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
Gaya modul CJS yang lebih lama, masih banyak digunakan di Node.js, adalah module.exports
/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 memasukkan konten JavaScript eksternal di browser yang tidak memerlukan preprocessing.
Anda dapat memuat skrip tambahan dengan panggilan AJAX dan kemudian gunakan eval
untuk menjalankannya. Ini adalah cara yang paling mudah, tetapi terbatas pada domain Anda karena model keamanan JavaScript sandbox. Menggunakan eval
juga membuka pintu bagi bug, peretasan, dan masalah keamanan.
Seperti Impor dinamis, Anda dapat memuat satu atau banyak skrip dengan fetch
panggilan menggunakan janji untuk mengontrol urutan eksekusi untuk dependensi skrip menggunakan pustaka Inject Ambil :
fetchInject([
'https://cdn.jsdelivr.net/momentjs/2.17.1/moment.min.js'
]).then(() => {
console.log(`Finish in less than ${moment().endOf('year').fromNow(true)}`)
})
The jQuery perpustakaan menyediakan memuat fungsi dalam satu baris :
$.getScript("my_lovely_script.js", function() {
alert("Script loaded but not necessarily executed.");
});
Anda dapat menambahkan tag skrip dengan URL skrip ke dalam HTML. Untuk menghindari overhead jQuery, ini adalah solusi ideal.
Skrip bahkan dapat berada di server yang berbeda. Selanjutnya, browser mengevaluasi kode. The <script>
tag dapat disuntikkan ke dalam 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 <script>
tag baru ke akhir bagian kepala halaman, di mana src
atribut diatur ke URL yang diberikan ke fungsi sebagai parameter pertama.
Kedua solusi ini dibahas dan diilustrasikan dalam JavaScript Madness: Dynamic Script Loading .
Sekarang, ada masalah besar yang harus Anda ketahui. Melakukan hal itu menyiratkan bahwa Anda memuat kode dari jarak jauh . Browser web modern akan memuat file dan terus mengeksekusi skrip Anda saat ini karena mereka memuat semuanya secara tidak sinkron untuk meningkatkan kinerja. (Ini berlaku untuk metode jQuery dan metode pemuatan skrip dinamis manual.)
Ini berarti bahwa jika Anda menggunakan trik ini secara langsung, Anda tidak akan dapat menggunakan kode yang baru dimuat di baris berikutnya setelah Anda memintanya untuk dimuat , karena masih akan memuat.
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 memuat kembali halaman yang sedang dipukul F5. Dan itu berhasil! Membingungkan ...
Jadi apa yang harus dilakukan?
Nah, Anda dapat menggunakan retasan yang disarankan penulis di tautan yang saya berikan kepada Anda. Singkatnya, untuk orang-orang yang terburu-buru, ia menggunakan acara untuk menjalankan fungsi panggilan balik ketika skrip dimuat. Jadi Anda bisa meletakkan semua kode menggunakan pustaka jarak jauh di fungsi panggilan balik. Sebagai contoh:
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 skrip dimuat dalam fungsi lambda :
var myPrettyCode = function() {
// Here, do whatever you want
};
Kemudian Anda jalankan semua itu:
loadScript("my_lovely_script.js", myPrettyCode);
Perhatikan bahwa skrip dapat dijalankan setelah DOM dimuat, atau sebelumnya, tergantung pada browser dan apakah Anda menyertakan baris script.async = false;
. Ada artikel hebat tentang pemuatan Javascript secara umum yang membahas hal ini.
Seperti yang disebutkan di bagian atas jawaban ini, banyak pengembang menggunakan alat build / transpilation (s) seperti Parcel, Webpack, atau Babel dalam proyek mereka, memungkinkan mereka untuk menggunakan sintaks JavaScript yang akan datang, memberikan kompatibilitas ke belakang untuk browser lama, menggabungkan file, memperkecil, melakukan pemecahan kode dll.
onreadystatechange
acara dan readyState
properti). Juga, pemuatan skrip dinamis tidak mendapat manfaat dari pemindai preload dari broswer. Rekomendasikan artikel HTML5Rocks ini: html5rocks.com/en/tutorials/speed/script-loading
Jika ada yang mencari sesuatu yang lebih maju, cobalah RequireJS . Anda akan mendapatkan manfaat tambahan seperti manajemen dependensi, konkurensi yang lebih baik, dan menghindari duplikasi (yaitu, mengambil skrip lebih dari sekali).
Anda dapat menulis file JavaScript di "modul" dan kemudian merujuknya sebagai dependensi di skrip lain. Atau Anda dapat menggunakan RequireJS sebagai solusi "go get this script" sederhana.
Contoh:
Tentukan 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
});
implementasi.js adalah file JavaScript "utama" Anda yang bergantung 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:
Mengharuskan JS memuat file JavaScript biasa serta modul yang lebih jelas. Ini dioptimalkan untuk penggunaan dalam browser, termasuk di Web Worker, tetapi dapat digunakan di lingkungan JavaScript lainnya, seperti Badak dan Node. Ini mengimplementasikan API Modul Asynchronous.
RequireJS menggunakan tag skrip biasa untuk memuat modul / file, sehingga harus memungkinkan untuk debugging mudah. Ini dapat digunakan hanya untuk memuat file JavaScript yang ada, sehingga Anda dapat menambahkannya ke proyek yang ada tanpa harus menulis ulang file JavaScript Anda.
...
Sebenarnya ada cara untuk memuat file JavaScript tidak asinkron, sehingga Anda dapat menggunakan fungsi yang disertakan dalam file yang baru Anda muat setelah memuatnya, dan saya pikir itu berfungsi 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 pada file JavaScript yang diimpor, Firebug (dan juga Firefox Error Console dan Tools Developer Chrome ) akan melaporkan tempatnya secara tidak benar, yang merupakan masalah besar jika Anda menggunakan Firebug untuk melacak Kesalahan JavaScript turun banyak (saya lakukan). Firebug tidak tahu tentang file yang baru dimuat karena suatu alasan, jadi jika terjadi kesalahan pada file itu, ia melaporkan bahwa itu terjadi pada file HTML utama Anda , dan Anda akan kesulitan menemukan alasan sebenarnya untuk kesalahan tersebut.
Tetapi jika itu bukan masalah bagi Anda, maka metode ini akan berhasil.
Saya sebenarnya telah menulis 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 yang perlu Anda lakukan untuk mengimpor JavaScript adalah:
$.import_js('/path_to_project/scripts/somefunctions.js');
Saya juga membuat tes sederhana untuk ini di Contoh .
Ini termasuk main.js
file dalam HTML utama dan kemudian skrip main.js
digunakan $.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()
fungsinya dipanggil, dan Anda mendapatkan peringatan.
(Jawaban ini sebagai respons terhadap komentar e-satis ').
jQuery.getScript
, dengan begitu Anda tidak perlu khawatir menulis plugin ...
script
elemen head
akan menyebabkannya berjalan secara tidak sinkron, kecuali jika async
diatur secara khusus false
.
"
, kode akan rusak
Cara lain, yang menurut saya jauh lebih bersih, adalah dengan membuat permintaan Ajax sinkron daripada menggunakan <script>
tag. Yang juga bagaimana Node.js menangani termasuk.
Berikut ini contoh menggunakan 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);
}
});
}
Anda kemudian dapat menggunakannya dalam kode Anda karena biasanya Anda akan menggunakan sertakan:
require("/scripts/subscript.js");
Dan dapat memanggil fungsi dari skrip yang diperlukan di baris berikutnya:
subscript.doSomethingCool();
async: false
sudah usang. Bukan itu! Seperti kutipan Anda nyatakan, hanya hal-hal terkait jqXHR yang.
Ada kabar baik untuk Anda. Segera Anda akan dapat memuat kode JavaScript dengan mudah. Ini akan menjadi cara standar untuk mengimpor modul kode JavaScript dan akan menjadi bagian dari inti JavaScript itu sendiri.
Anda hanya perlu menulis import cond from 'cond.js';
untuk memuat nama makro cond
dari file cond.js
.
Jadi Anda tidak harus bergantung pada kerangka JavaScript apa pun juga tidak harus secara eksplisit membuat panggilan Ajax .
Mengacu pada:
Dimungkinkan untuk secara dinamis menghasilkan tag JavaScript dan menambahkannya ke dokumen HTML dari dalam kode JavaScript lainnya. Ini akan memuat file JavaScript yang ditargetkan.
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");
js.onload = callback;
Pernyataan import
ada dalam ECMAScript 6.
Sintaksis
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;
Mungkin Anda dapat menggunakan fungsi ini yang saya temukan di halaman ini. Bagaimana cara saya memasukkan file JavaScript ke 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)
}
script.onload = callback;
var
, variabel akan bersifat global?
Ini adalah versi sinkron tanpa 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);
}
Perhatikan bahwa untuk mendapatkan lintas-domain yang berfungsi ini, server perlu mengatur allow-origin
tajuk sebagai jawabannya.
http://web.archive.org/web/20140905044059/http://www.howtocreate.co.uk/operaStuff/userjs/aagmfunctions.js
)
<script>
tag yang dimasukkan , bukan melalui XMLHttpRequest
.
const XMLHttpRequest = Components.Constructor("@mozilla.org/xmlextras/xmlhttprequest;1");
Saya baru saja menulis kode JavaScript ini (menggunakan Prototipe untuk manipulasi 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);
}
});
})();
Pemakaian:
<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>
Intisari: http://gist.github.com/284442 .
Berikut adalah versi umum tentang cara Facebook melakukannya untuk tombol Suka di mana-mana:
<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 itu berfungsi untuk Facebook, itu akan bekerja untuk Anda.
Alasan mengapa kami mencari script
elemen pertama bukan head
atau body
karena beberapa browser tidak membuat satu jika hilang, tetapi kami dijamin memiliki script
elemen - yang ini. Baca lebih lanjut di http://www.jspatterns.com/the-ridiculous-case-of-adding-a-script-element/ .
Jika Anda ingin menggunakan JavaScript murni, Anda dapat menggunakannya document.write
.
document.write('<script src="myscript.js" type="text/javascript"></script>');
Jika Anda menggunakan perpustakaan jQuery, Anda dapat menggunakan $.getScript
metode ini.
$.getScript("another_script.js");
Anda juga dapat merakit skrip 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
Sebagian besar solusi yang ditampilkan di sini menyiratkan pemuatan dinamis. Saya sedang mencari kompiler yang merakit semua file yang tergantung menjadi file output tunggal. Sama seperti Less / Sass preprocessors berurusan dengan aturan CSS @import
. Karena saya tidak menemukan sesuatu yang layak seperti ini, saya menulis alat sederhana untuk menyelesaikan masalah ini.
Jadi di sini adalah kompiler, https://github.com/dsheiko/jsic , yang menggantikan $import("file-path")
dengan konten file yang diminta dengan aman. Berikut ini adalah plugin Grunt yang sesuai : https://github.com/dsheiko/grunt-jsic .
Pada cabang master jQuery, mereka hanya menggabungkan file sumber atom menjadi satu mulai dengan intro.js
dan berakhir dengan outtro.js
. Itu tidak cocok untuk saya karena tidak memberikan fleksibilitas pada desain kode sumber. Lihat 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 kompiler:
node jsic.js src/main.js build/mail.js
Dan dapatkan file gabungannya
build / main.js
var foo = function() {
return {
prop: "",
method: function(){}
}
};
Jika niat Anda untuk memuat file JavaScript menggunakan fungsi dari file yang diimpor / disertakan , Anda juga dapat mendefinisikan objek global dan mengatur fungsi sebagai item objek. Contohnya:
A = {};
A.func1 = function() {
console.log("func1");
}
A.func2 = function() {
console.log("func2");
}
A.func1();
A.func2();
Anda hanya perlu berhati-hati saat memasukkan skrip ke dalam file HTML. Urutannya harus seperti di bawah ini:
<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>
Ini harus dilakukan:
xhr = new XMLHttpRequest();
xhr.open("GET", "/soap/ajax/11.0/connection.js", false);
xhr.send();
eval(xhr.responseText);
eval
adalah apa yang salah dengan itu. Dari Crockford , " eval
adalah kejahatan. eval
Fungsinya adalah fitur JavaScript yang paling banyak disalahgunakan. Hindari itu. eval
Alias. Jangan gunakan Function
konstruktor. Jangan berikan string ke setTimeout
atau setInterval
." Jika Anda belum membaca "JavaScript: The Good Parts" -nya, maka keluarlah dan lakukan sekarang. Anda tidak akan menyesalinya.
http://web.archive.org/web/20140905044059/http://www.howtocreate.co.uk/operaStuff/userjs/aagmfunctions.js
)
Atau alih-alih termasuk pada saat dijalankan, gunakan skrip untuk menyatukan sebelum mengunggah.
Saya menggunakan Sprockets (saya tidak tahu apakah ada yang lain). Anda membuat kode JavaScript dalam file terpisah dan memasukkan komentar yang diproses oleh mesin Sprockets sebagai termasuk. Untuk pengembangan, Anda dapat memasukkan file secara berurutan, kemudian untuk produksi untuk menggabungkannya ...
Lihat juga:
Saya punya masalah sederhana, tetapi saya bingung dengan jawaban atas pertanyaan ini.
Saya harus menggunakan variabel (myVar1) yang didefinisikan dalam satu file JavaScript (myvariables.js) di file JavaScript lain (main.js).
Untuk ini saya lakukan seperti di bawah ini:
Memuat kode JavaScript dalam file HTML, dalam urutan yang benar, myvariables.js pertama, lalu main.js:
<html>
<body onload="bodyReady();" >
<script src="myvariables.js" > </script>
<script src="main.js" > </script>
<!-- Some other code -->
</body>
</html>
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 file JavaScript lain, tapi saya tidak perlu memasukkan satu ke yang lain. Saya hanya perlu memastikan bahwa file JavaScript pertama dimuat sebelum file JavaScript kedua, dan, variabel file JavaScript pertama dapat diakses di file JavaScript kedua, secara otomatis.
Ini menyelamatkan hari saya. Saya harap ini membantu.
import
. Anda memerlukan file HTML untuk mendapatkan barang dari satu file js ke file lainnya.
<script>
tag. Ini dapat membantu organisasi. Jawaban ini bukan pertanyaan yang diajukan, dan tidak ideal dalam konteks ini.
Jika Anda menggunakan Pekerja Web dan ingin menyertakan skrip tambahan dalam lingkup pekerja, jawaban lain yang diberikan tentang menambahkan skrip ke head
tag, dll. Tidak akan berfungsi untuk Anda.
Untungnya, Pekerja Web memiliki importScripts
fungsi mereka sendiri yang merupakan fungsi global dalam lingkup Pekerja Web, asli dari browser itu sendiri karena merupakan bagian dari spesifikasi .
Atau, sebagai jawaban tertinggi kedua untuk menyoroti pertanyaan Anda , RequireJS juga dapat menangani termasuk skrip di dalam Pekerja Web (kemungkinan memanggil importScripts
dirinya sendiri, tetapi dengan beberapa fitur bermanfaat lainnya).
Dalam bahasa modern dengan tanda centang apakah skrip telah dimuat akan menjadi:
function loadJs(url){
return new Promise( (resolve, reject) => {
if (document.querySelector(`head > script[src="${src}"]`) !== null) return resolve()
const script = document.createElement("script")
script.src = url
script.onload = resolve
script.onerror = reject
document.head.appendChild(script)
});
}
Penggunaan (async / menunggu):
try { await loadJs("https://.../script.js") }
catch(error) {console.log(error)}
atau
await loadJs("https://.../script.js").catch(err => {})
Penggunaan (Janji):
loadJs("https://.../script.js").then(res => {}).catch(err => {})
var pi = 3.14
. panggil fungsi loadJS () vialoadJs("pi.js").then(function(){ console.log(pi); });
The @import
sintaks untuk mencapai CSS-seperti mengimpor JavaScript adalah mungkin menggunakan alat seperti Campuran melalui khusus mereka .mix
jenis file (lihat disini ). Saya membayangkan aplikasi hanya menggunakan salah satu metode yang disebutkan di atas secara internal, meskipun saya tidak tahu.
Dari dokumentasi Campuran pada .mix
file:
File campuran hanyalah file .js atau .css dengan .mix. dalam nama file. File campuran hanya memperluas fungsionalitas dari gaya normal atau file skrip dan memungkinkan Anda untuk mengimpor dan menggabungkan.
Berikut ini 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 menghasilkan ini sebagai scripts-global.js
dan juga sebagai versi yang diperkecil (scripts-global.min.js
).
Catatan: Saya sama sekali tidak berafiliasi dengan Mixture, selain menggunakannya sebagai alat pengembangan front-end. Saya menemukan pertanyaan ini setelah melihat .mix
file JavaScript sedang beraksi (di salah satu boilerplture Campuran) dan sedikit bingung olehnya ("Anda bisa melakukan ini?" Saya berpikir sendiri). Kemudian saya menyadari bahwa itu adalah tipe file khusus aplikasi (agak mengecewakan, disetujui). Meskipun demikian, pikir pengetahuan itu mungkin bermanfaat bagi orang lain.
UPDATE : Campuran sekarang gratis (offline).
UPDATE : Campuran sekarang dihentikan. Rilis campuran lama masih tersedia
var js = document.createElement("script");
js.type = "text/javascript";
js.src = jsFilePath;
document.body.appendChild(js);
body
belum ada atau tidak dapat dimodifikasi. Juga membantu menjelaskan jawaban.
Metode saya yang biasa adalah:
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);
}
Ini berfungsi dengan baik dan tidak menggunakan halaman-reload untuk saya. Saya sudah mencoba metode AJAX (salah satu jawaban lain) tetapi tampaknya tidak bekerja dengan baik untuk saya.
Berikut adalah penjelasan tentang bagaimana kode bekerja untuk mereka yang penasaran: pada dasarnya, ini membuat tag skrip baru (setelah yang pertama) dari URL. Ini mengaturnya ke mode asinkron sehingga tidak memblokir sisa kode, tetapi memanggil panggilan balik ketika readyState (keadaan konten yang akan dimuat) berubah menjadi 'dimuat'.
Meskipun jawaban ini bagus, ada "solusi" sederhana yang telah ada sejak pemuatan skrip ada, dan itu akan mencakup 99,999% dari kasus penggunaan kebanyakan orang. Cukup sertakan skrip yang Anda butuhkan sebelum skrip yang membutuhkannya. Untuk sebagian besar proyek, tidak butuh waktu lama untuk menentukan skrip mana yang diperlukan dan dalam urutan apa.
<!DOCTYPE HTML>
<html>
<head>
<script src="script1.js"></script>
<script src="script2.js"></script>
</head>
<body></body>
</html>
Jika script2 membutuhkan script1, ini benar-benar cara termudah untuk melakukan sesuatu seperti ini. Saya sangat terkejut tidak ada yang mengemukakan ini, karena ini adalah jawaban yang paling jelas dan paling sederhana yang akan diterapkan di hampir setiap kasus.
Saya menulis modul sederhana yang mengotomatiskan pekerjaan mengimpor / termasuk skrip modul dalam JavaScript. Untuk penjelasan rinci tentang kode, lihat posting blog JavaScript mengharuskan / impor / sertakan modul .
// ----- 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);
};
Script ini akan menambahkan file JavaScript ke atas <script>
tag lain :
(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);
})();
Ada juga Head.js . Sangat mudah untuk berurusan dengan:
head.load("js/jquery.min.js",
"js/jquery.someplugin.js",
"js/jquery.someplugin.css", function() {
alert("Everything is ok!");
});
Seperti yang Anda lihat, ini lebih mudah daripada Require.js dan senyaman $.getScript
metode jQuery . Ini juga memiliki beberapa fitur canggih, seperti pemuatan bersyarat, deteksi fitur dan banyak lagi .
Ada banyak jawaban potensial untuk pertanyaan ini. Jawaban saya jelas berdasarkan sejumlah dari mereka. Inilah yang akhirnya saya baca setelah membaca semua jawaban.
Masalah dengan $.getScript
dan benar-benar solusi lain yang memerlukan panggilan balik saat memuat selesai adalah bahwa jika Anda memiliki banyak file yang menggunakannya dan saling bergantung satu sama lain, Anda tidak lagi memiliki cara untuk mengetahui kapan semua skrip telah dimuat (setelah mereka disarangkan dalam banyak file).
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...
});
Anda benar ketika mengatakan bahwa Anda dapat menentukan Ajax untuk berjalan secara sinkron atau menggunakan XMLHttpRequest , tetapi tren saat ini tampaknya untuk menolak permintaan sinkron, sehingga Anda mungkin tidak mendapatkan dukungan browser penuh sekarang atau di masa depan.
Anda dapat mencoba menggunakan $.when
untuk memeriksa array objek yang ditangguhkan, tetapi sekarang Anda melakukan ini di setiap file dan file2 akan dianggap dimuat segera setelah $.when
dieksekusi bukan ketika callback dieksekusi, jadi file1 masih melanjutkan eksekusi sebelum file3 dimuat . Ini benar-benar masih memiliki masalah yang sama.
Saya memutuskan untuk mundur daripada maju. Terima kasih document.writeln
. Saya tahu itu hal yang tabu, tetapi selama digunakan dengan benar, ini bekerja dengan baik. Anda berakhir dengan kode yang dapat didebug dengan mudah, ditampilkan di DOM dengan benar dan dapat memastikan urutan ketergantungan dimuat dengan benar.
Anda tentu saja dapat menggunakan $ ("body"). Append (), tetapi kemudian Anda tidak dapat lagi melakukan debug dengan benar.
CATATAN: Anda harus menggunakan ini hanya saat halaman dimuat, jika tidak, Anda mendapatkan layar kosong. Dengan kata lain, selalu tempatkan ini sebelum / di luar dokumen . Sudah . Saya belum diuji menggunakan ini setelah halaman dimuat dalam acara klik atau semacamnya, tapi saya cukup yakin itu akan gagal.
Saya menyukai gagasan memperluas jQuery, tetapi jelas Anda tidak perlu melakukannya.
Sebelum menelepon document.writeln
, ini memeriksa untuk memastikan skrip belum memuat dengan mengevaluasi semua elemen skrip.
Saya berasumsi bahwa skrip tidak sepenuhnya dieksekusi sampai document.ready
acaranya telah dieksekusi. (Saya tahu menggunakan document.ready
tidak diperlukan, tetapi banyak orang menggunakannya, dan menangani ini adalah perlindungan.)
Ketika file-file tambahan dimuat, document.ready
callback akan dieksekusi dalam urutan yang salah. Untuk mengatasi ini ketika skrip benar-benar dimuat, skrip yang mengimpornya diimpor kembali sendiri dan eksekusi dihentikan. Ini menyebabkan file asal sekarang memiliki document.ready
callback yang dieksekusi setelah skrip apa pun yang diimpornya.
Alih-alih pendekatan ini, Anda bisa mencoba memodifikasi jQuery readyList
, tetapi ini sepertinya solusi yang lebih buruk.
Larutan:
$.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;
}
});
Pemakaian:
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"
});
Ada beberapa cara untuk mengimplementasikan modul dalam Javascript, Berikut adalah 2 yang paling populer:
Browser belum mendukung sistem moduling ini sehingga agar Anda dapat menggunakan sintaks ini, Anda harus menggunakan bundler seperti webpack. Lagi pula, menggunakan bundler lebih baik karena ini dapat menggabungkan semua file Anda yang berbeda menjadi satu (atau beberapa pasangan) file. Ini akan melayani file-file dari server ke klien lebih cepat karena setiap permintaan HTTP memiliki beberapa overhead terkait yang menyertainya. Jadi dengan mengurangi permintaan HTTP secara keseluruhan, kami meningkatkan kinerjanya. Berikut adalah contoh modul 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
Sistem moduling ini digunakan di NodeJS. Anda pada dasarnya menambahkan ekspor Anda ke objek yang disebut module.exports
. Anda kemudian dapat mengakses objek ini melalui a require('modulePath')
. Penting di sini adalah untuk menyadari bahwa modul-modul ini sedang di-cache, jadi jika Anda require()
modul tertentu dua kali akan mengembalikan modul yang sudah dibuat.
// 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
Saya sampai pada pertanyaan ini karena saya sedang mencari cara sederhana untuk memelihara koleksi plugin JavaScript yang berguna. Setelah melihat beberapa solusi di sini, saya datang dengan ini:
Siapkan file yang disebut "plugins.js" (atau extensions.js atau apa pun yang Anda inginkan). Simpan file plugin Anda bersama dengan satu file master itu.
plugins.js akan memiliki array bernama pluginNames[]
yang akan kita iterate each()
, kemudian tambahkan <script>
tag ke kepala untuk setiap plugin
//set array to be updated when we add or remove plugin files
var pluginNames = ["lettering", "fittext", "butterjam", etc.];
//one script tag for each plugin
$.each(pluginNames, function(){
$('head').append('<script src="js/plugins/' + this + '.js"></script>');
});
<script src="js/plugins/plugins.js"></script>
TAPI:
Meskipun semua plugin dimasukkan ke tag kepala seperti seharusnya, mereka tidak selalu dijalankan oleh browser saat Anda mengklik halaman atau menyegarkan.
Saya menemukan ini lebih dapat diandalkan untuk hanya menulis tag skrip di PHP. Anda hanya perlu menulisnya sekali dan itu sama artinya dengan memanggil plugin menggunakan JavaScript.