RequireJS仅加载连接文件

时间:2014-08-21 13:25:58

标签: javascript node.js requirejs r.js

我正在使用RequireJS(版本2.1.14),并希望将我的JavaScript文件连接成一个app-built.js。 我创建了一个小节点模块,它读取我的app.js,提取项目路径,并在我的应用程序的node build目录中运行js后执行。

节点模块(build.js):

var fs = require('fs'),
    path = require('path'),
    directory = __dirname + path.sep,
    requirejs = require(directory + 'vendor/r.js');

fs.readFile(directory + 'app.js', 'utf8', function(err, data) {
    if (err) {
        console.log('Error: ' + err);
        return
    } else {
        data = data.replace(/'/g, '"').replace(/\s+/g, '');
        var paths = data.substr(data.indexOf('{'), data.indexOf('}')),
            paths = paths.substr(0, paths.indexOf('}') + 1),
            paths = JSON.parse(paths);

        createAppBuilt(paths);
    }
});

function createAppBuilt(paths) {
    var config = {
        baseUrl: __dirname,
        paths: paths,
        name: 'app',
        out: 'app-built.js',
        preserveLicenseComments: false,
        findNestedDependencies: true,
        removeCombined: true
    };

    requirejs.optimize(config, function(buildResponse) {
        var contents = fs.readFileSync(config.out, 'utf8');
        console.log('Created app-built.js');
    }, function(err) {
        console.log('Error: ' + err);
        return;
    });
}

app.js:

var paths = {
    'jquery': 'vendor/jquery-1.11.0.min',
    // other paths
};

// Set language, necessary for validtaion plugin -> validation.js
if (Modernizr.localstorage) {
    localStorage.getItem('language') || localStorage.setItem('language', navigator.language || navigator.userLanguage);
}

requirejs.config({
    paths: paths,
    shim: {
        touchswipe: {
            deps: ['jquery']
        },
        icheck: {
            deps: ['jquery']
        },
        validate: {
            deps: ['jquery']
        },
        mask: {
            deps: ['jquery']
        },
        chosenImage: {
            deps: ['jquery', 'chosen']
        },
        cookie: {
            deps: ['jquery']
        }
    }
});

require(['globals', 'jquery', 'underscore'], function() {

    var initial = ['main'];

    if (!Modernizr.localstorage) {
        initial.push('cookie');
    }

    require(initial, function(Main) {
        $(function() {
            if (!Modernizr.localstorage) {
                $.cookie.json = true;
            }
            Main.init();
        });
    });

});

生成app-built.js但是当我将它包含在我的index.php中时,所有其他模块也会被加载。如何阻止加载所有模块并仅加载app-built.js

enter image description here

4 个答案:

答案 0 :(得分:-1)

我建议你研究http://webpack.github.io/http://browserify.org/因为这些可以解决这个问题。

它们允许您像以前一样使用require,但代码被编译/连接成一个文件。

Webpack允许在为站点的不同部分加载不同的代码块时更加灵活,但到目前为止,Browserify是最知名的。

切换到这些可能会有成本,因为我不认为他们是100%兼容的需求,但是它们带来了很大的优势。

Here's有人从RequireJS到Browserify的旅程中有一些优点和缺点。

答案 1 :(得分:-1)

将模块分成不同的文件,例如app-built.jsuser-built.js。然后在需要时加载脚本。

以下是演示:http://plnkr.co/edit/s6hUOEHjRbDhtGxaagdR?p=preview

加载页面时,requirejs仅加载global.js。点击Change Color按钮后,requirejs开始加载colorfy.js所需的random-color.jscolorfy.js

答案 2 :(得分:-1)

我不确定具体细节,但是,如果您没有exports选项,则r.js不会为您定义命名模块,这会导致实际加载脚本。

我假设你有jquery插件,所以添加额外的exports选项:

shim: {
    touchswipe: {
        deps: ['jquery'],
        exports: 'jQuery.fn.touchswipe'
    },

这应该强制r.js为touchswipe构建一个命名模块:

define("touchswipe", (function (global) {
    return function () {
        var ret, fn;
        return ret || global.jQuery.fn.touchswipe;
    };
}(this)));

请注意,exports选项可能无法构建此命名模块,在这种情况下,您最好的选择是手动包含此模块。

我再次不确定为什么以及如何发生这种情况,必须是requirejs中的一个错误,不太可能对此进行调整。

答案 3 :(得分:-1)

更改r.js优化器(到uglify2)解决了我的问题:

var config = {
    baseUrl: __dirname,
    paths: paths,
    name: 'app',
    out: 'app-built.js',
    findNestedDependencies: true,
    preserveLicenseComments: false,
    removeCombined: true,
    optimize: 'uglify2'
};