@import
다른 JavaScript 파일에 JavaScript 파일을 포함시킬 수있는 CSS 와 유사한 JavaScript가 있습니까?
script
태그 를 사용하여 선언하지 않겠습니까?
@import
다른 JavaScript 파일에 JavaScript 파일을 포함시킬 수있는 CSS 와 유사한 JavaScript가 있습니까?
script
태그 를 사용하여 선언하지 않겠습니까?
답변:
이전 버전의 JavaScript에는 가져 오기, 포함 또는 필요가 없었으므로이 문제에 대한 다양한 접근 방식이 개발되었습니다.
그러나 2015 년 (ES6) 이후 JavaScript는 Node.js에서 모듈을 가져 오기 위한 ES6 모듈 표준을 가지고 있으며 대부분의 최신 브라우저 에서도 지원됩니다 .
구형 브라우저와의 호환성을 위해 Webpack 및 Rollup 과 같은 빌드 도구 및 / 또는 Babel 과 같은 변환 툴을 사용할 수 있습니다.
ECMAScript (ES6) 모듈은 플래그 가있는 v8.5 이후 및 플래그가없는 Node.js v13.8.0 이상부터 Node.js 에서 지원 되었습니다 --experimental-modules
. "ESM"(Node.js를의 이전 CommonJS 스타일의 모듈 시스템 대 [ "CJS"]) 당신이 중 하나를 사용하도록 설정하려면 "type": "module"
에서를 package.json
하거나 파일 확장자를 제공합니다 .mjs
. ( .cjs
기본적으로 ESM이면 Node.js의 이전 CJS 모듈로 작성된 모듈의 이름을 지정할 수 있습니다 .)
사용 package.json
:
{
"type": "module"
}
그런 다음 module.js
:
export function hello() {
return "Hello";
}
그런 다음 main.js
:
import { hello } from './module.js';
let val = hello(); // val is "Hello";
를 사용 .mjs
하면 다음이 가능합니다 module.mjs
.
export function hello() {
return "Hello";
}
그런 다음 main.mjs
:
import { hello } from './module.mjs';
let val = hello(); // val is "Hello";
브라우저는 Safari 10.1, Chrome 61, Firefox 60 및 Edge 16 이후 ECMAScript 모듈을 직접로드 할 수 있습니다 (웹팩과 같은 도구는 필요 없음) . caniuse 에서 현재 지원을 확인하십시오 . Node.js의 .mjs
확장명 을 사용할 필요는 없습니다 . 브라우저는 모듈 / 스크립트의 파일 확장자를 완전히 무시합니다.
<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);
}
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에서 여전히 널리 사용되는 이전 CJS 모듈 스타일은 module.exports
/require
시스템입니다.
// mymodule.js
module.exports = {
hello: function() {
return "Hello";
}
}
// server.js
const myModule = require('./mymodule');
let val = myModule.hello(); // val is "Hello"
JavaScript가 전처리를 요구하지 않는 브라우저에 외부 JavaScript 컨텐츠를 포함시키는 다른 방법이 있습니다.
AJAX 호출로 추가 스크립트를로드 한 다음이를 사용 eval
하여 실행할 수 있습니다. 가장 간단한 방법이지만 JavaScript 샌드 박스 보안 모델로 인해 도메인으로 제한됩니다. 를 사용하면 eval
버그, 해킹 및 보안 문제가 발생할 수 있습니다.
동적 가져 오기와 마찬가지로 Fetch Inject 라이브러리를 fetch
사용하여 스크립트 종속성에 대한 실행 순서를 제어하는 약속을 사용하여 하나 이상의 스크립트를 호출하여 로드 할 수 있습니다 .
fetchInject([
'https://cdn.jsdelivr.net/momentjs/2.17.1/moment.min.js'
]).then(() => {
console.log(`Finish in less than ${moment().endOf('year').fromNow(true)}`)
})
의 jQuery 라이브러리 로딩 기능을 제공 한 줄에 :
$.getScript("my_lovely_script.js", function() {
alert("Script loaded but not necessarily executed.");
});
스크립트 URL이있는 스크립트 태그를 HTML에 추가 할 수 있습니다. jQuery의 오버 헤드를 피하기 위해 이상적인 솔루션입니다.
스크립트는 다른 서버에 상주 할 수도 있습니다. 또한 브라우저는 코드를 평가합니다. <script>
태그 중 하나의 웹 페이지로 주입 될 수있는 <head>
, 혹은 그저 폐쇄 전에 삽입 </body>
태그.
이것이 어떻게 작동하는지에 대한 예는 다음과 같습니다.
function dynamicallyLoadScript(url) {
var script = document.createElement("script"); // create a script DOM node
script.src = url; // set its src to the provided URL
document.head.appendChild(script); // add it to the end of the head section of the page (could change 'head' to 'body' to add it to the end of the body section instead)
}
이 함수는 <script>
페이지의 헤드 섹션 끝에 새 태그를 추가합니다 . 여기서 src
속성은 함수에 첫 번째 매개 변수로 제공되는 URL로 설정됩니다.
이러한 솔루션은 모두 JavaScript Madness : Dynamic Script Loading에 설명되어 있습니다.
이제 알아야 할 큰 문제가 있습니다. 그렇게하면 원격으로 코드를로드 할 수 있습니다 . 최신 웹 브라우저는 성능을 향상시키기 위해 모든 것을 비동기식으로로드하기 때문에 파일을로드하고 현재 스크립트를 계속 실행합니다. (이는 jQuery 메소드와 수동 동적 스크립트로드 메소드 모두에 적용됩니다.)
즉, 이러한 트릭을 직접 사용하는 경우 새로로드 된 코드를로드 요청 후 다음 줄에서 사용할 수 없습니다 .로드가 계속 진행 중이기 때문입니다.
예를 들면 다음과 같습니다. my_lovely_script.js
contains MySuperObject
:
var js = document.createElement("script");
js.type = "text/javascript";
js.src = jsFilePath;
document.body.appendChild(js);
var s = new MySuperObject();
Error : MySuperObject is undefined
그런 다음 치는 페이지를 다시로드하십시오 F5. 그리고 작동합니다! 혼란스러운 ...
그래서 어떻게해야합니까?
글쎄, 당신은 내가 준 링크에서 저자가 제안한 해킹을 사용할 수 있습니다. 요약하자면, 급한 사람들을 위해, 그는 스크립트가로드 될 때 이벤트를 사용하여 콜백 함수를 실행합니다. 따라서 콜백 함수에서 원격 라이브러리를 사용하여 모든 코드를 넣을 수 있습니다. 예를 들면 다음과 같습니다.
function loadScript(url, callback)
{
// Adding the script tag to the head as suggested before
var head = document.head;
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;
// Then bind the event to the callback function.
// There are several events for cross browser compatibility.
script.onreadystatechange = callback;
script.onload = callback;
// Fire the loading
head.appendChild(script);
}
그런 다음 스크립트가 람다 함수에 로드 된 후 사용하려는 코드를 작성하십시오 .
var myPrettyCode = function() {
// Here, do whatever you want
};
그런 다음 모든 것을 실행하십시오.
loadScript("my_lovely_script.js", myPrettyCode);
스크립트는 브라우저가로드 된 후 또는 라인 포함 여부에 따라 DOM이로드 된 후 또는 이전에 실행될 수 있습니다 script.async = false;
. Javascript 로딩에 대한 훌륭한 기사 가 있습니다 .
이 답변의 맨 위에 언급했듯이 많은 개발자는 프로젝트에서 Parcel, Webpack 또는 Babel과 같은 빌드 / 번역 도구를 사용하여 향후 JavaScript 구문을 사용하고, 이전 브라우저에 대한 하위 호환성을 제공하고, 파일을 결합하고, 축소하고, 코드 분할 등을 수행하십시오.
onreadystatechange
이벤트 및 readyState
속성)를 약간 수정해야합니다 . 또한 동적 스크립트 로딩은 브라우저의 사전로드 스캐너에서 도움이되지 않습니다. 이 HTML5Rocks 기사를 추천하십시오 : html5rocks.com/en/tutorials/speed/script-loading
더 진보 된 것을 찾는 사람이라면 RequireJS를 사용해보십시오 . 종속성 관리, 동시성 향상 및 복제 방지 (스크립트를 두 번 이상 검색)와 같은 추가 이점을 얻을 수 있습니다.
"모듈"로 JavaScript 파일을 작성한 다음 다른 스크립트에서 종속성으로 참조 할 수 있습니다. 또는 RequireJS를 간단한 "이 스크립트 가져 오기"솔루션으로 사용할 수 있습니다.
예:
종속성을 모듈로 정의하십시오.
some-dependency.js
define(['lib/dependency1', 'lib/dependency2'], function (d1, d2) {
//Your actual script goes here.
//The dependent scripts will be fetched if necessary.
return libraryObject; //For example, jQuery object
});
implementation.js 는 some-dependency.js에 의존 하는 "기본"JavaScript 파일입니다.
require(['some-dependency'], function(dependency) {
//Your script goes here
//some-dependency.js is fetched.
//Then your script is executed
});
GitHub 읽어보기 에서 발췌 :
RequireJS는 일반 JavaScript 파일과 더 정의 된 모듈을로드합니다. 웹 워커를 포함하여 브라우저 내 사용에 최적화되어 있지만 Rhino 및 Node와 같은 다른 JavaScript 환경에서 사용할 수 있습니다. 비동기 모듈 API를 구현합니다.
RequireJS는 일반 스크립트 태그를 사용하여 모듈 / 파일을로드하므로 쉽게 디버깅 할 수 있습니다. 기존 JavaScript 파일을로드하는 데 간단히 사용할 수 있으므로 JavaScript 파일 을 다시 쓰지 않고도 기존 프로젝트에 파일 을 추가 할 수 있습니다.
...
실제로이 있다 자바 스크립트 파일을로드 할 수있는 방법 하지 당신이 그것을로드 한 후 새로로드 된 파일 오른쪽에 포함 된 기능을 사용할 수 있도록, 비동기, 그리고 나는 그것이 모든 브라우저에서 작동합니다 생각합니다.
페이지 요소에서 다음 을 사용해야 jQuery.append()
합니다 <head>
.
$("head").append('<script type="text/javascript" src="' + script + '"></script>');
그러나이 방법에도 문제가 있습니다. 가져온 JavaScript 파일에서 오류가 발생하면 Firebug (및 Firefox 오류 콘솔 및 Chrome 개발자 도구 )도 잘못된 위치를보고하므로 Firebug를 사용하여 추적하는 경우 큰 문제입니다 JavaScript 오류가 많이 발생합니다 (그렇습니다). Firebug는 어떤 이유로 새로로드 된 파일에 대해 단순히 알지 못하므로 해당 파일에서 오류가 발생하면 기본 HTML 파일 에서 발생한 것으로보고 하여 오류의 실제 원인을 찾는 데 어려움을 겪습니다.
그러나 이것이 문제가되지 않으면이 방법이 효과적입니다.
실제로이 방법을 사용하는 $ .import_js () 라는 jQuery 플러그인을 작성했습니다 .
(function($)
{
/*
* $.import_js() helper (for JavaScript importing within JavaScript code).
*/
var import_js_imported = [];
$.extend(true,
{
import_js : function(script)
{
var found = false;
for (var i = 0; i < import_js_imported.length; i++)
if (import_js_imported[i] == script) {
found = true;
break;
}
if (found == false) {
$("head").append('<script type="text/javascript" src="' + script + '"></script>');
import_js_imported.push(script);
}
}
});
})(jQuery);
따라서 JavaScript를 가져 오려면 다음을 수행하십시오.
$.import_js('/path_to_project/scripts/somefunctions.js');
또한 Example 에서 간단한 테스트를 수행했습니다 .
main.js
기본 HTML에 파일 이 포함 된 다음 스크립트 가 추가 파일을 가져 오는 main.js
데 사용 $.import_js()
합니다.included.js
합니다.이 은이 함수를 정의합니다.
function hello()
{
alert("Hello world!");
}
그리고 포함 직후 included.js
에 hello()
함수가 호출되고 경고가 표시됩니다.
(이 답변은 e-satis의 의견에 대한 답변입니다).
jQuery.getScript
하면 플러그인 작성에 대해 걱정할 필요가 없습니다.
"
코드가 작동하지 않습니다
내 의견으로는 훨씬 깨끗하다는 또 다른 방법은 <script>
태그 를 사용하는 대신 동기 Ajax 요청을하는 것입니다 . 또한 어떻게Node.js 가 include를 처리 있습니다.
다음은 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);
}
});
}
그런 다음 일반적으로 include를 사용할 때 코드에서 사용할 수 있습니다.
require("/scripts/subscript.js");
다음 줄에서 필요한 스크립트에서 함수를 호출 할 수 있습니다.
subscript.doSomethingCool();
async: false
. 그렇지 않습니다! 귀하의 견적에 따르면 jqXHR 관련 항목 만 있습니다.
좋은 소식이 있습니다. 곧 JavaScript 코드를 쉽게로드 할 수 있습니다. JavaScript 코드 모듈을 가져 오는 표준 방법이되고 핵심 JavaScript 자체의 일부가됩니다.
파일에서 import cond from 'cond.js';
이름이 지정된 매크로를로드 하기 만하면 cond
됩니다 cond.js
.
따라서 JavaScript 프레임 워크에 의존하거나 Ajax 호출 을 명시 적으로 지정할 필요가 없습니다 .
인용하다:
JavaScript 태그를 동적으로 생성하여 다른 JavaScript 코드 내부에서 HTML 문서에 추가 할 수 있습니다. 타겟 JavaScript 파일이로드됩니다.
function includeJs(jsFilePath) {
var js = document.createElement("script");
js.type = "text/javascript";
js.src = jsFilePath;
document.body.appendChild(js);
}
includeJs("/path/to/some/file.js");
js.onload = callback;
명령문 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;
이 페이지에서 찾은이 기능을 사용할 수 있습니다 . 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)
}
script.onload = callback;
var
변수는 전역입니까?
다음은 jQuery 가없는 동기 버전입니다 .
function myRequire( url ) {
var ajax = new XMLHttpRequest();
ajax.open( 'GET', url, false ); // <-- the 'false' makes it synchronous
ajax.onreadystatechange = function () {
var script = ajax.response || ajax.responseText;
if (ajax.readyState === 4) {
switch( ajax.status) {
case 200:
eval.apply( window, [script] );
console.log("script loaded: ", url);
break;
default:
console.log("ERROR: script not loaded: ", url);
}
}
};
ajax.send(null);
}
이 작동하는 도메인 간을 가져 오려면 서버가 allow-origin
응답에 헤더 를 설정해야합니다 .
http://web.archive.org/web/20140905044059/http://www.howtocreate.co.uk/operaStuff/userjs/aagmfunctions.js
)
<script>
태그 를 통해서만 스크립트를로드 할 수 있습니다 XMLHttpRequest
.
const XMLHttpRequest = Components.Constructor("@mozilla.org/xmlextras/xmlhttprequest;1");
난 그냥 (사용하여이 자바 스크립트 코드 작성 프로토 타입을 위한 DOM의 조작을) :
var require = (function() {
var _required = {};
return (function(url, callback) {
if (typeof url == 'object') {
// We've (hopefully) got an array: time to chain!
if (url.length > 1) {
// Load the nth file as soon as everything up to the
// n-1th one is done.
require(url.slice(0, url.length - 1), function() {
require(url[url.length - 1], callback);
});
} else if (url.length == 1) {
require(url[0], callback);
}
return;
}
if (typeof _required[url] == 'undefined') {
// Haven't loaded this URL yet; gogogo!
_required[url] = [];
var script = new Element('script', {
src: url,
type: 'text/javascript'
});
script.observe('load', function() {
console.log("script " + url + " loaded.");
_required[url].each(function(cb) {
cb.call(); // TODO: does this execute in the right context?
});
_required[url] = true;
});
$$('head')[0].insert(script);
} else if (typeof _required[url] == 'boolean') {
// We already loaded the thing, so go ahead.
if (callback) {
callback.call();
}
return;
}
if (callback) {
_required[url].push(callback);
}
});
})();
용법:
<script src="prototype.js"></script>
<script src="require.js"></script>
<script>
require(['foo.js','bar.js'], function () {
/* Use foo.js and bar.js here */
});
</script>
다음은 Facebook의 유비쿼터스 좋아요 버튼에 대해 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/ 에서 자세히 알아보십시오 .
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
여기에 표시된 대부분의 솔루션은 동적 로딩을 의미합니다. 대신 모든 종속 파일을 단일 출력 파일로 어셈블하는 컴파일러를 찾고있었습니다. 과 동일한 이하 / 말대꾸의 는 CSS와 전처리 거래@import
에서 규칙. 나는 이런 종류의 적절한 것을 찾지 못했기 때문에 문제를 해결하는 간단한 도구를 작성했습니다.
따라서 https://github.com/dsheiko/jsic 컴파일러 $import("file-path")
는 요청 된 파일 내용으로 안전하게 대체 됩니다. 해당 Grunt 플러그인 은 다음과 같습니다 . https://github.com/dsheiko/grunt-jsic .
jQuery 마스터 브랜치에서는 원자 소스 파일을로 시작 intro.js
하고 끝나는 단일 소스 파일로 간단히 연결합니다 outtro.js
. 소스 코드 디자인에 유연성이 없기 때문에 나에게 적합하지 않습니다. jsic과의 작동 방식을 확인하십시오.
src / main.js
var foo = $import("./Form/Input/Tel");
src / 양식 / 입력 /Tel.js
function() {
return {
prop: "",
method: function(){}
}
}
이제 컴파일러를 실행할 수 있습니다 :
node jsic.js src/main.js build/mail.js
그리고 결합 된 파일을 얻으십시오
빌드 / 메인 .js
var foo = function() {
return {
prop: "",
method: function(){}
}
};
JavaScript 파일을로드하려는 의도가 가져 오거나 포함 된 파일의 함수를 사용하는 경우 경우 전역 오브젝트를 정의하고 함수를 오브젝트 항목으로 설정할 수도 있습니다. 예를 들어 :
A = {};
A.func1 = function() {
console.log("func1");
}
A.func2 = function() {
console.log("func2");
}
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>
이것은해야합니다 :
xhr = new XMLHttpRequest();
xhr.open("GET", "/soap/ajax/11.0/connection.js", false);
xhr.send();
eval(xhr.responseText);
eval
그것이 뭐가 잘못이다. 에서 크록 포드 , " eval
악은.입니다 eval
. 그것을 피하십시오. 기능은 자바 스크립트의 가장 잘못 사용 기능입니다 eval
별명이 있습니다. 사용하지 마십시오 Function
. 생성자에 문자열을 전달하지 않습니다 setTimeout
나 setInterval
." "자바 스크립트 : 좋은 부분"을 읽지 않았다면 지금 나가십시오. 당신은 것입니다 그것을 후회하지.
http://web.archive.org/web/20140905044059/http://www.howtocreate.co.uk/operaStuff/userjs/aagmfunctions.js
)
또는 런타임에 포함하는 대신 스크립트를 사용하여 업로드하기 전에 연결하십시오.
나는 스프로킷을 사용한다 (다른 것이 있는지 모르겠습니다). 별도의 파일로 JavaScript 코드를 작성하고 Sprockets 엔진에서 처리 한 주석을 포함으로 포함시킵니다. 개발을 위해 파일을 순차적으로 포함시킨 다음 프로덕션 환경에서 파일을 병합 할 수 있습니다.
또한보십시오:
나는 간단한 문제가 있었지만이 질문에 대한 답변으로 당황했다.
한 JavaScript 파일 (myvariables.js)에 정의 된 변수 (myVar1)를 다른 JavaScript 파일 (main.js)을 사용해야했습니다.
이를 위해 다음과 같이했습니다.
HTML 파일에서 JavaScript 코드를 올바른 순서로 myvariables.js에 이어 main.js에로드했습니다.
<html>
<body onload="bodyReady();" >
<script src="myvariables.js" > </script>
<script src="main.js" > </script>
<!-- Some other code -->
</body>
</html>
파일 : myvariables.js
var myVar1 = "I am variable from myvariables.js";
파일 : main.js
// ...
function bodyReady() {
// ...
alert (myVar1); // This shows "I am variable from myvariables.js", which I needed
// ...
}
// ...
보시다시피 한 JavaScript 파일의 변수를 다른 JavaScript 파일의 변수를 사용했지만 다른 변수를 포함 할 필요는 없었습니다. 방금 첫 번째 JavaScript 파일이 두 번째 JavaScript 파일보다 먼저로드되고 첫 번째 JavaScript 파일의 변수에 두 번째 JavaScript 파일에서 자동으로 액세스 할 수 있는지 확인해야했습니다.
이것은 나의 하루를 구했다. 이게 도움이 되길 바란다.
import
입니다. 한 js 파일에서 다른 js 파일로 물건을 가져 오려면 HTML 파일이 필요합니다.
<script>
태그 만 갖는 것이 도움이됩니다 . 이것은 조직에 도움이 될 수 있습니다. 이 답변은 단순히 질문이 요구 한 것이 아니며,이 맥락에서 이상적이지 않습니다.
웹 워커를 사용 중이고 워커 범위에 추가 스크립트를 포함하려는 경우 head
태그에 스크립트를 추가하는 등의 다른 답변 은 작동하지 않습니다.
다행히도 웹 워커 는 사양의 일부인 브라우저 자체에 고유 한 웹 워커 범위의 글로벌 기능인 자체 importScripts
기능 을 가지고 있습니다 .
또는 (가) 두 번째로 높은 질문 하이라이트에 대답을 투표로 , RequireJS는 또한 웹 노동자 (가능성이 호출 내부에 스크립트를 포함하여 처리 할 수 importScripts
있지만, 몇 가지 다른 유용한 기능으로, 자신을).
스크립트가 이미로드되어 있는지 확인하는 현대 언어에서는 다음과 같습니다.
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)
});
}
사용법 (비동기 / 대기) :
try { await loadJs("https://.../script.js") }
catch(error) {console.log(error)}
또는
await loadJs("https://.../script.js").catch(err => {})
사용법 (약속) :
loadJs("https://.../script.js").then(res => {}).catch(err => {})
var pi = 3.14
. 경유 () 함수를 호출 loadJSloadJs("pi.js").then(function(){ console.log(pi); });
@import
자바 스크립트 가져 오기는 그들의 특별한 통해 혼합물 같은 도구를 사용하여 가능처럼 CSS는-달성하기위한 구문 .mix
파일 형식 (참조 여기 ). 나는 응용 프로그램이 단순히 위에서 언급 한 방법 중 하나를 내부적으로 사용한다고 생각합니다.
.mix
파일 의 혼합물 설명서에서 :
믹스 파일은 단순히 .js가 포함 된 .js 또는 .css 파일입니다. 파일 이름에. 믹스 파일은 단순히 일반 스타일 또는 스크립트 파일의 기능을 확장하여 가져오고 결합 할 수있게합니다.
다음 .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를 프론트 엔드 개발 도구로 사용하는 것 외에는 어떤 방식으로도 Mixture와 제휴하지 않습니다. .mix
JavaScript 파일이 (Mixture 상용구 중 하나에서) 작동하고 약간 혼란스러워 보이는 것을보고이 질문에 부딪 쳤습니다 ( "당신은 이것을 할 수 있습니까?"라고 생각했습니다). 그런 다음 응용 프로그램 별 파일 형식이라는 것을 깨달았습니다 (약간 실망스럽고 동의했습니다). 그럼에도 불구하고 지식이 다른 사람들에게 도움이 될 것이라고 생각했습니다.
업데이트 : 혼합물은 이제 무료입니다 (오프라인).
업데이트 : 혼합물이 중단되었습니다. 오래된 혼합물 방출 은 여전히 유효합니다
var js = document.createElement("script");
js.type = "text/javascript";
js.src = jsFilePath;
document.body.appendChild(js);
body
합니다 . 또한 답변을 설명하는 데 도움이됩니다.
내 일반적인 방법은 다음과 같습니다
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 (로드 할 내용의 상태)가 'loaded'로 변경되면 콜백을 호출합니다.
이러한 답변은 훌륭하지만 스크립트로드가 존재 한 이후로 존재하는 간단한 "솔루션"이 있으며 대부분의 사람들이 사용하는 사례의 99.999 %를 차지합니다. 필요한 스크립트 앞에 필요한 스크립트를 포함시키기 만하면됩니다. 대부분의 프로젝트에서 필요한 스크립트와 순서를 결정하는 데 시간이 오래 걸리지 않습니다.
<!DOCTYPE HTML>
<html>
<head>
<script src="script1.js"></script>
<script src="script2.js"></script>
</head>
<body></body>
</html>
script2에 script1이 필요한 경우 실제로 이와 같은 작업을 수행하는 가장 쉬운 방법입니다. 거의 모든 경우에 적용되는 가장 분명하고 간단한 답변이기 때문에 아무도 이것을 제기하지 않은 것에 매우 놀랐습니다.
JavaScript로 모듈 스크립트 가져 오기 / 포함 작업을 자동화하는 간단한 모듈을 작성했습니다. 코드에 대한 자세한 설명은 블로그 게시물 JavaScript require / import / include 모듈을 참조하십시오 .
// ----- USAGE -----
require('ivar.util.string');
require('ivar.net.*');
require('ivar/util/array.js');
require('http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js');
ready(function(){
//Do something when required scripts are loaded
});
//--------------------
var _rmod = _rmod || {}; //Require module namespace
_rmod.LOADED = false;
_rmod.on_ready_fn_stack = [];
_rmod.libpath = '';
_rmod.imported = {};
_rmod.loading = {
scripts: {},
length: 0
};
_rmod.findScriptPath = function(script_name) {
var script_elems = document.getElementsByTagName('script');
for (var i = 0; i < script_elems.length; i++) {
if (script_elems[i].src.endsWith(script_name)) {
var href = window.location.href;
href = href.substring(0, href.lastIndexOf('/'));
var url = script_elems[i].src.substring(0, script_elems[i].length - script_name.length);
return url.substring(href.length+1, url.length);
}
}
return '';
};
_rmod.libpath = _rmod.findScriptPath('script.js'); //Path of your main script used to mark
//the root directory of your library, any library.
_rmod.injectScript = function(script_name, uri, callback, prepare) {
if(!prepare)
prepare(script_name, uri);
var script_elem = document.createElement('script');
script_elem.type = 'text/javascript';
script_elem.title = script_name;
script_elem.src = uri;
script_elem.async = true;
script_elem.defer = false;
if(!callback)
script_elem.onload = function() {
callback(script_name, uri);
};
document.getElementsByTagName('head')[0].appendChild(script_elem);
};
_rmod.requirePrepare = function(script_name, uri) {
_rmod.loading.scripts[script_name] = uri;
_rmod.loading.length++;
};
_rmod.requireCallback = function(script_name, uri) {
_rmod.loading.length--;
delete _rmod.loading.scripts[script_name];
_rmod.imported[script_name] = uri;
if(_rmod.loading.length == 0)
_rmod.onReady();
};
_rmod.onReady = function() {
if (!_rmod.LOADED) {
for (var i = 0; i < _rmod.on_ready_fn_stack.length; i++){
_rmod.on_ready_fn_stack[i]();
});
_rmod.LOADED = true;
}
};
_.rmod = namespaceToUri = function(script_name, url) {
var np = script_name.split('.');
if (np.getLast() === '*') {
np.pop();
np.push('_all');
}
if(!url)
url = '';
script_name = np.join('.');
return url + np.join('/')+'.js';
};
//You can rename based on your liking. I chose require, but it
//can be called include or anything else that is easy for you
//to remember or write, except "import", because it is reserved
//for future use.
var require = function(script_name) {
var uri = '';
if (script_name.indexOf('/') > -1) {
uri = script_name;
var lastSlash = uri.lastIndexOf('/');
script_name = uri.substring(lastSlash+1, uri.length);
}
else {
uri = _rmod.namespaceToUri(script_name, ivar._private.libpath);
}
if (!_rmod.loading.scripts.hasOwnProperty(script_name)
&& !_rmod.imported.hasOwnProperty(script_name)) {
_rmod.injectScript(script_name, uri,
_rmod.requireCallback,
_rmod.requirePrepare);
}
};
var ready = function(fn) {
_rmod.on_ready_fn_stack.push(fn);
};
이 스크립트는 다른 <script>
태그 의 맨 위에 JavaScript 파일을 추가합니다 .
(function () {
var li = document.createElement('script');
li.type = 'text/javascript';
li.src= "http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js";
li.async=true;
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(li, s);
})();
이 질문에 대한 많은 잠재적 인 답변이 있습니다. 내 대답은 분명히 여러 가지를 기반으로합니다. 이것이 모든 답변을 읽은 후에 끝내는 것입니다.
$.getScript
로딩이 완료되었을 때 콜백이 필요한 다른 해결책 의 문제 는 파일을 사용하고 서로 의존하는 여러 파일이 있으면 더 이상 모든 스크립트가로드 된 시점을 알 수있는 방법이 없다는 것입니다. 여러 파일로).
file3.js
var f3obj = "file3";
// Define other stuff
file2.js :
var f2obj = "file2";
$.getScript("file3.js", function(){
alert(f3obj);
// Use anything defined in file3.
});
file1.js :
$.getScript("file2.js", function(){
alert(f3obj); //This will probably fail because file3 is only guaranteed to have loaded inside the callback in file2.
alert(f2obj);
// Use anything defined in the loaded script...
});
Ajax를 지정하여 동기식으로 실행하거나 XMLHttpRequest를 사용할 수 있다고 말할 때 . 그러나 현재 추세는 동기식 요청을 더 이상 사용하지 않는 것으로 보이므로 현재 또는 미래에 전체 브라우저를 지원하지 않을 수 있습니다.
$.when
지연 된 객체의 배열을 확인하는 데 사용할 수는 있지만 이제는 모든 파일 에서이 작업을 수행 $.when
하고 콜백이 실행될 때가 아닌 즉시 실행되는 file2 가로 드 된 것으로 간주 되므로 file3 이로 드되기 전에 file1이 계속 실행됩니다. . 이것은 여전히 똑같은 문제가 있습니다.
나는 대신에 뒤로 가기로 결정했습니다. 감사합니다 document.writeln
. 나는 그것이 금기임을 알고 있지만 올바르게 사용되는 한 잘 작동합니다. 결국 쉽게 디버깅 할 수 있고 DOM에 올바르게 표시되고 종속성이 올바르게로드되는 순서를 보장 할 수있는 코드로 끝납니다.
물론 $ ( "body"). append ()를 사용할 수 있지만 더 이상 더 이상 올바르게 디버깅 할 수 없습니다.
참고 :이 페이지를로드하는 동안에 만 사용해야합니다. 그렇지 않으면 빈 화면이 나타납니다. 즉, 항상 document.ready 앞 / 뒤에 배치하십시오 . 페이지가 클릭 이벤트 또는 이와 유사한 것으로로드 된 후에 이것을 사용하여 테스트하지는 않았지만 실패 할 것이라고 확신합니다.
jQuery를 확장한다는 아이디어가 마음에 들었지만 반드시 그럴 필요는 없습니다.
를 호출하기 전에 document.writeln
모든 스크립트 요소를 평가하여 스크립트가 이미로드되지 않았는지 확인합니다.
document.ready
이벤트가 실행될 때까지 스크립트가 완전히 실행되지 않았다고 가정합니다 . (사용 document.ready
이 필요하지는 않지만 많은 사람들이 사용하는 것을 알고 있으며 이것을 처리하는 것이 안전합니다.)
추가 파일이로드되면 document.ready
콜백이 잘못된 순서로 실행됩니다. 스크립트가 실제로로드 될 때이 문제를 해결하기 위해 스크립트를 가져온 스크립트는 다시 가져 오기되고 실행이 중지됩니다. 이로 인해 원래 파일 document.ready
이 가져 오는 스크립트에서 콜백이 실행됩니다.
이 접근법 대신 jQuery를 수정하려고 시도 할 수는 readyList
있지만 더 나쁜 해결책 인 것 같습니다.
해결책:
$.extend(true,
{
import_js : function(scriptpath, reAddLast)
{
if (typeof reAddLast === "undefined" || reAddLast === null)
{
reAddLast = true; // Default this value to true. It is not used by the end user, only to facilitate recursion correctly.
}
var found = false;
if (reAddLast == true) // If we are re-adding the originating script we do not care if it has already been added.
{
found = $('script').filter(function () {
return ($(this).attr('src') == scriptpath);
}).length != 0; // jQuery to check if the script already exists. (replace it with straight JavaScript if you don't like jQuery.
}
if (found == false) {
var callingScriptPath = $('script').last().attr("src"); // Get the script that is currently loading. Again this creates a limitation where this should not be used in a button, and only before document.ready.
document.writeln("<script type='text/javascript' src='" + scriptpath + "'></script>"); // Add the script to the document using writeln
if (reAddLast)
{
$.import_js(callingScriptPath, false); // Call itself with the originating script to fix the order.
throw 'Readding script to correct order: ' + scriptpath + ' < ' + callingScriptPath; // This halts execution of the originating script since it is getting reloaded. If you put a try / catch around the call to $.import_js you results will vary.
}
return true;
}
return false;
}
});
용법:
파일 3 :
var f3obj = "file3";
// Define other stuff
$(function(){
f3obj = "file3docready";
});
파일 2 :
$.import_js('js/file3.js');
var f2obj = "file2";
$(function(){
f2obj = "file2docready";
});
파일 1 :
$.import_js('js/file2.js');
// Use objects from file2 or file3
alert(f3obj); // "file3"
alert(f2obj); // "file2"
$(function(){
// Use objects from file2 or file3 some more.
alert(f3obj); //"file3docready"
alert(f2obj); //"file2docready"
});
Javascript에서 모듈을 구현하는 방법에는 여러 가지가 있습니다. 가장 인기있는 두 가지 방법은 다음과 같습니다.
브라우저는 아직이 변조 시스템을 지원하지 않으므로이 구문을 사용하려면 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
이 변조 시스템은 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
유용한 JavaScript 플러그인 모음을 유지 관리하는 간단한 방법을 찾고 있었기 때문에이 질문에 왔습니다. 여기에 몇 가지 해결책을 본 후에 나는 이것을 생각해 냈습니다.
"plugins.js"(또는 extensions.js 또는 원하는 파일)라는 파일을 설정하십시오. 하나의 마스터 파일과 함께 플러그인 파일을 유지하십시오.
plugins.js에는 pluginNames[]
반복 하는 배열이 있으며 각 플러그인의 머리에 태그를 each()
추가합니다.<script>
//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>
그러나:
모든 플러그인이 원하는 방식으로 헤드 태그에 들어가더라도 페이지를 클릭하거나 새로 고칠 때 항상 브라우저에서 실행되는 것은 아닙니다.
PHP include에 스크립트 태그를 작성하는 것이 더 안정적이라는 것을 알았습니다. 한 번만 작성하면 JavaScript를 사용하여 플러그인을 호출하는 것만큼이나 효과적입니다.