如何在sails.js中连接bower组件?

42
我希望能够通过 bower 安装Javascript依赖项,并在sails.js 应用程序中使用它们,但我无法找到一种不仅仅是从bower_components文件夹复制和粘贴文件到Sails资产文件夹的方法。
理想情况下,我认为我想使用 requirejs 并在 main.js 文件中指向 bower components。如果这样做不正确,请告诉我。任何关于使用Sails管理 components / libraries 的想法都欢迎。
5个回答

42

在Sails 0.10中,“assets/linker”目录不再存在,但我找到了一个简单的解决方案,可以自动化bower -> asset链接器的工作流程,同时允许对要链接的内容进行一些细粒度控制。

解决方案是将grunt-bower添加到您的Sails.js compileAssets任务中。

grunt.registerTask('compileAssets', [
    'clean:dev',
    'bower:dev',
    'jst:dev',
    'less:dev',
    'copy:dev',
    'coffee:dev'
]);

然后像这样配置您的grunt-bower任务(在 tasks/config/bower.js 中):

module.exports = function(grunt) {
  grunt.config.set('bower', {
    dev: {
        dest: '.tmp/public',
        js_dest: '.tmp/public/js',
        css_dest: '.tmp/public/styles'
    }
  });

  grunt.loadNpmTasks('grunt-bower');

};

这将自动将您的bower js和css文件复制到Sail资产链接器寻找并自动添加到项目布局模板的正确位置。任何其他js或css文件仍将在您的bower文件之后自动添加。

但是,此设置仍存在两个重大注意事项:

1- 通过bower-grunt添加的文件必须列在bower.json的main数组中。如果您发现未加载某些文件,则必须编辑该软件包的bower.json文件或通过grunt-bower的packageSpecific选项手动添加依赖项。

2- 资产链接器中bower文件的顺序目前是按字母顺序排列的。我唯一的解决方案是调整此顺序,因此需要在Sail的compileAssets任务之前使用额外的grunt任务来手动重新排序文件。不过我相信,grunt-bower可以支持软件包复制排序以解决这个问题。


5
要管理脚本的顺序,只需编辑 tasks/pipeline.js 中的 var jsFilesToInject = [] - m4tm4t
1
这个功能一直很好用,直到 grunt-bower 版本升级到 0.15.1。有些变化导致无法复制 bower_components - theblang
1
我认为现在应该已经修复了,因为今天我使用grunt-bower 0.16.0时它可以工作。 - newz2000

33
请注意:下面的答案已经不再完全适用于SailsJS的当前版本,因为从SailsJS 0.10开始不再支持链接器文件夹。
请参见:Sails not generating linker 原始答案:
我找到了一个解决方案,实际上非常简单。我之前没有意识到可以配置bower将其文件放置在哪个位置。
创建一个.bowerrc文件,并更改bower组件安装的目录,在Sailjs中应该将它们放入assets文件夹中。
/*
 * Create a file called .bowerrc and put the following in it.
 * This file should be in the root directory of the sails app.
 */

 {
   "directory": "assets/linker/bower_components"
 }

Sails将使用grunt在文件更改时将它们复制到.tmp/public/assets文件夹中。如果您不希望Sails不断删除然后重新复制这些文件,可以在grunt文件中排除它们。
/* 
 * This is not necessary, but if you have a lot of components and don't want
 * them constantly being deleted and copied at every file change you can update
 * your Gruntfile.js with the below.
 */

 clean: {
   dev: ['.tmp/public/**',
         '!.tmp/public',
         '!.tmp/public/bower_components/**'],
   build: ['www']
 },

在使用Sails时,关于requirejs的一个提示。默认情况下,由于Sails没有使用requirejs来加载socket.io文件,因此您将会收到一个错误。这是因为socket.io支持amd风格的加载方式,更多详细信息请参见http://requirejs.org/docs/errors.html#mismatch

最简单的解决方法是注释掉socket.io.js末尾附近的几行代码。

/*
 * Comment the below out in the file assets/js/socket.io.js, if using requirejs
 * and you don't want to modify the default sails setup or socket.io.
 */

 if (typeof define === "function" && define.amd) {
   define([], function () { return io; });
 }

另外一种方法是将位于assets/js中的sails文件命名为"socket.io.js"、"sails.io.js"和app.js,将它们重新编码为AMD模块。

这个答案现在有点过时了。 - ktamlyn

11

我发现最简单的实现方法就是将个别的 Bower 组件添加到你的 tasks/pipeline.js 文件中。举个例子,这里是你可能如何添加 Modernizr:

转化结果为:

实现方法最简单的方式就是直接将单个 Bower 组件添加到你的tasks/pipeline.js文件中。例如,以下是添加 Modernizr 的方法:

// Client-side javascript files to inject in order
// (uses Grunt-style wildcard/glob/splat expressions)
var jsFilesToInject = [

  // Load sails.io before everything else
  'js/dependencies/sails.io.js',

  // Dependencies like jQuery, or Angular are brought in here
  'js/dependencies/**/*.js',

  // =========================================================
  // Modernizr:
  'bower_components/modernizr/modernizr.js',
  // =========================================================

  // All of the rest of your client-side js files
  // will be injected here in no particular order.
  'js/**/*.js'
];

在您的布局模板中,将会插入到<!--SCRIPTS-->占位符中的链接bower_components/modernizr/modernizr.js,当您运行sails lift --prod时,它也会被缩小等处理。


是的,这就是 v0.11 的答案。 - KimchiMan
9
对这个答案点赞。添加一个包含 {"directory": "assets/bower_components"}.bowerrc 文件也会有所帮助。 - rishabhmhjn
真的很喜欢这个解决方案,并且添加.bowerrc非常干净、直接和完美地集成了。 - wsfuller
.bowerrc是目前最简单的解决方案,而且效果非常好。应该标记为被接受的答案! - Deep Shah

3

对不起,我来晚了。

我认为将bower_components包含在链接器中是一个不好的主意,因为当你启动sails时,它里面的所有内容都会被复制到.tmp并包含在标签中。 例如,如果你使用bower包含Angular,你的脚本中就会有两个引用:一个是angular.js,另一个是angular.min.js。同时拥有这两个文件是一个错误。

以下是我的项目解决方案:

  • 我在根目录中创建了一个名为bower_component的文件夹。
  • 我在Gruntfile.js的copy:dev数组中添加了一行代码:

    { '.tmp/public/linker/js/angular.js': './bower_components/angular/angular.js' }

对于每个要包含的文件,我需要在该数组中手动添加一行新代码。我没有找到其他自动化解决方案。如果有人找到更好的解决方案... ;)


这也可以是一个解决方案。 - Faris Rayhan

1

这里强烈反对仅提供链接的答案,因为链接可能在未来失效。建议您编辑答案并引用您引用的来源。 - Anirudh Sharma

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接