file includes方法 - 如何在另一个JavaScript文件中包含JavaScript文件?




import用法 import中文 (25)

在JavaScript中是否有类似于@import的内容,允许您在另一个JavaScript文件中包含JavaScript文件?


Answers

您还可以使用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

我有一个简单的问题,但我对这个问题的回答感到困惑。

我不得不在另一个JavaScript文件(main.js)中使用一个JavaScript文件(myvariables.js)中定义的变量(myVar1)。

为此,我做了如下:

以正确的顺序加载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文件的变量可以在第二个JavaScript文件中自动访问。

这节省了我的一天。 我希望这有帮助。


有一个好消息要告诉你。 很快您就可以轻松加载JavaScript代码了。 它将成为导入JavaScript代码模块的标准方式,并将成为核心JavaScript本身的一部分。

你只需import cond from 'cond.js';写下import cond from 'cond.js'; 从文件cond.js加载名为cond的宏。

因此,您不必依赖任何JavaScript框架,也不必显式地进行Ajax调用。

参考:


或者不是在运行时包括在上载之前使用脚本连接。

我使用Sprockets (我不知道是否还有其他Sprockets )。 您可以在单独的文件中构建JavaScript代码,并包含由Sprockets引擎作为包含处理的注释。 对于开发,您可以按顺序包含文件,然后生产以合并它们...

也可以看看:


旧版本的JavaScript没有导入,包含或要求,因此开发了许多不同的方法来解决这个问题。

但自2015年(ES6)以来,JavaScript已经有了ES6模块标准来导入Node.js中的模块, 大多数现代浏览器也支持这种模块。

为了与旧版浏览器兼容,可以使用build和/或transpilation工具。

ES6模块

自v8.5起,Node.js支持ECMAScript(ES6)模块,带有--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模块

since Safari 10.1,Chrome 61,Firefox 60和Edge 16 since ,浏览器已经支持直接加载ECMAScript模块(不需要像Webpack这样的工具)。检查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);
}

欲了解更多信息, since访问: sincesince

浏览器中的动态导入

动态导入允许脚本根据需要加载其他脚本:

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

欲了解更多信息, https://developers.google.com/web/updates/2017/11/dynamic-import访问: https://developers.google.com/web/updates/2017/11/dynamic-importhttps://developers.google.com/web/updates/2017/11/dynamic-import

Node.js需要

仍然在Node.js中广泛使用的旧模式导入模块是module.exports/require系统。

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

JavaScript还有其他方法可以在不需要预处理的浏览器中包含外部JavaScript内容。

AJAX加载

您可以使用AJAX调用加载其他脚本,然后使用eval运行它。 这是最简单的方法,但由于JavaScript沙箱安全模型,它仅限于您的域。 使用eval还可以打开错误,黑客和安全问题的大门。

jQuery加载

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>标记添加到页面的head部分的末尾,其中src属性设置为作为第一个参数赋予函数的URL。

这些解决方案都在JavaScript疯狂:动态脚本加载中进行了讨论和说明。

检测脚本何时执行

现在,您必须了解一个大问题。 这样做意味着您远程加载代码 。 现代Web浏览器将加载文件并继续执行当前脚本,因为它们异步加载所有内容以提高性能。 (这适用于jQuery方法和手动动态脚本加载方法。)

这意味着如果您直接使用这些技巧, 在您要求加载后您将无法在下一行使用新加载的代码 ,因为它仍将加载。

例如: my_lovely_script.js包含MySuperObject

var js = document.createElement("script");

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

document.body.appendChild(js);

var s = new MySuperObject();

Error : MySuperObject is undefined

然后你重新加载页面击中F5 。 它的工作原理! 混乱...

那该怎么办呢?

好吧,你可以在我给你的链接中使用作者建议的黑客。 总之,对于匆忙的人,他在加载脚本时使用事件来运行回调函数。 因此,您可以使用远程库将所有代码放在回调函数中。 例如:

function loadScript(url, callback)
{
    // Adding the script tag to the head as suggested before
    var head = document.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 = callback;
    script.onload = callback;

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

然后在lambda函数中加载脚本后编写要使用的代码:

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

然后你运行所有:

loadScript("my_lovely_script.js", myPrettyCode);

请注意,脚本可以在DOM加载之后或之前执行,具体取决于浏览器以及是否包含行script.async = false; 。 有一篇关于Javascript加载的文章 ,讨论了这个问题。

源代码合并/预处理

如本答案的顶部所述,许多开发人员在他们的项目中使用像Parcel,Webpack或Babel这样的构建/转换工具,允许他们使用即将推出的JavaScript语法,为旧浏览器提供向后兼容性,组合文件,缩小,执行代码拆分等


var js = document.createElement("script");

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

document.body.appendChild(js);

我编写了一个简单的模块,可以自动执行在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);
};

这应该做:

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

此脚本将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);
})();

如果有人想要更高级的东西,请尝试RequireJS 。 您将获得额外的好处,例如依赖关系管理,更好的并发性,并避免重复(即,多次检索脚本)。

您可以在“模块”中编写JavaScript文件,然后在其他脚本中将它们作为依赖项引用。 或者您可以将RequireJS用作简单的“go get this script”解决方案。

例:

将依赖项定义为模块:

一些-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文件以及更多已定义的模块。 它针对浏览器内使用进行了优化,包括在Web Worker中,但它可以在其他JavaScript环境中使用,如Rhino和Node。 它实现了异步模块API。

RequireJS使用普通脚本标记来加载模块/文件,因此它应该允许轻松调试。 它可以简单地用于加载现有的JavaScript文件,因此您可以将其添加到现有项目中,而无需重新编写JavaScript文件。

...


可以动态生成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");

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

如果您正在使用Web Workers并希望在worker的范围内包含其他脚本,则提供有关向head标记添加脚本等的其他答案将不适合您。

幸运的是, Web Workers有自己的importScripts函数 ,它是Web Worker范围内的全局函数,是浏览器本身的本机函数,因为它是规范的一部分

或者, 作为对您的问题的第二高投票答案 , RequireJS还可以处理包含Web Worker中的脚本(可能调用importScripts本身,但具有一些其他有用的功能)。


更好地使用jQuery方式。要延迟就绪事件,请先拨打电话$.holdReady(true)。示例(source):

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

我通常的方法是:

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方法(其他一个答案),但它似乎对我来说效果不佳。

下面解释了代码如何为那些好奇的人工作:基本上,它创建了一个新的脚本标记(在第一个之后)。它将其设置为异步模式,因此它不会阻止其余代码,但在readyState(要加载的内容的状态)更改为“已加载”时调用回调。


如果您要加载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>

我刚写了这个JavaScript代码(使用Prototype进行DOM操作):

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

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

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

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

用法:

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

要点: http://gist.github.com/284442http://gist.github.com/284442


我创建了一个函数,允许您使用与C#/ Java类似的措辞来包含JavaScript文件。我甚至从另一个 JavaScript文件内部测试了一下它似乎工作。它确实需要jQuery,但最后需要一些“魔术”。

我把这段代码放在脚本目录根目录下的文件中(我把它命名为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);
}

还有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方法一样方便。它还具有一些高级功能,如条件加载,功能检测等等


这里显示的大多数解决方案都意味着动态加载。 我正在搜索一个编译器,它将所有依赖的文件组合成一个输出文件。 与Less / Sass预处理器相同,处理CSS @import at-rule。 由于我没有找到这种类似的东西,我写了一个简单的工具来解决这个问题。

所以这里是编译器, https://github.com/dsheiko/jsic ,它可以安全地用所需的文件内容替换$import("file-path") 。 这是相应的Grunt插件: https://github.com/dsheiko/grunt-jsichttps://github.com/dsheiko/grunt-jsic

在jQuery master分支上,他们只是简单地将原子源文件连接成一个以intro.js并以outtro.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

并获得组合文件

建立/ main.js

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

用现代语言来说就是这样

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

我来到这个问题是因为我正在寻找一种简单的方法来维护一组有用的JavaScript插件。在看到这里的一些解决方案之后,我想出了这个:

  1. 设置一个名为“plugins.js”(或extensions.js或者你有什么)的文件。将插件文件与一个主文件保持在一起。

  2. plugins.js将有一个名为“pluginNames []”的数组,我们将遍历每个(),然后为每个插件添加一个标记到头部

    //当我们添加或删除插件文件时设置要更新的数组var pluginNames = [“lettering”,“fittext”,“butterjam”等]; //每个插件的一个脚本标签$ .each(pluginNames,function(){$('head')。append('');});

  3. 手动调用你头脑中的一个文件:
    <script src="js/plugins/plugins.js"></script>

我发现即使所有的插件都按照它们应该的方式放入头标签,但当你点击页面或刷新时,它们并不总是被浏览器运行。

我发现在PHP包中编写脚本标签更可靠。您只需编写一次,这与使用JavaScript调用插件一样多。


另一种方式,在我看来更清晰,是制作同步Ajax请求而不是使用<script>标记。 这也是Node.js处理的方式。

这是使用jQuery的一个例子:

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

然后,您可以在代码中使用它,因为您通常使用包含:

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

并且能够在下一行中从所需脚本调用函数:

subscript.doSomethingCool(); 

虽然array.indexOf(x)!=-1是最简洁的方法(并且已经被非Internet Explorer浏览器支持了十多年......),但它不是O(1),而是O( N),这太可怕了。 如果您的数组不会更改,您可以将数组转换为哈希表,然后执行table[x]!==undefined===undefined

Array.prototype.toTable = function() {
    var t = {};
    this.forEach(function(x){t[x]=true});
    return t;
}

演示:

var toRemove = [2,4].toTable();
[1,2,3,4,5].filter(function(x){return toRemove[x]===undefined})

(不幸的是,虽然你可以创建一个Array.prototype.contains来“冻结”一个数组并将this._cache中的哈希表存储在两行中,但是如果你以后选择编辑你的数组,这会产生错误的结果.JavaScript没有足够的钩子。让你保持这种状态,例如Python不同。)





javascript file import include