【发布时间】:2017-12-14 05:48:54
【问题描述】:
我正在尝试减轻我的应用服务器上的负载。我希望它只提供一个小页面外壳,并从我的 CDN 提供经过优化的捆绑 js。我可以这样做吗?
我问是因为我没有运气,在这种情况下应该问的第一个问题是“我应该这样做吗?”也许这不是该工具的预期工作流程。
该项目可能包含 100 个左右的 js 文件(大部分是我的,一些是第 3 方)。我通过 require 使用 AMD 使其易于管理。我已经运行了优化器并生成了一个优化文件。但是当我将该文件放在我的 CDN 上并从我的项目中的脚本标签中引用它时,应用程序会抱怨如下:
GET https://myserver.com/modules/util/utilloader.js net::ERR_ABORTED 12:50:16.452 require.js:168 Uncaught Error: Script error for "modules/util/utilloader" http://requirejs.org/docs/errors.html#scripterror at makeError (require.js:168) at HTMLScriptElement.onScriptError (require.js:1735)
它似乎在抱怨,因为它希望组件/文件位于与我的服务器上的应用程序相关的路径中。但我希望它在捆绑文件中查找该代码。
我正在尝试做的事情可行吗?如果是这样,我如何让应用程序在优化文件中查找代码,而不是在相对于我服务器上的应用程序根目录的其他文件中查找代码?
其他详细信息(每个请求): 配置文件 (application.js) 基本上首先需要一堆 3rd 方的东西。然后它需要我制作的模块。这似乎是麻烦开始的地方。如果您查看下面的 application.js 文件,则有两个 require 语句在依赖项列表中具有路径(utilloader、mod1、mod2、mod3 等)。它永远不会找到那些,因为它们不存在。我已将这些文件捆绑到一个名为 application.js 的文件中。这就是现在的全部内容,只有一个文件。这个困境告诉我我只是不了解这个工具和过程。我如何需要像 utilloader 这样的东西而没有像“modules/util/utilloader”这样的路径?我原以为优化器会理解这个问题并在捆绑时解决它。但同样,我认为我不了解工具或过程。
以下是相关文件:
构建文件
({
appDir: ".",
baseUrl: "myapp",
dir: "../scripts-build",
mainConfigFile: 'myapp/application.js',
modules: [
{
name: "application"
}
]
})
代码结构(优化器目录)
-optimize -r -scripts -backbone.js -backbone.marionette.js ...many more 3rd party libs -underscore.js -myapp -application.js -controller.js -router.js -modules (complex modules each with many dependencies. Sub-structures omitted here for brevity) -mod1 -mod2 -mod3 -util
配置(应用程序.js)
require.config({
paths: {
jquery: '../jquery-2.2.3.min',
bootstrap: '../bootstrap.min',
jqueryui: '../jquery-ui-1.11.4.min',
jqcloud: '../jqcloud.min',
jqmarquee: '../jquery.marquee.min',
bootstrapslider: '../bootstrap-slider.min',
underscore: '../underscore.min',
backbone: '../backbone.min',
marionette: '../backbone.marionette.min',
handlebars: '../handlebars.min',
hls: '../hls.min'
},
shim: {
'jqueryui': {
deps: ['jquery']
},
"bootstrap": {
"deps": ['jquery']
},
'jqcloud': {
deps: ['jquery']
},
'jqmarquee': {
deps: ['jquery']
},
'bootstrapslider': {
deps: ['jquery', 'bootstrap']
},
underscore: {
exports: '_'
},
backbone: {
deps: ["underscore", "jquery"],
exports: "Backbone"
},
marionette: {
deps: ["backbone"],
exports: "Marionette"
}
}
});
//Outer require - Need this 3rd party stuff to make our Marionette app.
//There will be 2 more requires inside this outer require.
require(["marionette", "hls", "jqueryui", "jqcloud", "jqmarquee", "handlebars", "bootstrap", "bootstrapslider"], function (Marionette, Hls) {
//Create a Marionette js application
window.App = new Marionette.Application();
//Do a bunch of stuff in the app's global space that uses some of the 3rd party packages required above
...code ommitted here for brevity
//#1
//Require some other modules (mine, not 3rd party) before officially "starting" the marionette js application.
//Each of these modules include many dependencies (many dozens of files) of thier own in their definitions
require([
"modules/util/utilloader",
"modules/mod1/mod1loader",
"modules/mod2/mod2loader",
"modules/mod3/mod3loader"
], function () {
App.start();
});
//#2
//Require two more files (mine) to make a backbone router.
require(["controller", "router"], function (Controller, AppRouter) {
var router = new AppRouter({ controller: new Controller() });
});
//When the marionette js application is officially "started", start the backbone history.
App.on("start", function () {
//History
if (Backbone.history) {
Backbone.history.start();
}//End history
//Some more app start functions
...code ommitted here for brevity
});//end App on start handler
})//end outer require
我的主配置文件 (application.js) 所需的示例模块 (utilloader.js)
// loader for Util module (lets you spread this module across multiple files)
// the 'loader' includes initial module definition and manages the loading
// of all module files including javascript and templates.
// define base module elements; other module files may depend
// on this, but it must not depend on any other module files.
//NOTE: I think this first piece here is what the optimizer is complaining about
//It's not inside a define?
App.module("UtilModule", function (UtilModule) {
UtilModule.views = {}; //put your views and models in structures so you
UtilModule.models = {};//can get at them from anywhere in the module
});
// Recommended: define all dependencies for this module
// while you could spread dependency requirements
// over all your module files on purely "as needed" basis,
// this adds to complication of code in your module files
// defining them all, here, has the advantage of limiting use of RequireJS
// to this loader file only
var dependencies = [
"modules/util/views/view1",
"modules/util/views/view2",
"modules/util/views/view3",
"modules/util/models/model1",
"modules/util/models/model2",
"modules/util/models/model3"
];
// define the loader last. generally, it should depend on all
// module files, otherwise they may not get loaded
define(dependencies,
function () {
App.module("UtilModule", function (UtilModule, App, Backbone, Marionette, $, _) {
//Some functions here to make views, bind them to the models listed above and show them.
//...ommitted here for space and clarity
});//Close the module definition
});//Close the define function
2017 年 12 月 13 日更新
也许我优化的东西不起作用,因为并非我的所有文件都符合 AMD 标准(未包含在定义函数中的东西)。所以我经历了整个项目并解决了这个问题。下面是我在整个项目中所做的修订类型示例,并概述了新问题。
我的主配置文件 (application.js) 所需的修订示例模块 (utilloader.js) 优化器不喜欢上述版本(不符合 AMD 标准)。它在 DEFINE 函数之外有一些东西(模块定义,var 依赖项)。在这里,我已对其进行了修改,以将这些内容放入定义中。现在应该很好。但是这样做我得到了新的错误。现在有人抱怨外部文件中定义的内容不在本模块的范围内。因此,如果我在诸如 modules/util/models/model1 之类的外部文件中定义了一个主干模型,则尝试在此文件中创建该模型的实例会产生未定义的错误。这个模块只是不知道这些外部文件中有什么,即使它们列在这个模块的依赖数组中。所以需要加载没有错误的外部文件,但在这些文件中创建的内容不在本模块的范围内。但是所有这一切都可以在未优化的情况下运行良好(如果我不使用优化器)。为什么会有差异?如果代码以某种方式格式不正确,我希望它以两种方式都失败,或者两种方式都成功。
// loader for Util module (lets you spread this module across multiple files)
// the 'loader' includes initial module definition and manages the loading
// of all module files including javascript and templates.
// Recommended: define all dependencies for this module.
// while you could spread dependency requirements
// over all your module files on purely "as needed" basis,
// this adds to complication of code in your module files.
// defining them all, here, has the advantage of limiting use of RequireJS
// to this loader file only
// define the loader last. generally, it should depend on all
// module files, otherwise they may not get loaded
define(
[
"modules/util/views/view1",
"modules/util/views/view2",
"modules/util/views/view3",
"modules/util/models/model1",
"modules/util/models/model2",
"modules/util/models/model3"
],
function () {
App.module("UtilModule", function (UtilModule, App, Backbone, Marionette, $, _) {
UtilModule.views = {}; //put your views and models in structures so you
UtilModule.models = {};//can get at them from anywhere in the module
//Try to create an instance of a model defined in an external file.
var model1 = new Model1();
//No errors are reported in the parsing of the external file. But the line above
//produces 'Model1' is undefined. I have dozens of external definitions like this
//in the app. All of them resolve fine unoptimized. When I run the requirejs optimizer,
//none of them resolve.
});//Close the module definition
});//Close the define function
【问题讨论】:
标签: javascript optimization requirejs