我对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"
}
}
},
注意:如果我使用未经优化的版本,一切正常。
答案 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.
虽然当我有一百个文件时这会变得很麻烦。我不想用包含的所有文件来构建整个文件,我想要一组优化文件,以及一些可以动态需要的其他文件。