增量吞咽少构建 [英] Incremental gulp less build

查看:139
本文介绍了增量吞咽少构建的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的办公室,我们正在使用gulp来建立我们较少的文件。我想改善构建任务,因为它花了一秒钟的时间来构建我们最近开发的一个大型项目。这个想法是缓存文件,只通过改变的文件。所以我开始使用谷歌,并发现增量构建的JavaScript昂认为这将是很容易重写他们少。这是我开始的那个: https://github.com /gulpjs/gulp/blob/master/docs/recipes/incremental-builds-with-concatenate.md

In my office we are using gulp to build our less files. I wanted to improve the build task as it took over a second to build on a large project we recently worked on. The idea was to cache the files and only pass the one that changed. So I started with google and found incremental builds for javascript ang thought it would be easy to rewrite them for less. Here's the one I started with: https://github.com/gulpjs/gulp/blob/master/docs/recipes/incremental-builds-with-concatenate.md

经过几次不成功的尝试,我最终以以下代码(使用最新的引导程序分发进行测试):

After a few unsuccessful tries I ended up with following code (tested with the latest bootstrap distribution):

var gulp            = require('gulp');
var less            = require('gulp-less');
var concat          = require('gulp-concat');
var remember        = require('gulp-remember');
var cached          = require('gulp-cached');

var fileGlob = [
    './bootstrap/**/*.less',
    '!./bootstrap/bootstrap.less',
    '!./bootstrap/mixins.less'
];

gulp.task('less', function () {
    return gulp.src(fileGlob)
        .pipe(cached('lessFiles'))
        .pipe(remember('lessFiles'))
        .pipe(less())
        .pipe(gulp.dest('output'));
});

gulp.task('watch', function () {
    var watcher = gulp.watch(fileGlob, ['less']);
    watcher.on('change', function (e) {
        if (e.type === 'deleted') {
            delete cached.caches.scripts[e.path];
            remember.forget('lessFiles', e.path);
        }
    });
});

但是,这只会传递已更改的文件,而由于缺少变量定义,编译器会失败。如果我在较少的任务之前使用concat插件,gulp会陷入一个(看似)无止境的循环。

But this passes only the changed file and the less compiler fails because of the variable definitions missing. If I pipe the concat plugin before the less task, gulp gets stuck in a (seemingly) endless loop.

gulp.task('less', function () {
    return gulp.src(fileGlob)
        .pipe(cached('lessFiles'))
        .pipe(remember('lessFiles'))
        .pipe(concat('main.less')
        .pipe(less())
        .pipe(gulp.dest('output'));
});

有没有人使用这些插件的经验,或者设法以另一种方式创建增量减少的构建。 )用于测试的github存储库: https://github.com/tuelsch/perfect-less-build

Has anyone experience with those plugins or managed to create an incremental less build in an other way. Here is a (messy) github repository for testing: https://github.com/tuelsch/perfect-less-build

PS:我打算在后面添加linting,sourcemaps,minification,evtl. cache busting和autoprefixer。

PS: I'm planning on adding linting, sourcemaps, minification, evtl. cache busting and autoprefixer later on.

推荐答案

像Ashwell一样,我发现使用import可以确保所有LESS文件都可以访问变量d mixins他们需要我也使用LESS文件与进口捆绑目的。这有几个优点:$ b​​
$ b

Like Ashwell, I've found it useful to use imports to ensure that all my LESS files have access to the variables and mixins that they need. I also use a LESS file with imports for bundling purposes. This has a few advantages:


  1. 我可以利用LESS的特性来完成复杂的事情,比如重写变量值来产生多个主题,或者预先设置一个类到另一个LESS文件中的每个规则。
  2. 不需要concat插件。
  3. Web Essentials for Visual Studio等工具可以提供语法帮助和输出预览,因为每个LESS文件都完全能够自行渲染。

如果要导入变量,mixins等,但您不希望输出其他文件的全部内容,您可以使用:

Where you want to import variables, mixins, etc, but you don't want to actually output the entire contents of another file, you can use:

@import (reference) "_colors.less";

经过几天的努力,我终于得到了一个增量构建,可以正确地重建所有依赖于我更改的LESS文件的对象。我将结果记录在此处。这是最终的gulpfile:

After a few days of effort, I was finally able to get an incremental build that correctly rebuilds all the objects that depend on the LESS file I changed. I documented the results here. This is the final gulpfile:

/*
 * This file defines how our static resources get built.
 * From the StaticCommon root folder, call "gulp" to compile all generated
 * client-side resources, or call "gulp watch" to keep checking source 
 * files, and rebuild them whenever they are changed. Call "gulp live" to 
 * do both (build and watch).
 */

/* Dependency definitions: in order to avoid forcing everyone to have 
 * node/npm installed on their systems, we are including all of the 
 * necessary dependencies in the node_modules folder. To install new ones,
 * you must install nodejs on your machine, and use the "npm install XXX" 
 * command. */
var gulp = require('gulp');
var less = require('gulp-less');
var LessPluginCleanCss = require('less-plugin-clean-css'),
    cleanCss = new LessPluginCleanCss();
var sourcemaps = require('gulp-sourcemaps');
var rename = require('gulp-rename');
var cache = require('gulp-cached');
var progeny = require('gulp-progeny');
var filter = require('gulp-filter');
var plumber = require('gulp-plumber');
var debug = require('gulp-debug');

gulp.task('less', function() {
    return gulp
        // Even though some of our LESS files are just references, and 
        // aren't built, we need to start by looking at all of them because 
        // if any of them change, we may need to rebuild other less files.
        .src(
        ['Content/@(Theme|Areas|Css)/**/*.less'],
        { base: 'Content' })
        // This makes it so that errors are output to the console rather 
        // than silently crashing the app.
        .pipe(plumber({
            errorHandler: function (err) {
                console.log(err);
                // And this makes it so "watch" can continue after an error.
                this.emit('end');
            }
        }))
        // When running in "watch" mode, the contents of these files will 
        // be kept in an in-memory cache, and after the initial hit, we'll
        // only rebuild when file contents change.
        .pipe(cache('less'))
        // This will build a dependency tree based on any @import 
        // statements found by the given REGEX. If you change one file,
        // we'll rebuild any other files that reference it.
        .pipe(progeny({
            regexp: /^\s*@import\s*(?:\(\w+\)\s*)?['"]([^'"]+)['"]/
        }))
        // Now that we've set up the dependency tree, we can filter out 
        // any files whose
        // file names start with an underscore (_)
        .pipe(filter(['**/*.less', '!**/_*.less']))
        // This will output the name of each LESS file that we're about 
        // to rebuild.
        .pipe(debug({ title: 'LESS' }))
        // This starts capturing the line-numbers as we transform these 
        // files, allowing us to output a source map for each LESS file 
        // in the final stages.
        // Browsers like Chrome can pick up those source maps and show you 
        // the actual LESS source line that a given rule came from, 
        // despite the source file's being transformed and minified.
        .pipe(sourcemaps.init())
        // Run the transformation from LESS to CSS
        .pipe(less({
            // Minify the CSS to get rid of extra space and most CSS
            // comments.
            plugins: [cleanCss]
        }))
        // We need a reliable way to indicate that the file was built
        // with gulp, so we can ignore it in Mercurial commits.
        // Lots of css libraries get distributed as .min.css files, so
        // we don't want to exclude that pattern. Let's try .opt.css 
        // instead.
        .pipe(rename(function(path) {
            path.extname = ".opt.css";
        }))
        // Now that we've captured all of our sourcemap mappings, add
        // the source map comment at the bottom of each minified CSS 
        // file, and output the *.css.map file to the same folder as 
        // the original file.
        .pipe(sourcemaps.write('.'))
        // Write all these generated files back to the Content folder.
        .pipe(gulp.dest('Content'));
});

// Keep an eye on any LESS files, and if they change then invoke the 
// 'less' task.
gulp.task('watch', function() {
    return gulp.watch('Content/@(Theme|Areas|Css)/**/*.less', ['less']);
});

// Build things first, then keep a watch on any changed files.
gulp.task('live', ['less', 'watch']);

// This is the task that's run when you run "gulp" without any arguments.
gulp.task('default', ['less']);

现在我们可以简单地运行 gulp live 来建立我们所有的LESS文件一次,然后允许每个后续更改只建立那些依赖于更改文件的文件。

We can now simply run gulp live to build all our LESS files once, and then allow each subsequent change to just build those files that depend on the changed files.

这篇关于增量吞咽少构建的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆