优化后的RrequireJS优化器和加载动态路径

时间:2015-09-30 18:54:36

标签: javascript optimization gruntjs requirejs

我对requirejs执行了一项艰巨的任务,并且正在运行优化器。

我加载了许多在运行时并不总是需要的外部文件,通常我只需要一些核心文件。然后根据用户决定,我在运行时加载某些文件。

前:

define(["backbone",     'text!data/filePaths.json'],
    function(Backbone,   filePaths) {
        'use strict';

        return Backbone.Model.extend({

            initialize: function(){
                // parse the file paths, there could be a hundred here
                this.filePaths = JSON.parse(filePaths);
            },

            // dynamically add a file via this function call
            addFile: function(id){
                var self = this;

                return new Promise(function(resolve, reject){     

                    // load files dynamically based on the id passed in
                    require([self.filePaths[id].path], function(View){
                        resolve(new View());
                    });


                });
            }

        });

    }

);

文件路径json可能如下所示:

"ONE": {
    "name": "BlueBox",
    "path": "views/box/Blue"
},
"TWO": {
    "name": "RedBox",
    "path": "views/box/Red"
},
etc...

问题是这对我来说不适用于优化器。

当我使用优化文件运行我的应用程序时,我得到:

Uncaught Error: undefined missing views/box/Red

更新

grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    requirejs: {
        desktopJS: {
            options: {
                baseUrl: "public/js/app",
                wrap: true,
                // Cannot use almond since it does not currently appear to support requireJS's config-map
                name: "../libs/almond",
                preserveLicenseComments: false,
                optimize: "uglify2",
                uglify2: {
                    // mangle: false,
                    // no_mangle: true,
                    // stats: true,
                    // "mangle-props": false,
                    "max-line-len": 1000,
                    max_line_length: 1000
                },
                uglify: {
                    mangle: false,
                    no_mangle: true,
                    stats: true,
                    "mangle-props": false,
                    max_line_length: 1000,
                    beautify: true
                },
                mainConfigFile: "public/js/app/config/config.js",
                include: ["init/DesktopInit"],
                out: "public/js/app/init/DesktopInit.min.js"
            }
        },
        desktopCSS: {
            options: {
                optimizeCss: "standard",
                cssIn: "./public/css/desktop.css",
                out: "./public/css/desktop.min.css"
            }
        }
    },

注意:如果我使用未经优化的版本,一切正常。

2 个答案:

答案 0 :(得分:1)

优化器无法跟踪没有依赖关系的require调用的依赖关系作为字符串文字数组。您的调用是优化程序无法处理的require调用的示例,因为依赖项列表是在运行时计算的:

require([self.filePaths[id].path], function(View){

原因很简单:优化器不会评估您的模块,因为它会优化它们。无论如何,self.filePaths[id].path的可能值的数量可能是无限的,因此优化器无法处理所有情况。因此,当优化器优化您的代码时,应该由此require调用加载的模块不包含在捆绑包中。您在your own answer中提到的一个解决方案是使用include 包含可以通过require调用加载的所有可能模块。

正如您所指出的,如果您可以拥有数百个模块,这意味着将它们全部包含在优化程序生成的包中。还有其他选择吗?是的,有。

您可以生成仅包含应用程序的其他模块的捆绑包,将上面require调用要加载的模块单独加载,而不是作为捆绑包的一部分加载。 啊,但是您在问题中显示的具体配置存在问题。您有评论说您不能使用杏仁。然而,实际上你确实使用它,就在下一行。 (你的答案中也有它。)问题是Almond的一个限制是它没有动态加载。这是list of restrictions中的第一个限制。 您必须使用全功能的AMD加载程序,例如RequireJS本身。

答案 1 :(得分:0)

这不是真正的答案,只是一种方式"围绕"我的申请没有工作。

我认为唯一可以避免这种情况的方法是使用 include 配置

例如:

requirejs: {
    desktopJS: {
        options: {
            baseUrl: "public/js/app",
            wrap: true,
            name: "../libs/almond",
            optimize: "uglify2",
            uglify2: {
                "max-line-len": 1000,
                max_line_length: 1000
            },
            mainConfigFile: "public/js/app/config/config.js",
            include: ["init/DesktopInit", "views/box/Blue"], // include the file here, all of a sudden the error goes away for that file.

虽然当我有一百个文件时这会变得很麻烦。我不想用包含的所有文件来构建整个文件,我想要一组优化文件,以及一些可以动态需要的其他文件。