在Ember.JS ember-cli应用中包含Bootstrap库的推荐方法是什么?

80

我正在尝试在当前的ember-cli项目中正确安装Twitter Bootstrap。 我已经使用bower安装了bootstrap:

bower install --save bootstrap

现在,该库已下载到/vendor/bootstrap/dist/(css|js|fonts)中。我尝试了这里提到的方法:http://ember-cli.com/#managing-dependencies,替换路径和CSS文件名,但是我遇到了有关Brocfile.js文件的错误。我认为与示例相比,brocfile格式已经改变太多了。
我还尝试使用/app/styles/app.css文件进行@import,将样式表移动到/app/styles/目录后:
@import url('/assets/bootstrap.css');
@import url('/assets/bootstrap-theme.css');

但是它没有起作用。这些文件在开发服务器上是可见的:http://localhost:4200/assets/bootstrap.css

有人能帮我一下吗?

谢谢

编辑:

ember -v
ember-cli 0.0.23

brocfile.js

    /* global require, module */

var uglifyJavaScript = require('broccoli-uglify-js');
var replace = require('broccoli-replace');
var compileES6 = require('broccoli-es6-concatenator');
var validateES6 = require('broccoli-es6-import-validate');
var pickFiles = require('broccoli-static-compiler');
var mergeTrees = require('broccoli-merge-trees');

var env = require('broccoli-env').getEnv();
var getEnvJSON = require('./config/environment');

var p = require('ember-cli/lib/preprocessors');
var preprocessCss = p.preprocessCss;
var preprocessTemplates = p.preprocessTemplates;
var preprocessJs = p.preprocessJs;

module.exports = function (broccoli) {

  var prefix = 'caisse';
  var rootURL = '/';

  // index.html

  var indexHTML = pickFiles('app', {
    srcDir: '/',
    files: ['index.html'],
    destDir: '/'
  });

  indexHTML = replace(indexHTML, {
    files: ['index.html'],
    patterns: [{ match: /\{\{ENV\}\}/g, replacement: getEnvJSON.bind(null, env)}]
  });

  // sourceTrees, appAndDependencies for CSS and JavaScript

  var app = pickFiles('app', {
    srcDir: '/',
    destDir: prefix
  });

  app = preprocessTemplates(app);

  var config = pickFiles('config', { // Don't pick anything, just watch config folder
    srcDir: '/',
    files: [],
    destDir: '/'
  });

  var sourceTrees = [app, config, 'vendor'].concat(broccoli.bowerTrees());
  var appAndDependencies = mergeTrees(sourceTrees, { overwrite: true });

  // JavaScript

  var legacyFilesToAppend = [
    'jquery.js',
    'handlebars.js',
    'ember.js',
    'ic-ajax/dist/named-amd/main.js',
    'ember-data.js',
    'ember-resolver.js',
    'ember-shim.js',
    'bootstrap/dist/js/bootstrap.js'
  ];

  var applicationJs = preprocessJs(appAndDependencies, '/', prefix);

  applicationJs = compileES6(applicationJs, {
    loaderFile: 'loader/loader.js',
    ignoredModules: [
      'ember/resolver',
      'ic-ajax'
    ],
    inputFiles: [
      prefix + '/**/*.js'
    ],
    legacyFilesToAppend: legacyFilesToAppend,
    wrapInEval: env !== 'production',
    outputFile: '/assets/app.js'
  });

  if (env === 'production') {
    applicationJs = uglifyJavaScript(applicationJs, {
      mangle: false,
      compress: false
    });
  }

  // Styles

  var styles = preprocessCss(appAndDependencies, prefix + '/styles', '/assets');

  // Bootstrap Style integration
  var bootstrap = pickFiles('vendor', {
    srcDir: '/bootstrap/dist/css',
    files: [
      'bootstrap.css',
      'bootstrap-theme.css'
    ],
    destDir: '/assets/'
  });

//var bootstrap = preprocessCss(appAndDependencies, '/vendor/bootstrap/dist/css', '/assets');

  // Ouput

  var outputTrees = [
    indexHTML,
    applicationJs,
    'public',
    styles,
    bootstrap
  ];

  // Testing

  if (env !== 'production') {

    var tests = pickFiles('tests', {
      srcDir: '/',
      destDir: prefix + '/tests'
    });

    var testsIndexHTML = pickFiles('tests', {
      srcDir: '/',
      files: ['index.html'],
      destDir: '/tests'
    });

    var qunitStyles = pickFiles('vendor', {
      srcDir: '/qunit/qunit',
      files: ['qunit.css'],
      destDir: '/assets/'
    });

    testsIndexHTML = replace(testsIndexHTML, {
      files: ['tests/index.html'],
      patterns: [{ match: /\{\{ENV\}\}/g, replacement: getEnvJSON.bind(null, env)}]
    });

    tests = preprocessTemplates(tests);

    sourceTrees = [tests, 'vendor'].concat(broccoli.bowerTrees());
    appAndDependencies = mergeTrees(sourceTrees, { overwrite: true });

    var testsJs = preprocessJs(appAndDependencies, '/', prefix);

    var validatedJs = validateES6(mergeTrees([app, tests]), {
      whitelist: {
        'ember/resolver': ['default'],
        'ember-qunit': [
          'globalize',
          'moduleFor',
          'moduleForComponent',
          'moduleForModel',
          'test',
          'setResolver'
        ]
      }
    });

    var legacyTestFiles = [
      'qunit/qunit/qunit.js',
      'qunit-shim.js',
      'ember-qunit/dist/named-amd/main.js'
    ];

    legacyFilesToAppend = legacyFilesToAppend.concat(legacyTestFiles);

    testsJs = compileES6(testsJs, {
      // Temporary workaround for
      // https://github.com/joliss/broccoli-es6-concatenator/issues/9
      loaderFile: '_loader.js',
      ignoredModules: [
        'ember/resolver',
        'ember-qunit'
      ],
      inputFiles: [
        prefix + '/**/*.js'
      ],
      legacyFilesToAppend: legacyFilesToAppend,

      wrapInEval: true,
      outputFile: '/assets/tests.js'
    });

    var testsTrees = [qunitStyles, testsIndexHTML, validatedJs, testsJs];
    outputTrees = outputTrees.concat(testsTrees);
  }

  return mergeTrees(outputTrees, { overwrite: true });
};

你能展示一下你的ember-cli版本和Brocfile.js内容吗? - Marcio Junior
同时,在将 /styles 复制到 index.html 后,也包括以下内容:<link rel="stylesheet" href="assets/bootstrap.css"><link rel="stylesheet" href="assets/bootstrap-theme.css"> - Guidouil
9个回答

68

BASH:

bower install --save bootstrap

Brocfile.js:

app.import('vendor/bootstrap/dist/js/bootstrap.js');
app.import('vendor/bootstrap/dist/css/bootstrap.css');

JS将会被添加到默认链接的app.js中,CSS将会被添加到assets/vendor.css中,默认情况下从5月14日开始。

参考:http://www.ember-cli.com/#managing-dependencies

针对@Joe有关字体和其他资产的问题,我无法使用推荐的app.import()方法来处理字体。我选择了合并树和静态编译器的方法:

var mergeTrees = require('broccoli-merge-trees');
var pickFiles = require('broccoli-static-compiler');
var extraAssets = pickFiles('vendor/bootstrap/dist/fonts',{
    srcDir: '/', 
    files: ['**/*'],
    destDir: '/fonts'
});

module.exports = mergeTrees([app.toTree(), extraAssets]);

9
需要重启服务器,因为 Livereload 不会自动捕捉到 brocfile 的更改...我想 :) - max
7
如果你正在使用ember-cli v0.0.35或更新版本,你可能需要在你的package.json文件中包含一些Broccoli插件。你可以通过以下方式添加它们:npm install --save-dev broccoli-merge-treesnpm install --save-dev broccoli-static-compiler - Sean O'Hara
5
请注意,现在使用Bower安装的所有内容都已将“vendor”替换为“bower_components”。但是,“vendor”文件夹仍可用于用户指定的库。 - SeanK
6
你还可以使用app.import('vendor/bootstrap/dist/fonts/glyphicons-halflings-regular.woff', { destDir: 'fonts' }); 导入字体。请查看以下链接http://miguelcamba.com/blog/2014/08/10/import-bootstrap-glyphicons-in-ember-cli/。 - Jose S
3
看起来我的生成项目也请求了 boostrap.css.map 文件,所以我也添加了下面这行代码。app.import('bower_components/bootstrap/dist/css/bootstrap.css.map', { destDir: 'assets' }); - consideRatio
显示剩余3条评论

46

BASH:

bower install --save bootstrap

Brocfile.js:

/* global require, module */

...


app.import('bower_components/bootstrap/dist/css/bootstrap.css');
app.import('bower_components/bootstrap/dist/css/bootstrap.css.map', {
    destDir: 'assets'
});
app.import('bower_components/bootstrap/dist/fonts/glyphicons-halflings-regular.eot', {
    destDir: 'fonts'
});
app.import('bower_components/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf', {
    destDir: 'fonts'
});
app.import('bower_components/bootstrap/dist/fonts/glyphicons-halflings-regular.svg', {
    destDir: 'fonts'
});
app.import('bower_components/bootstrap/dist/fonts/glyphicons-halflings-regular.woff', {
    destDir: 'fonts'
});
app.import('bower_components/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2', {
    destDir: 'fonts'
});

app.import('bower_components/bootstrap/dist/js/bootstrap.js');

module.exports = app.toTree();

这是一个不错的方法,适用于Ember 1.9版本,直到ember-cli-bootstrap更新支持handlebars >=2.0。 - genkilabs
2
Sean O'Hara 在 Drew 的回答中提到的命令应该添加到这里:npm install --save-dev broccoli-merge-trees && npm install --save-dev broccoli-static-compiler - Timo
@TimoLehto,cli相比broc import有什么优势? - SuperUberDuper
@SuperUberDuper 使用cli-bootstrap的原因(在我看来)是因为它不仅使得bootstrap的安装与其他cli插件保持一致,而且对于大型团队构建多个标准应用程序或招聘和培训新开发人员来说更加清晰和可重复。当然,对于小团队或玩具应用程序来说这并不重要,但是使用一致的实践、安装和插件可以帮助减少工业开发中的错误。 - genkilabs
@genkilabs 谢谢,但我还是不太确定。对于使用 bower 中的 bootstrap 和在 brocfile 中合并树的团队来说,这非常容易理解,而且你可以轻松更改 bootstrap 版本。 - SuperUberDuper
显示剩余5条评论

41

你可能想要查看 ember-bootstrap,它可以自动导入 bootstrap 资源。

ember install ember-bootstrap

此外,它为您的应用程序添加了一套原生 Ember 组件,使得在 Ember 中使用 Bootstrap 功能变得更加容易。看看吧,虽然我有点偏见,因为我是它的作者! ;)


2
这个命令足以将任何现有的Ember项目转换为Bootstrap。谢谢Simon。 - Raja Nagendra Kumar
ember-bootstrap非常出色!但是,这里缺少一个组件,那就是走马灯。如果您需要使用走马灯,则需要按照@rastapasta的说明安装bootstrap组件--似乎ember-bootstrap没有将transitions.js作为其引入的bootstrap资产的一部分,而这是走马灯所必需的。 - RyanNerd
@RyanNerd 谢谢!是的,走马灯还没有。但希望在即将到来的1.0版本发布后不久就会添加! - Simon Ihmig

23

更新 3/30/15

虽然时光荏苒...我现在使用ember-cli-bootstrap-sassy,它似乎只带最少的垃圾,同时还让我可以自定义Bootstrap的变量。


更新 1/22/15

你应该使用Johnny上面提到的解决方法,而不是我原先提到的库。我也喜欢ember-cli-bootstrap-sass,因为我可以直接在项目中自定义Bootstrap的变量。

原始 7/11/14

如果您正在使用支持插件(我相信是0.35+)的ember-cli版本,则可以使用ember-cli-bootstrap软件包。从您的应用程序根目录开始,

npm install --save-dev ember-cli-bootstrap

就是这样!

注意:正如@poweratom所指出的,ember-cli-bootstrap是别人的库,它选择还包括bootstrap-for-ember。因此,这个库可能会与官方的bootstrap版本脱节。不过,我仍然认为这是在新项目上快速进行原型设计的好方法!


2
将当前版本更改为您的当前版本。 当前版本今天(0.0.39)甚至可能不是您正在使用的版本... - Jacob van Lingen
现在的 ember-cli-bootstrap 中不包括 bootstrap.js,因此您将无法使用内置的 javascript 方法或各种插件。 - drew covi
2
我不确定这是否应该是一种“推荐”的安装方式。 'ember-cli-bootstrap' 项目依赖于 'bootstrap-for-ember' 项目。不幸的是,根据后者项目的维护者所说,他宣布正在开发 'ember-components' 项目作为其继承者。所以,除非有人来接手他的工作(我相信该项目目前正在使用bootstrap 3.0.0),否则Bootstrap版本很快就会变得陈旧(已经陈旧了)。 - poweratom

15
$> bower install --save bootstrap

接下来将以下两行添加到你的 ember-cli-build.js 中(如果你在使用旧版本的Ember.js,则添加到Brocfile.js中):

app.import(app.bowerDirectory + '/bootstrap/dist/js/bootstrap.js');
app.import(app.bowerDirectory + '/bootstrap/dist/css/bootstrap.css');

完成了,准备就绪!

更新于08/18/2015:适应了Ember.js 1.13中引入的新方案。


1
最新版本的ember-cli不再包含brocfile.js文件。 - Mad Scientist
5
@MadScientist,您可以使用'ember-cli-build.js'进行导入,上述步骤仍可使用。(Ember版本:1.12.6) - Alan Francis
你如何将这种方法与Bootstrap覆盖一起使用,例如https://bootswatch.com/flatly/? - Ben

6
如果你正在使用SASS(可能是通过ember-cli-sass),bower_components会自动添加到查找路径中。这意味着你可以只使用Bower,避免使用Brocfile / ember-cli-build文件。

使用Bower安装Bootstrap的官方SASS版本。

bower install --save bootstrap-sass

然后在app.scss中导入该库。这样做的好处是您可以在导入bootstrap之前自定义变量:

$brand-primary: 'purple';

@import 'bower_components/bootstrap-sass/assets/stylesheets/bootstrap';

或者 $ ember install ember-cli-sass $ ember install ember-cli-bootstrap-sassy 然后将 app.css 重命名为 app.scss 并在其中添加这一行:@import "bootstrap" - rmcsharry

5
这是我如何使用Broccoli(Ember-cli的基础)打包供应商CSS文件的方法。
 var vendorCss = concat('vendor', {
   inputFiles: [
     'pikaday/css/pikaday.css'
   , 'nvd3/nv.d3.css'
   , 'semantic-ui/build/packaged/css/semantic.css'
   ]
  , outputFile: '/assets/css/vendor.css'
  });

vendor 文件夹是存放我的 Bower 包的地方。而 assets 则是我期望存放 CSS 的地方。我假设您已经使用 Ember-cli 自带的 Bower 安装了 Bootstrap。

然后在我的 index.html 中,我只需要引用那个 vendor.css 文件:

  <link href="/assets/css/vendor.css" rel="stylesheet" type="text/css" media="all">

干杯。

我尝试了一下,但它告诉我在 Broccoli 中未定义 concat (ReferenceError: concat is not defined)。我只是通过更改应用程序文件夹根目录中的 Brocfile.js 文件中包含样式表的路径来添加它。 - Guidouil
1
安装插件 npm install broccoli-concat --save 然后在你的 Brocfile 文件顶部添加:var concat = require('broccoli-concat'); - Johnny Hall

3
bower install --save bootstrap

在你的brocfile.js中:
app.import('bower_components/bootstrap/dist/js/bootstrap.js');
app.import('bower_components/bootstrap/dist/css/bootstrap.css');

我不知道为什么这实际上被标记了。除非您知道在哪里放置这些语句,否则可能不太清楚。但它运行良好...也许不像插件那样好看,我承认。它们放在 ember-cli-build.js 文件中,如果有人需要,它可以正常工作。我正在从 Asp.Net MVC 项目内部提供我的 Ember,并且需要它可用于该项目,而不仅仅是 Ember 应用程序。 - hal9000

0
在终端上(对于使用Node Package Manager的人)
npm install bootstrap --save

使用ember-cli,导入已安装的bootstrap 打开ember-cli-build.js文件
module.exports = function(defaults) {
  let app = new EmberApp(defaults, {
    // Add options here
  });
app.import('node_modules/bootstrap/dist/css/bootstrap.min.css');
app.import('node_modules/bootstrap/dist/js/bootstrap.min.js');

如果通过NPM安装程序包,那么这样做就可以了。

不要这样做:

app.import('./node_modules/bootstrap/dist/css/bootstrap.min.css');
app.import('./node_modules/bootstrap/dist/js/bootstrap.min.js');

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