我希望尽量减少客户端在浏览器中加载脚本的HTTP请求数。这将是一个相当普遍的问题,但我仍然希望我能得到一些答案,因为到目前为止javascript中的模块管理一直很痛苦。
目前,在开发过程中,每个模块都是从主html模板中单独请求的,如下所示:
<script src="/libraries/jquery.js"></script>
<script src="/controllers/controllername.js"></script>
...
服务器在Node.js上运行,并根据请求发送脚本。
显然,这是最不理想的方式,因为所有模型,集合等也被分成他们自己的文件,这些文件可以转化为许多不同的请求。
我遇到的库(RequireJS使用AMD和CommonJS)可以从发送到客户端的主.js文件中请求模块,但是需要大量额外的工作才能使每个模块符合每个库:
;(function(factory){
if (typeof define === 'function' && define.amd) define([], factory);
else factory();
}(function(){
// Module code
exports = moduleName;
}));
我想在服务器上创建一个文件,将所有模块“连接”在一起。如果我可以这样做而无需向现有模块添加更多代码,那将是完美的。然后,我可以在请求时将该单个文件提供给客户端。
这可能吗?
此外,如果我设法构建单个文件,我应该在其中包含开源库(jQuery,Angular.js等)还是从客户端的外部cdn请求它们?
答案 0 :(得分:3)
从我所知道的,你要求做的是将你的js文件连接成一个文件然后在你的main.html中你会有这个
<script src="/pathLocation/allMyJSFiles.js"></script>
如果我的假设是正确的,那么答案就是使用以下两个项目中的一个
我使用 GULP 。
您可以根据具体情况使用gulp,这意味着从命令行调用gulp执行gulp代码,或者使用watch在保存时自动执行。
除了让gulp工作并包含你需要做的所需的gulp文件之外,我只会提供一些我用来获得答案的内容。
在我的gulp文件中,我会有类似的东西
var gulp = require('gulp');
var concat = require('gulp-concat');
...maybe more.
然后我需要将文件路径缩减为一个文件。
var onlyProductionJS = [
'public/application.js',
'public/directives/**/*.js',
'public/controllers/**/*.js',
'public/factories/**/*.js',
'public/filters/**/*.js',
'public/services/**/*.js',
'public/routes.js'
];
我在gulp任务中使用此信息,如下面的那个
gulp.task('makeOneFileToRuleThemAll', function(){
return gulp.src(onlyProductionJS)
.pipe(concat('weHaveTheRing.js'))
.pipe(gulp.dest('public/'));
});
然后我通过调用
在命令行中运行任务gulp makeOneFileToRuleThemAll
此调用运行相关的gulp任务,该任务使用&#39; gulp-concat&#39; 将所有文件合并到一个名为&#39; weHaveTheRing.js&的新文件中#39; 并在目标&#39; public /&#39;
中创建该文件然后只需将新文件包含在 main.html
中<script src="/pathLocation/weHaveTheRing.js"></script>
至于将所有文件包含在一个文件中,包括供应商文件,只需确保首先运行供应商代码。除非您有一个确定的方法来首先加载您的供应商代码而没有任何问题,否则最好将它们保持独立。
<强>更新强>
这是我的gulp watch任务。
gulp.task('startTheWatchingEye', function () {
gulp.watch(productionScripts, ['makeOneFileToRuleThemAll']);
});
然后我像这样启动我的服务器(你的服务器可能不同)
npm start
// in a different terminal window I then type
gulp startTheWatchfuleye
注意:您可以使用任何想要的电影或节目参考! :)
现在只需对其进行编码,每次在指定文件中进行更改 GULP 都会运行您的任务。
如果你想为你的试运行者说跑Karma ......
将以下内容添加到您的gulp文件
var karma = require('karma').server;
gulp.task('karma', function(done){
karma.start({
configFile: __dirname + '/karma.conf.js'
}, done);
});
然后将此任务业力添加到我上面说过的手表中......
gulp.task('startTheWatchingEye', function(){
gulp.watch(productionScripts, ['makeOneFileToRuleThemAll', 'karma']);
});
同时强>
您的特定设置可能需要更多gulp模块。通常,您可以全局安装Gulp,以及每个模块。然后在各种项目中使用它们。只需确保您的项目的package.json具有dev或其他所需的gulp模块。
关于是否使用Gulp或Grunt,有不同的文章。 Gulp是在Grunt之后制作的,只有Grunt缺少的一些补充。我不知道Grunt是否缺少它们。我很喜欢Gulp,并且发现它非常适用于大量文档。
祝你好运!答案 1 :(得分:2)
我想在服务器上创建一个文件,将所有模块“连接”在一起。如果我可以这样做而无需向现有模块添加更多代码,那将是完美的。
当然可以。您可以使用Grunt或Gulp执行此操作,更具体地说,grunt-contrib-concat或gulp-concat
这是一个Gruntfile.js配置示例,用于连接js目录下的每个文件:
grunt.initConfig({
concat: {
dist: {
files: {
'dist/built.js': ['js/**/**.js'],
},
},
},
});
此外,您可以使用grunt-contrib-minify在连接后缩小所有内容。
两个库都支持source maps所以,如果bug生成,你可以轻松调试。
您还可以使用grunt-contrib-htmlmin缩小HTML文件。
还有一个名为grunt-usemin的非常有用的库。 Usemin让你使用HTML注释来“控制”哪些文件被缩小(所以你不必手动添加它们)。
缺点是您必须通过脚本标记明确地将它们包含在HTML中,因此不能通过javascript进行异步加载(例如,使用RequireJS)。
此外,如果我设法构建单个文件,我应该在其中包含开源库(jQuery,Angular.js等)还是从客户端的外部cdn请求它们?
这是值得商榷的。两者都有利有弊。连接供应商确保,如果由于某种原因,CDN不可用,您的页面将按预期工作。但是,服务的文件更大,因此您消耗更多带宽。
根据我的个人经验,我倾向于包含供运行页面绝对必要的供应商库,例如AngularJS。
答案 2 :(得分:0)
如果我理解正确,您可以使用Grunt等任务运行程序为您连接文件。
查看Grunt Concat插件。
来自文档的示例配置:
// Project configuration.
grunt.initConfig({
concat: {
dist: {
src: ['src/intro.js', 'src/project.js', 'src/outro.js'],
dest: 'dist/built.js',
}
}
});
否则,正如您所说,“模块加载器”系统(例如Require JS或Browserify)可能是最佳选择。