通过示例自定义 Bootstrap 3 管道
Custom Bootstrap 3 pipeline by example
我有兴趣使用我自己的颜色和主题自定义 Twitter Bootstrap 3。我 不 对使用网络工具或专有(付费)工具感兴趣,并且想通过从命令创建 "pipeline"(运行 -line),它采用一些初始工件集(LESS 文件等)并将它们转换为完全 minified、Bootstrap.
的自定义版本
我对基本流程的理解是:
我不明白的是:
- 什么工具(LESS、g运行t、bower 等)构成了这个管道,我们用它们做什么(特别是)?做 LESS,g运行t 和 bower 都做同样的事情还是他们处理不同的事情 transformations/operations(如果是,那是什么)?
- 我们从 TB3 CSS 和 JS 开始的初始工件是什么?它们是什么类型的文件?
- minification/uglification是如何实现的?由于我们使用命令行工具来生成我的自定义 TB3,这些可以只是 "any" 旧 minifier/uglifier 吗?
您的管道有点过头了。您只需要在 source
文件夹中设置项目(使用 Bootstrap + 其他依赖项和自定义主题代码),然后使用构建工具将所有内容编译到 destination
文件夹中.
- Gulp and Grunt 是两个最常用的构建工具。 Grunt 配置比较重,Gulp 只使用 JS 脚本。两者都有大量的插件,您可以自定义插件以按照您想要的方式进行构建。他们从字面上使用您设置的命令从源文件构建您的站点。
- Bower是一个前端JS包管理器。它只是为你存放 JS 包,并将它们包含到你的项目中。
- LESS and presumably Sass 是 CSS 预处理器,您可以在其中编写您的样式。您的构建工具将获取它们的内容并自动将它们变成缩小的 CSS。
如果这是您第一次从头开始制作这样的管道,请不要这样做。你会陷入困境。从另一个基地开始要容易得多。最好的选择之一是使用 Yeoman,它搭建了一个已经包含 Bower + Build Tools 的基本应用程序。
我最喜欢的基础是他们的 Gulp Webapp,其中包括 Bootstrap、Bower、Sass、Gulp 并且已经在 [=13] 中设置了构建管道=](这将在项目的根目录中)。通读有关此生成器的文档 - 它解释了您在此 SO post.
中遇到的一堆问题
至于 LESS 如何与构建管道一起工作:
var less = require('gulp-less');
var minifyCSS = require('gulp-minify-css');
gulp.task('styles', function() {
gulp.src(['app/styles/*.less'])
.pipe(less())
.pipe(minifyCSS())
.pipe(gulp.dest('dist'))
.pipe(refresh(server))
})
- 将所有自定义 LESS 样式文件(具有 .less 扩展名的文件)添加到
styles
子目录中,该子目录将位于上述 gulp-webapp 生成器的 app
文件夹中多于。这将是您的自定义样式代码。
- 在您的构建中,您需要包含到
gulp-less
plugin 并如上所示实施。
- 缩小是通过上面代码块中引用的另一个名为
gulp-minify-css
的插件完成的。
我运行很多次都是这样的问题!
所以,相信我,请按照以下步骤操作:
(使用 Grunt)
- 通过 bower(或直接下载)带来 bootstrap-sources 并将它们放在您的源目录中,通常 frontend/src (/scss 用于样式表,/js 用于 javascript)
- 安装 grunt-sass (that uses libSass,比 ruby 编译器更快)
- 安装grunt-contrib-uglify
Consider using Sass instead of less because the next version of bootstrap drops less!
这就是拥有最小构建系统的全部!
当然,你可以从很多方面改进它,你可以从one that i made
开始
希望对您有所帮助!
我认为流水线的想法是有效的并且不过分,因为它加快了开发周期。我有一个项目可以作为起点。
https://github.com/mhanney/twitter-bootstrap-customization
它按照你的建议使用了G运行t、Bower和LESS,还优化了css和js。我称它为管道,因为它使用 grunt-contrib-watch
和 grunt-contrib-connect
在文件更改时重建和重新加载文件。这使得迭代主题比使用 point and click web UI.
耗时少得多
我以这种方式进行自定义构建的动机不仅是自定义主题,而且还为移动网络应用程序制作更小的 Bootstrap.css 和 Bootstrap.js。许多 类 和 js 功能可以省略。我使用 uncss
和 processhtml
g运行t 插件的组合来做到这一点。
我上面链接的项目是我典型的移动网络应用程序构建过程的简化版本。 gruntfile.js
中的注释应该有助于阐明管道中每个步骤的作用。我在此处的回答中包含了 package.json、bower.json、gruntfile.js 和自述文件以供快速参考,但您也需要其他部分。
@staypuftman 和@Hitmands 提出了很好的观点。为什么对@Hitmands 投反对票?这是一个很好的答案。总是有不止一种方法可以做到这一点。
package.json
{
"name": "Twitter-Bootstrap-Customization-Pipeline-Example",
"description": "Twitter Bootstrap Customization Pipeline using Grunt",
"version": "0.0.1",
"build": "1",
"license": "MIT",
"repository": "git@github.com:mhanney/twitter-bootstrap-customization.git",
"private": false,
"author": {
"name": "mhanney",
"url": "https://github.com/mhanney/twitter-bootstrap-customization"
},
"devDependencies": {
"bower": "^1.4.1",
"connect": "~3.4.0",
"grunt": "^0.4.5",
"grunt-autoprefixer": "^3.0.3",
"grunt-bower-task": "^0.4.0",
"grunt-cli": "0.1.13",
"grunt-contrib-clean": "^0.6.0",
"grunt-contrib-concat": "^0.5.1",
"grunt-contrib-connect": "^0.10.1",
"grunt-contrib-cssmin": "~0.12.3",
"grunt-contrib-less": "^1.0.1",
"grunt-contrib-uglify": "^0.10.0",
"grunt-contrib-watch": "0.6.1",
"grunt-processhtml": "~0.3.8",
"grunt-uncss": "~0.4.3",
"less-plugin-autoprefix": "^1.4.2"
}
}
bower.json
{
"name": "Twitter-Bootstrap-Customization-Pipeline-Example",
"version": "0.0.1",
"dependencies": {
"bootstrap": "~3.3.5"
},
"private": false
}
gruntfile.js
module.exports = function(grunt) {
'use strict';
grunt.loadNpmTasks('grunt-bower-task');
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-uncss');
grunt.loadNpmTasks('grunt-processhtml');
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.loadNpmTasks('grunt-contrib-connect');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.initConfig({
// variable to the location of the bootstrap javascript source
dirs: {
'bootstrapjs': 'bower_components/bootstrap/js',
},
// defer to bower.json to decide which bower packages to install
bower: {
install: {}
},
// Process the bootstrap less files.
// The paths setting here is critical.
// We include all of the bootstrap less files from bower,
// then incude our modifications and overrides to
// bootstrap by bringing in the file src/theme/build.less.
// Our build.less is actually a list of more includes.
// This is a shortcut. We could have listed all our less includes
// here instead.
//
// We then use the less-plugin-autoprefix plug-in to
// only add brower specific prefixes for our known target audience -
// in my case this is mobile browsers - iOS and Android.
// The result of the less build is placed into our 'intermediate' directory
// for the optimization steps.
less: {
default: {
options: {
paths: ['bower_components/bootstrap/less'],
compress: false,
strictMath: true,
plugins: [
new(require('less-plugin-autoprefix'))({
browsers: ['iOS >= 7', 'Android >= 4', 'last 2 versions']
})
],
},
files: {
'intermediate/bootstrap-custom.css': 'src/theme/build.less'
},
}
},
// css minification
cssmin: {
minify: {
expand: false,
src: 'intermediate/bootstrap-custom.css',
dest: 'public/bootstrap-custom.min.css'
}
},
// uncss removes css styles not found in src/index.html
uncss: {
public: {
files: {
'public/bootstrap-custom.css': ['src/index.html']
}
}
},
// The file 'src/index.html' gets transformed by processhtml to use our
// optimized 'uncss' version of bootstrap.
// The processed index.html is copied into the `public`
// directory where it is served by connect
processhtml: {
public: {
files: {
'public/index.html': ['src/index.html'],
}
}
},
// Declare which components of bootstrap.js to include.
// Concatenate the files we choose into one file
// called bootstrap-custom.js in the `intermediate`
// directory where it will get processed by the next
// step in the pipeline - `uglify` for js minification.
// Be very careful here not to cut too munch of Bootstrap's
// functionality. I do this optimization only when I am absolutely sure
// that whole features - such as modals - are not used in a mobile
// we app.
concat: {
bootstrap: {
src: [
'<%=dirs.bootstrapjs%>/transition.js',
//'<%=dirs.bootstrapjs%>/alert.js',
//'<%=dirs.bootstrapjs%>/button.js',
//'<%=dirs.bootstrapjs%>/carousel.js',
'<%=dirs.bootstrapjs%>/collapse.js',
//'<%=dirs.bootstrapjs%>/dropdown.js',
//'<%=dirs.bootstrapjs%>/modal.js',
//'<%=dirs.bootstrapjs%>/tooltip.js',
//'<%=dirs.bootstrapjs%>/popover.js',
//'<%=dirs.bootstrapjs%>/scrollspy.js',
//'<%=dirs.bootstrapjs%>/tab.js',
//'<%=dirs.bootstrapjs%>/affix.js'
],
dest: 'intermediate/bootstrap-custom.js'
}
},
// js minification
// A standard uglification task.
// Takes the bootstrap js from the `intermediate`
// dir and puts a minified copy in `public` - the dir
// being served by node/connect for previewing.
uglify: {
options: {
sourceMap: true
},
bootstrap: {
files: {
'public/bootstrap-custom.min.js': ['intermediate/bootstrap-custom.js']
}
}
},
// Start up a simple nodejs web server for fast reload of the test index
// page that references our custom bootstrap css and js.
// With livereload = true changes will update in the browser without having
// to manually F5 reload in the browser.
// We set keepalive to false, because the `watch` task has a
// keepalive=true and that is enough to keep the
// grunt task runner from stopping (which would stop connect)
connect: {
base: {
options: {
base: 'public',
port: 8082,
livereload: true,
keepalive: false,
open: true
}
}
},
// Run the css pipeline again if any of the following files change.
// With livereload = true changes will update in the browser without having
// to manually F5 reload in the browser.
watch: {
files: ['src/theme/bootstrap.less',
'src/theme/variables.less',
'src/theme/structural.less',
'src/index.html'
],
tasks: 'css',
options: {
livereload: true,
nospawn: true
}
},
// Utility task to clean up
// the temporary `intermediate`
// and `public` directories.
// Be very, very careful running grunt clean:nuke
// it only exists for making a really, really clean
// source tree for pushing to source control.
clean: {
build: {
src: ['intermediate/*.*',
'public/*.*']
},
nuke: {
src: ['bower_components',
'lib',
'node_modules',
'intermediate',
'public']
}
}
});
// We declare task `targets`, or aliases so that
// we can call them individually on the command line
// if we want. This is useful for testing the order in which
// the tasks need to run. To run just one of these tasks,
// do `grunt css` - for example.
// declare a task target called 'css' that will do the
// less, uncss, cssmin and processhtml tasks
grunt.registerTask('css', ['clean:build', 'less', 'cssmin', 'processhtml:public']);
// declare a task target called 'js' that will do the concat and uglify steps
grunt.registerTask('js', ['concat', 'uglify']);
// declare the default task that will run
// the `css` target, followed by the `js` target.
// Order is important here. We must build the css and js before
// starting the `connect` local web server, and file watcher tasks
grunt.registerTask('default', ['css', 'js', 'connect', 'watch']);
};
自述文件
Twitter Bootstrap 3 自定义管道示例
这是使用 g运行t 自定义 Twitter Bootstrap 的构建过程。
动机
问题
- Twitter Bootstrap 的受欢迎程度使得所有使用它的网站看起来都差不多。
我们经常需要自定义主题以与公司的品牌保持一致。
此外,Twitter Bootstrap CSS 对于移动浏览器来说实际上有点大 (~130K)
并且通常包含许多未使用的样式。许多 JavaScript 组件
对于为移动 Web 应用程序量身定制的超精益构建,也可以删除。最后,网络点击工具很好,但在迭代设计时需要大量劳动。我们需要一个连续的 'watch and rebuild' 管道。
解决方案
- 使用 g运行t 任务 运行ner 我们将构建一个高效的管道来
构建 Bootstrap JavaScript 和 CSS,优化输出,将其放在测试中
index.html 页面,并让 g运行t 观察源文件的变化,以便
管道自动重新开始,并且更改在浏览器中可见
无需按 F5 即可立即执行。
TL;DR
- 安装节点和 npm
git clone git@github.com:mhanney/twitter-bootstrap-customization.git
cd twitter-bootstrap-customization
npm install --no-optional
grunt bower
grunt
- 更改src/theme
中的less文件
- 立即在 http://localhost:8082
查看更改
什么是什么?
NPM
NPM 是节点的包管理器。我们用它来放置 g运行t 任务(在 node_modules 中)。
我们只使用 NPM 来获取我们的构建管道工具。我们不使用 NPM 来获取我们的前端组件源。
使用 Bower 更有意义,即使可以从 NPM 获取 Bootstrap 和 jQuery,
因为 Bower 将前端资源放在 ~/lib 中——这是一个更合乎逻辑的引用位置
index.html 测试页面比 ~/node_modules.
下某处的资源
凉亭
Bower 是前端 Web 组件的包管理器。
我们将使用它将 bootstrap 源(及其依赖 - jQuery)引入我们的项目。
就这些。我们仅使用 Bower 将由其他方维护的源文件复制到位。
bower g运行t 任务下载 bootstrap 和 jQuery 并将它们的源放入 bower_components 并将它们的未压缩版本放入 lib.
如果 Bower 任务失败并显示 - git ls-remote exit code of #128
- 那么您可能遇到阻止 git 协议的防火墙问题。解决方法是将协议更改为 https:
git config --global url."https://".insteadOf git://
G运行t
Grunt 是 运行ner JavaScript 的任务。
我们将使用它来自动化 运行 构建 Twitter Bootstrap 所涉及的命令。
G运行t 任务只是命令 运行ners,其参数在 JSON.
中声明
g运行t 任务的排序使得:
- Bootstrap LESS 文件变成了 CSS
- CSS 为自定义浏览器列表添加了供应商特定前缀
- 通过检查使用 CSS 文件的页面删除未使用的 CSS 类
- 处理 HTML 以包括优化的 CSS 而不是原始的
- 优化后的CSS进一步缩小
- 观看可编辑的.less文件,整个管道再次运行。
- 浏览器会在检测到构建更改时自动刷新。
- Twitter Bootstrap JavaScript 组件可以打开和关闭。
- Twitter Bootstrap JavaScript 使用 uglify 缩小。
少
Less is a CSS pre-processor, meaning that it extends the CSS language, adding features that allow variables, mixins, functions and many other techniques that allow you to make CSS that is more maintainable, themable and extendable.
自定义
主题由三个 LESS 文件组成。
* src/theme/bootstrap.less
- 要包含的其他文件列表
如果你知道有bootstrap个你肯定不会用到的组件,
你可以在 src/theme/bootstrap.less
中将它们注释掉
如果您破坏了某些内容,请不要担心,重新评论它是微不足道的。
* src/theme/variables.less
,默认包含在 Bootstrap,
允许您自定义 these settings。
* src/theme/structural.less
引入了更广泛的结构变化。
这些是唯一被观看较少的文件。
优化
grunt-uncss 是一个 g运行t 任务,用于从您的项目中删除未使用的 CSS。这是移动网络的超级优化。在一些项目中,我通过删除未使用的样式将 ~130K Bootstrap.css 文件减少到不到 30K。
grunt-contrib-uglify
使用 Uglify
缩小 JavaScript
连接并自动重新加载
连接 Web 服务器进程将服务于 public/index.html 文件
localhost:8082 并观察我们的文件是否有变化。
检测到更改后,索引页面将自动在浏览器中重新加载。
版权和许可
版权所有 (c) 2014 "mhanney" Michael Hanney
特此免费授予任何人许可
获取此软件和相关文档的副本
文件("Software"),无需处理软件
限制,包括但不限于使用权,
复制、修改、合并、发布、分发、再许可、and/or 出售
该软件的副本,并允许那些人
为此提供软件,但须满足以下条件
条件:
以上版权声明及本许可声明为
包含在软件的所有副本或重要部分中。
软件的提供 "AS IS",没有任何形式的保证,
明示或暗示的,包括但不限于保证
适销性,适用于特定用途和
非侵权。在任何情况下,作者或版权均不得
持有人应对任何索赔、损害或其他责任负责,
无论是在合同、侵权或其他方面的诉讼中,
来自、不属于或与软件有关或使用或
软件中的其他交易。
我有兴趣使用我自己的颜色和主题自定义 Twitter Bootstrap 3。我 不 对使用网络工具或专有(付费)工具感兴趣,并且想通过从命令创建 "pipeline"(运行 -line),它采用一些初始工件集(LESS 文件等)并将它们转换为完全 minified、Bootstrap.
的自定义版本我对基本流程的理解是:
我不明白的是:
- 什么工具(LESS、g运行t、bower 等)构成了这个管道,我们用它们做什么(特别是)?做 LESS,g运行t 和 bower 都做同样的事情还是他们处理不同的事情 transformations/operations(如果是,那是什么)?
- 我们从 TB3 CSS 和 JS 开始的初始工件是什么?它们是什么类型的文件?
- minification/uglification是如何实现的?由于我们使用命令行工具来生成我的自定义 TB3,这些可以只是 "any" 旧 minifier/uglifier 吗?
您的管道有点过头了。您只需要在 source
文件夹中设置项目(使用 Bootstrap + 其他依赖项和自定义主题代码),然后使用构建工具将所有内容编译到 destination
文件夹中.
- Gulp and Grunt 是两个最常用的构建工具。 Grunt 配置比较重,Gulp 只使用 JS 脚本。两者都有大量的插件,您可以自定义插件以按照您想要的方式进行构建。他们从字面上使用您设置的命令从源文件构建您的站点。
- Bower是一个前端JS包管理器。它只是为你存放 JS 包,并将它们包含到你的项目中。
- LESS and presumably Sass 是 CSS 预处理器,您可以在其中编写您的样式。您的构建工具将获取它们的内容并自动将它们变成缩小的 CSS。
如果这是您第一次从头开始制作这样的管道,请不要这样做。你会陷入困境。从另一个基地开始要容易得多。最好的选择之一是使用 Yeoman,它搭建了一个已经包含 Bower + Build Tools 的基本应用程序。
我最喜欢的基础是他们的 Gulp Webapp,其中包括 Bootstrap、Bower、Sass、Gulp 并且已经在 [=13] 中设置了构建管道=](这将在项目的根目录中)。通读有关此生成器的文档 - 它解释了您在此 SO post.
中遇到的一堆问题至于 LESS 如何与构建管道一起工作:
var less = require('gulp-less');
var minifyCSS = require('gulp-minify-css');
gulp.task('styles', function() {
gulp.src(['app/styles/*.less'])
.pipe(less())
.pipe(minifyCSS())
.pipe(gulp.dest('dist'))
.pipe(refresh(server))
})
- 将所有自定义 LESS 样式文件(具有 .less 扩展名的文件)添加到
styles
子目录中,该子目录将位于上述 gulp-webapp 生成器的app
文件夹中多于。这将是您的自定义样式代码。 - 在您的构建中,您需要包含到
gulp-less
plugin 并如上所示实施。 - 缩小是通过上面代码块中引用的另一个名为
gulp-minify-css
的插件完成的。
我运行很多次都是这样的问题! 所以,相信我,请按照以下步骤操作:
(使用 Grunt)
- 通过 bower(或直接下载)带来 bootstrap-sources 并将它们放在您的源目录中,通常 frontend/src (/scss 用于样式表,/js 用于 javascript)
- 安装 grunt-sass (that uses libSass,比 ruby 编译器更快)
- 安装grunt-contrib-uglify
这就是拥有最小构建系统的全部! 当然,你可以从很多方面改进它,你可以从one that i made
开始希望对您有所帮助!
我认为流水线的想法是有效的并且不过分,因为它加快了开发周期。我有一个项目可以作为起点。
https://github.com/mhanney/twitter-bootstrap-customization
它按照你的建议使用了G运行t、Bower和LESS,还优化了css和js。我称它为管道,因为它使用 grunt-contrib-watch
和 grunt-contrib-connect
在文件更改时重建和重新加载文件。这使得迭代主题比使用 point and click web UI.
我以这种方式进行自定义构建的动机不仅是自定义主题,而且还为移动网络应用程序制作更小的 Bootstrap.css 和 Bootstrap.js。许多 类 和 js 功能可以省略。我使用 uncss
和 processhtml
g运行t 插件的组合来做到这一点。
我上面链接的项目是我典型的移动网络应用程序构建过程的简化版本。 gruntfile.js
中的注释应该有助于阐明管道中每个步骤的作用。我在此处的回答中包含了 package.json、bower.json、gruntfile.js 和自述文件以供快速参考,但您也需要其他部分。
@staypuftman 和@Hitmands 提出了很好的观点。为什么对@Hitmands 投反对票?这是一个很好的答案。总是有不止一种方法可以做到这一点。
package.json
{
"name": "Twitter-Bootstrap-Customization-Pipeline-Example",
"description": "Twitter Bootstrap Customization Pipeline using Grunt",
"version": "0.0.1",
"build": "1",
"license": "MIT",
"repository": "git@github.com:mhanney/twitter-bootstrap-customization.git",
"private": false,
"author": {
"name": "mhanney",
"url": "https://github.com/mhanney/twitter-bootstrap-customization"
},
"devDependencies": {
"bower": "^1.4.1",
"connect": "~3.4.0",
"grunt": "^0.4.5",
"grunt-autoprefixer": "^3.0.3",
"grunt-bower-task": "^0.4.0",
"grunt-cli": "0.1.13",
"grunt-contrib-clean": "^0.6.0",
"grunt-contrib-concat": "^0.5.1",
"grunt-contrib-connect": "^0.10.1",
"grunt-contrib-cssmin": "~0.12.3",
"grunt-contrib-less": "^1.0.1",
"grunt-contrib-uglify": "^0.10.0",
"grunt-contrib-watch": "0.6.1",
"grunt-processhtml": "~0.3.8",
"grunt-uncss": "~0.4.3",
"less-plugin-autoprefix": "^1.4.2"
}
}
bower.json
{
"name": "Twitter-Bootstrap-Customization-Pipeline-Example",
"version": "0.0.1",
"dependencies": {
"bootstrap": "~3.3.5"
},
"private": false
}
gruntfile.js
module.exports = function(grunt) {
'use strict';
grunt.loadNpmTasks('grunt-bower-task');
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-uncss');
grunt.loadNpmTasks('grunt-processhtml');
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.loadNpmTasks('grunt-contrib-connect');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.initConfig({
// variable to the location of the bootstrap javascript source
dirs: {
'bootstrapjs': 'bower_components/bootstrap/js',
},
// defer to bower.json to decide which bower packages to install
bower: {
install: {}
},
// Process the bootstrap less files.
// The paths setting here is critical.
// We include all of the bootstrap less files from bower,
// then incude our modifications and overrides to
// bootstrap by bringing in the file src/theme/build.less.
// Our build.less is actually a list of more includes.
// This is a shortcut. We could have listed all our less includes
// here instead.
//
// We then use the less-plugin-autoprefix plug-in to
// only add brower specific prefixes for our known target audience -
// in my case this is mobile browsers - iOS and Android.
// The result of the less build is placed into our 'intermediate' directory
// for the optimization steps.
less: {
default: {
options: {
paths: ['bower_components/bootstrap/less'],
compress: false,
strictMath: true,
plugins: [
new(require('less-plugin-autoprefix'))({
browsers: ['iOS >= 7', 'Android >= 4', 'last 2 versions']
})
],
},
files: {
'intermediate/bootstrap-custom.css': 'src/theme/build.less'
},
}
},
// css minification
cssmin: {
minify: {
expand: false,
src: 'intermediate/bootstrap-custom.css',
dest: 'public/bootstrap-custom.min.css'
}
},
// uncss removes css styles not found in src/index.html
uncss: {
public: {
files: {
'public/bootstrap-custom.css': ['src/index.html']
}
}
},
// The file 'src/index.html' gets transformed by processhtml to use our
// optimized 'uncss' version of bootstrap.
// The processed index.html is copied into the `public`
// directory where it is served by connect
processhtml: {
public: {
files: {
'public/index.html': ['src/index.html'],
}
}
},
// Declare which components of bootstrap.js to include.
// Concatenate the files we choose into one file
// called bootstrap-custom.js in the `intermediate`
// directory where it will get processed by the next
// step in the pipeline - `uglify` for js minification.
// Be very careful here not to cut too munch of Bootstrap's
// functionality. I do this optimization only when I am absolutely sure
// that whole features - such as modals - are not used in a mobile
// we app.
concat: {
bootstrap: {
src: [
'<%=dirs.bootstrapjs%>/transition.js',
//'<%=dirs.bootstrapjs%>/alert.js',
//'<%=dirs.bootstrapjs%>/button.js',
//'<%=dirs.bootstrapjs%>/carousel.js',
'<%=dirs.bootstrapjs%>/collapse.js',
//'<%=dirs.bootstrapjs%>/dropdown.js',
//'<%=dirs.bootstrapjs%>/modal.js',
//'<%=dirs.bootstrapjs%>/tooltip.js',
//'<%=dirs.bootstrapjs%>/popover.js',
//'<%=dirs.bootstrapjs%>/scrollspy.js',
//'<%=dirs.bootstrapjs%>/tab.js',
//'<%=dirs.bootstrapjs%>/affix.js'
],
dest: 'intermediate/bootstrap-custom.js'
}
},
// js minification
// A standard uglification task.
// Takes the bootstrap js from the `intermediate`
// dir and puts a minified copy in `public` - the dir
// being served by node/connect for previewing.
uglify: {
options: {
sourceMap: true
},
bootstrap: {
files: {
'public/bootstrap-custom.min.js': ['intermediate/bootstrap-custom.js']
}
}
},
// Start up a simple nodejs web server for fast reload of the test index
// page that references our custom bootstrap css and js.
// With livereload = true changes will update in the browser without having
// to manually F5 reload in the browser.
// We set keepalive to false, because the `watch` task has a
// keepalive=true and that is enough to keep the
// grunt task runner from stopping (which would stop connect)
connect: {
base: {
options: {
base: 'public',
port: 8082,
livereload: true,
keepalive: false,
open: true
}
}
},
// Run the css pipeline again if any of the following files change.
// With livereload = true changes will update in the browser without having
// to manually F5 reload in the browser.
watch: {
files: ['src/theme/bootstrap.less',
'src/theme/variables.less',
'src/theme/structural.less',
'src/index.html'
],
tasks: 'css',
options: {
livereload: true,
nospawn: true
}
},
// Utility task to clean up
// the temporary `intermediate`
// and `public` directories.
// Be very, very careful running grunt clean:nuke
// it only exists for making a really, really clean
// source tree for pushing to source control.
clean: {
build: {
src: ['intermediate/*.*',
'public/*.*']
},
nuke: {
src: ['bower_components',
'lib',
'node_modules',
'intermediate',
'public']
}
}
});
// We declare task `targets`, or aliases so that
// we can call them individually on the command line
// if we want. This is useful for testing the order in which
// the tasks need to run. To run just one of these tasks,
// do `grunt css` - for example.
// declare a task target called 'css' that will do the
// less, uncss, cssmin and processhtml tasks
grunt.registerTask('css', ['clean:build', 'less', 'cssmin', 'processhtml:public']);
// declare a task target called 'js' that will do the concat and uglify steps
grunt.registerTask('js', ['concat', 'uglify']);
// declare the default task that will run
// the `css` target, followed by the `js` target.
// Order is important here. We must build the css and js before
// starting the `connect` local web server, and file watcher tasks
grunt.registerTask('default', ['css', 'js', 'connect', 'watch']);
};
自述文件
Twitter Bootstrap 3 自定义管道示例
这是使用 g运行t 自定义 Twitter Bootstrap 的构建过程。
动机
问题
- Twitter Bootstrap 的受欢迎程度使得所有使用它的网站看起来都差不多。 我们经常需要自定义主题以与公司的品牌保持一致。 此外,Twitter Bootstrap CSS 对于移动浏览器来说实际上有点大 (~130K) 并且通常包含许多未使用的样式。许多 JavaScript 组件 对于为移动 Web 应用程序量身定制的超精益构建,也可以删除。最后,网络点击工具很好,但在迭代设计时需要大量劳动。我们需要一个连续的 'watch and rebuild' 管道。
解决方案
- 使用 g运行t 任务 运行ner 我们将构建一个高效的管道来 构建 Bootstrap JavaScript 和 CSS,优化输出,将其放在测试中 index.html 页面,并让 g运行t 观察源文件的变化,以便 管道自动重新开始,并且更改在浏览器中可见 无需按 F5 即可立即执行。
TL;DR
- 安装节点和 npm
git clone git@github.com:mhanney/twitter-bootstrap-customization.git
cd twitter-bootstrap-customization
npm install --no-optional
grunt bower
grunt
- 更改src/theme 中的less文件
- 立即在 http://localhost:8082 查看更改
什么是什么?
NPM
NPM 是节点的包管理器。我们用它来放置 g运行t 任务(在 node_modules 中)。 我们只使用 NPM 来获取我们的构建管道工具。我们不使用 NPM 来获取我们的前端组件源。 使用 Bower 更有意义,即使可以从 NPM 获取 Bootstrap 和 jQuery, 因为 Bower 将前端资源放在 ~/lib 中——这是一个更合乎逻辑的引用位置 index.html 测试页面比 ~/node_modules.
下某处的资源凉亭
Bower 是前端 Web 组件的包管理器。 我们将使用它将 bootstrap 源(及其依赖 - jQuery)引入我们的项目。 就这些。我们仅使用 Bower 将由其他方维护的源文件复制到位。
bower g运行t 任务下载 bootstrap 和 jQuery 并将它们的源放入 bower_components 并将它们的未压缩版本放入 lib.
如果 Bower 任务失败并显示 - git ls-remote exit code of #128
- 那么您可能遇到阻止 git 协议的防火墙问题。解决方法是将协议更改为 https:
git config --global url."https://".insteadOf git://
G运行t
Grunt 是 运行ner JavaScript 的任务。 我们将使用它来自动化 运行 构建 Twitter Bootstrap 所涉及的命令。 G运行t 任务只是命令 运行ners,其参数在 JSON.
中声明g运行t 任务的排序使得:
- Bootstrap LESS 文件变成了 CSS
- CSS 为自定义浏览器列表添加了供应商特定前缀
- 通过检查使用 CSS 文件的页面删除未使用的 CSS 类
- 处理 HTML 以包括优化的 CSS 而不是原始的
- 优化后的CSS进一步缩小
- 观看可编辑的.less文件,整个管道再次运行。
- 浏览器会在检测到构建更改时自动刷新。
- Twitter Bootstrap JavaScript 组件可以打开和关闭。
- Twitter Bootstrap JavaScript 使用 uglify 缩小。
少
Less is a CSS pre-processor, meaning that it extends the CSS language, adding features that allow variables, mixins, functions and many other techniques that allow you to make CSS that is more maintainable, themable and extendable.
自定义
主题由三个 LESS 文件组成。
* src/theme/bootstrap.less
- 要包含的其他文件列表
如果你知道有bootstrap个你肯定不会用到的组件,
你可以在 src/theme/bootstrap.less
中将它们注释掉
如果您破坏了某些内容,请不要担心,重新评论它是微不足道的。
* src/theme/variables.less
,默认包含在 Bootstrap,
允许您自定义 these settings。
* src/theme/structural.less
引入了更广泛的结构变化。
这些是唯一被观看较少的文件。
优化
grunt-uncss 是一个 g运行t 任务,用于从您的项目中删除未使用的 CSS。这是移动网络的超级优化。在一些项目中,我通过删除未使用的样式将 ~130K Bootstrap.css 文件减少到不到 30K。
grunt-contrib-uglify 使用 Uglify
缩小 JavaScript
连接并自动重新加载
连接 Web 服务器进程将服务于 public/index.html 文件 localhost:8082 并观察我们的文件是否有变化。
检测到更改后,索引页面将自动在浏览器中重新加载。
版权和许可
版权所有 (c) 2014 "mhanney" Michael Hanney
特此免费授予任何人许可 获取此软件和相关文档的副本 文件("Software"),无需处理软件 限制,包括但不限于使用权, 复制、修改、合并、发布、分发、再许可、and/or 出售 该软件的副本,并允许那些人 为此提供软件,但须满足以下条件 条件:
以上版权声明及本许可声明为 包含在软件的所有副本或重要部分中。
软件的提供 "AS IS",没有任何形式的保证, 明示或暗示的,包括但不限于保证 适销性,适用于特定用途和 非侵权。在任何情况下,作者或版权均不得 持有人应对任何索赔、损害或其他责任负责, 无论是在合同、侵权或其他方面的诉讼中, 来自、不属于或与软件有关或使用或 软件中的其他交易。