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

RrequireJS optimizer and loading dynamic paths after optimization

我有一个带有 requirejs 的 g运行t 任务并且正在 运行 优化器。

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

例如:

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"
            }
        }
    },

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

这并不是真正的答案,只是一种方式"around"我的应用程序无法正常工作。

我相信唯一可以避免这种情况的方法是使用 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.

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

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

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

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

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

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