我如何在另一个JavaScript文件中添加一个JavaScript文件,类似于CSS中的 @import?


当前回答

下面是没有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);
}

请注意,为了获得此工作跨域,服务器将需要在其响应中设置允许起源标题。

其他回答

如果你发现有两个或多个脚本在被召唤时占据相同功能,我们不能同时包含它们,我们需要通过用户选择进行动态操作。

在 jQuery 中的另一个文件使用 $.getScript 工作,因为脚本不会默认隐藏。

HTML

<select class="choice">
  <option value="script1" selected>Script-1</option>
  <option value="script2">Script-2</option>
</select>

雅各布斯

$(".choice").change(on_change);

var url = "https://example.com";
$.url1 = url + "/script1.js";
$.url2 = url + "/script2.js";

function on_change() {
  if ($(".choice").val()=="script1") {
    script1();
  } else {
    script2();
  }
}

// script1
function script1() {
  $.getScript($.url1, function( data, textStatus, jqxhr ) {
    // Execute here
  });
}

// script2
function script2() {
  $.getScript($.url2, function( data, textStatus, jqxhr ) {
    // Execute here
  });
}

您也可以使用 gulp, gulp-concat, gulp-typescript with /// <reference path= 包括:

{
  "scripts": {
    "gulp": "gulp main"
  },
  "dependencies": {
    "@types/gulp": "^4.0.6",
    "@types/gulp-concat",
    "@types/gulp-typescript",
    "gulp": "^4.0.2",
    "gulp-concat": "^2.6.1",
    "gulp-resolve-dependencies": "^3.0.1",
    "gulp-typescript": "^6.0.0-alpha.1",
    "typescript": "^3.7.3"
  }
}

文件 src/someimport.ts

class SomeClass {
    delay: number;
}

/// <reference path="./someimport.ts" />

someclass = new SomeClass();
someclass.delay = 1;

var gulp = require("gulp");
var concat = require('gulp-concat');
var resolveDependencies = require('gulp-resolve-dependencies');

var ts = require("gulp-typescript");
var tsProject = ts.createProject("tsconfig.json");

gulp.task("main", function() {
  return gulp
    .src(["src/main.ts"])
    .pipe(resolveDependencies({
      pattern: /^\s*\/\/\/\s*<\s*reference\s*path\s*=\s*(?:"|')([^'"\n]+)/gm
    }))
    .on('error', function(err) {
        console.log(err.message);
    })
    .pipe(tsProject())
    .pipe(concat('main.js'))
    .pipe(gulp.dest("build/"));
});

如果您想针对所有 TypeScript 项目文件而不是仅是 src/main.ts,您可以取代以下文件:

  return gulp
    .src(["src/main.ts"])
    .pipe(resolveDependencies({
    ...
// -->
  return tsProject
    .src()
    .pipe(resolveDependencies({
    ...

如果您不想使用 TypeScript,您可以使用此简化 gulpfile.js 并从 package.json 中删除所有包含的 TypeScript:

圖片來源:Gulpfile.js

var gulp = require("gulp");
var concat = require('gulp-concat');
var resolveDependencies = require('gulp-resolve-dependencies');

gulp.task("main", function() {
  return gulp
    .src(["src/main.js"])
    .pipe(resolveDependencies({
      pattern: /^\s*\/\/\/\s*<\s*reference\s*path\s*=\s*(?:"|')([^'"\n]+)/gm
    }))
    .on('error', function(err) {
        console.log(err.message);
    })
    .pipe(concat('main.js'))
    .pipe(gulp.dest("build/"));
});

{
  "scripts": {
    "gulp": "gulp main"
  },
  "dependencies": {
    "gulp": "^4.0.2",
    "gulp-concat": "^2.6.1",
    "gulp-resolve-dependencies": "^3.0.1"
  }
}

class SomeClass {
}
/// <reference path="./someimport.ts" />
someclass = new SomeClass();
someclass.delay = 1;

<html>
    <head>
        <script src="main.js"></script>
    </head>
    <body>
        <script type="text/javascript">
            console.log(someclass.delay);
        </script>
    </body>
</html>

TypeScript: Gulp 我可以使用 TypeScript 没有 RequireJS? 需要使用 Node.js 上的 Gulp.js 客户端使用另一个 JavaScript 文件的主要文件的简单折叠: 没有折叠的参考错误: 需要没有定义 如何使用 Gulp.js 编写 TypeScript 浏览器 Node.js 模块? 使用 babel 使用文件的折叠 如何在浏览器中“要求” CommonJS 模块? 有没有替代的浏览器

所以,如果你想要它快,容易......试试这个:

function include(filename)
{
    var head = document.getElementsByTagName('head')[0];

    var script = document.createElement('script');
    script.src = filename;
    script.type = 'text/javascript';

    head.appendChild(script)
}

我写了一个简单的模块,它自动化了在JavaScript中进口/包含模块脚本的工作。 详细解释代码,请参阅博客帖子JavaScript需要/进口/包含模块。

// ----- USAGE -----

require('ivar.util.string');
require('ivar.net.*');
require('ivar/util/array.js');
require('http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js');

ready(function(){
    //Do something when required scripts are loaded
});

    //--------------------

var _rmod = _rmod || {}; //Require module namespace
_rmod.LOADED = false;
_rmod.on_ready_fn_stack = [];
_rmod.libpath = '';
_rmod.imported = {};
_rmod.loading = {
    scripts: {},
    length: 0
};

_rmod.findScriptPath = function(script_name) {
    var script_elems = document.getElementsByTagName('script');
    for (var i = 0; i < script_elems.length; i++) {
        if (script_elems[i].src.endsWith(script_name)) {
            var href = window.location.href;
            href = href.substring(0, href.lastIndexOf('/'));
            var url = script_elems[i].src.substring(0, script_elems[i].length - script_name.length);
            return url.substring(href.length+1, url.length);
        }
    }
    return '';
};

_rmod.libpath = _rmod.findScriptPath('script.js'); //Path of your main script used to mark
                                                   //the root directory of your library, any library.


_rmod.injectScript = function(script_name, uri, callback, prepare) {

    if(!prepare)
        prepare(script_name, uri);

    var script_elem = document.createElement('script');
    script_elem.type = 'text/javascript';
    script_elem.title = script_name;
    script_elem.src = uri;
    script_elem.async = true;
    script_elem.defer = false;

    if(!callback)
        script_elem.onload = function() {
            callback(script_name, uri);
        };
    document.getElementsByTagName('head')[0].appendChild(script_elem);
};

_rmod.requirePrepare = function(script_name, uri) {
    _rmod.loading.scripts[script_name] = uri;
    _rmod.loading.length++;
};

_rmod.requireCallback = function(script_name, uri) {
    _rmod.loading.length--;
    delete _rmod.loading.scripts[script_name];
    _rmod.imported[script_name] = uri;

    if(_rmod.loading.length == 0)
        _rmod.onReady();
};

_rmod.onReady = function() {
    if (!_rmod.LOADED) {
        for (var i = 0; i < _rmod.on_ready_fn_stack.length; i++){
            _rmod.on_ready_fn_stack[i]();
        });
        _rmod.LOADED = true;
    }
};

_.rmod = namespaceToUri = function(script_name, url) {
    var np = script_name.split('.');
    if (np.getLast() === '*') {
        np.pop();
        np.push('_all');
    }

    if(!url)
        url = '';

    script_name = np.join('.');
    return  url + np.join('/')+'.js';
};

//You can rename based on your liking. I chose require, but it
//can be called include or anything else that is easy for you
//to remember or write, except "import", because it is reserved
//for future use.
var require = function(script_name) {
    var uri = '';
    if (script_name.indexOf('/') > -1) {
        uri = script_name;
        var lastSlash = uri.lastIndexOf('/');
        script_name = uri.substring(lastSlash+1, uri.length);
    } 
    else {
        uri = _rmod.namespaceToUri(script_name, ivar._private.libpath);
    }

    if (!_rmod.loading.scripts.hasOwnProperty(script_name)
     && !_rmod.imported.hasOwnProperty(script_name)) {
        _rmod.injectScript(script_name, uri,
            _rmod.requireCallback,
                _rmod.requirePrepare);
    }
};

var ready = function(fn) {
    _rmod.on_ready_fn_stack.push(fn);
};

如果有人正在寻找一些更先进的东西,试试 RequireJS. 你会得到添加的好处,如依赖管理,更好的竞争,并避免复制(即,获得一个脚本超过一次)。

您可以将 JavaScript 文件写入“模块”,然后将其列为其他脚本中的依赖,或者您可以使用 RequireJS 作为一个简单的“去获取这个脚本”解决方案。

例子:

将依赖定义为模块:

某些依赖性.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 是您的“主要” JavaScript 文件,取决于某些 dependency.js

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

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

從 GitHub README 發表:

RequireJS 加载平面 JavaScript 文件以及更定义的模块. 它是优化在浏览器中的使用,包括在 Web 工作者,但它可以用于其他 JavaScript 环境,如 Rhino 和 Node. 它实施了 Asynchronous 模块 API. RequireJS 使用平面脚本标签加载模块/文件,所以它应该允许轻松的解体。