【问题标题】:Assemble every module into a single .js file将每个模块组装成一个 .js 文件
【发布时间】:2015-09-29 09:48:39
【问题描述】:

我想尽量减少来自客户端在浏览器中加载脚本的 HTTP 请求数。这将是一个非常普遍的问题,但我仍然希望我能得到一些答案,因为到目前为止,javascript 中的模块管理一直很痛苦。

现状

目前,在开发中,每个模块都是从主 html 模板单独请求的,如下所示:

<script src="/libraries/jquery.js"></script>
<script src="/controllers/controllername.js"></script>
...

服务器在 Node.js 上运行并根据请求发送脚本。

显然这是最不理想的方式,因为所有模型、集合等也都被分离到它们自己的文件中,这些文件会转化为许多不同的请求。

就研究而言

我遇到的库(使用 AMD 和 CommonJS 的 RequireJS)可以从发送到客户端的主 .js 文件中请求模块,但需要大量额外的工作才能使每个模块与每个库兼容:

;(function(factory){

    if (typeof define === 'function' && define.amd) define([], factory);
    else factory();

}(function(){

    // Module code

    exports = moduleName;
}));

我的目标

我想在服务器上创建一个将所有模块“连接”在一起的文件。如果我可以做到这一点而不必向已经存在的模块添加更多代码,那将是完美的。然后我可以简单地在客户端请求时将单个文件提供给它。

这可能吗?

此外,如果我确实设法构建了一个文件,我应该在其中包含开源库(jQuery、Angular.js 等)还是从客户端的外部 cdn 请求它们?

【问题讨论】:

  • 你看过browserify吗?这听起来像您正在寻找的东西。

标签: javascript node.js requirejs httprequest commonjs


【解决方案1】:

据我所知,你要求做的是将你的 js 文件合并到一个文件中,然后在你的 main.html 中你会得到这个

<script src="/pathLocation/allMyJSFiles.js"></script>

如果我的假设是正确的,那么答案将是使用以下两项之一

咕噜link或咕噜link

我使用 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 任务,该任务使用 'gulp-concat' 将所有文件集中到一个名为 'weHaveTheRing.js' 的新文件中并创建该文件目标 'public/'

中的文件

然后只需将该新文件包含到您的 ma​​in.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);
});

然后将这个任务karma添加到我上面所说的手表中......

gulp.task('startTheWatchingEye', function(){
  gulp.watch(productionScripts, ['makeOneFileToRuleThemAll', 'karma']);
});

您的特定设置可能需要更多的 gulp 模块。通常,您会全局安装 Gulp 以及每个模块。然后在您的各种项目中使用它们。只需确保您的项目的 package.json 具有您在 dev 或其他方面需要的 gulp 模块。

关于使用 Gulp 还是 Grunt 有不同的文章。 Gulp 是在 Grunt 之后制作的,并添加了 Grunt 缺少的一些内容。我不知道 Grunt 是否不再缺少它们。不过我非常喜欢 Gulp,并且发现它对大量文档非常有用。

祝你好运!

【讨论】:

  • 这很好。我可以直接从服务器脚本运行gulp makeOneFileToRuleThemAll 吗?
  • 我不知道?我这样做的方式是,我有一块手表,当我启动我的服务器时,我会启动它,即 gulp startUpTheNoise。然后它会监视我关心的所有文件,当我进行更改时,它会自动连接、缩小、丑化并创建新文件。我留在我需要编程的代码中,gulp 使我的脚本文件准备好快速一次性交付。
  • 您的更新帮助很大,感谢您向我介绍 gulp :)
  • 你打赌。完成所有设置后,它实际上很容易使用;并且高度可配置。
【解决方案2】:

我想在服务器上创建一个文件,将所有模块“连接”在一起。如果我可以做到这一点而不必向已经存在的模块添加更多代码,那将是完美的。

当然可以。您可以使用 Grunt 或 Gulp 来执行此操作,更具体地说是 grunt-contrib-concatgulp-concat

这是一个 Gruntfile.js 配置示例,用于连接 js 目录下的每个文件:

grunt.initConfig({
  concat: {
    dist: {
      files: {
        'dist/built.js': ['js/**/**.js'],
      },
    },
  },
});

此外,您可以在连接后使用grunt-contrib-minify 缩小所有内容。

两个库都支持source maps,因此,如果有错误进入生产环境,您可以轻松调试。

您还可以使用 grunt-contrib-htmlmin 缩小 HTML 文件。


还有一个非常有用的库,名为grunt-usemin。 Usemin 让您使用 HTML cmets 来“控制”哪些文件被缩小(因此您不必手动添加它们)。

缺点是您必须通过脚本标签明确地将它们包含在您的 HTML 中,因此不能通过 javascript 进行异步加载(例如使用 RequireJS)。


此外,如果我确实设法构建了一个文件,我应该在其中包含开源库(jQuery、Angular.js 等)还是从客户端的外部 cdn 请求它们?

这是有争议的。两者都有优点和缺点。连接供应商可确保,如果由于某种原因 CDN 不可用,您的页面将按预期工作。但是,提供的文件更大,因此您会消耗更多带宽。

根据我的个人经验,我倾向于包含对于页面运行绝对必要的供应商库,例如 AngularJS。

【讨论】:

    【解决方案3】:

    如果我理解正确,您可以使用诸如Grunt 之类的任务运行器来为您连接文件。

    看看Grunt Concat 插件。

    文档中的示例配置:

    // Project configuration.
    grunt.initConfig({
      concat: {
        dist: {
          src: ['src/intro.js', 'src/project.js', 'src/outro.js'],
          dest: 'dist/built.js',
        }
      }
    });
    

    否则,正如您所说,“模块加载器”系统,如 Require JSBrowserify 可能是要走的路。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-11
      • 1970-01-01
      • 2017-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-17
      • 1970-01-01
      相关资源
      最近更新 更多