javascript Gulp.js工作流程

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了javascript Gulp.js工作流程相关的知识,希望对你有一定的参考价值。

# Getting started with Gulp.JS

## Preliminary Checklist

- Is the project initialized (with ```npm init```)?
  - If not, open a command line, navigate to the root of your current project, then run ```npm init```.
- Is ```gulp-cli``` installed/up to date?
  - Run ```npm i -g gulp-cli``` to install/update the package globally. This makes the ```gulp``` command available everywhere.

 

## Installing Gulp and Gulp Plugins

Using the command line in the root of your project, run 

```npm i -D gulp``` 

to install Gulp.js as a dev-dependency. Once Gulp has finished installing, run

```touch gulpfile.js```

to generate the configuration file Gulp will look for when you want to automate your tasks.

Gulp plugins are installed the same way as above, and multiple plugins/npm packages in general can be installed in the same command. For example:

```npm i -D gulp-sass gulp-clean-css browser-sync some-other-package...```

### Stylesheet Plugins

My go-to stylesheet plugins are:

```gulp-sass gulp-clean-css gulp-autoprefixer```

### JavaScript Plugins

My go-to javascript plugins are:

```gulp-concat gulp-uglify```

### Image Optimization Plugins

My go-to image optimization plugins are:

```gulp-imagemin imagemin-mozjpeg imagemin-pngquant imagemin-svgo```

### Utility plugins

My go-to utility plugins are:

```gulp-newer gulp-rename gulp-plumber gulp-sourcemaps browser-sync```

### All Together Now!

```npm i -D gulp gulp-sass gulp-clean-css gulp-autoprefixer gulp-concat gulp-uglify gulp-imagemin imagemin-mozjpeg imagemin-pngquant imagemin-svgo gulp-newer gulp-rename gulp-plumber gulp-sourcemaps browser-sync```

 

## Setting up gulpfile.js

Assign gulp and the plugins you'll be using to convenient variables.

```
var gulp = require('gulp'),

    // Style-related plugins
    sass         = require('gulp-sass'),
    cleancss     = require('gulp-clean-css'),
    autoprefixer = require('gulp-autoprefixer'),

    // JavaScript-related plugins
    concat       = require('gulp-concat'),
    uglify       = require('gulp-uglify'),

    // Image optimization plugins
    imagemin     = require('gulp-imagemin'),
    svgo         = require('imagemin-svgo'),
    mozjpeg      = require('imagemin-mozjpeg'),
    pngquant     = require('imagemin-pngquant'),

    // Utility plugins
    newer        = require('gulp-newer'),
    rename       = require('gulp-rename'),
    plumber      = require('gulp-plumber'),
    sourcemaps   = require('gulp-sourcemaps'),

    // Browsery Sync
    browsersync  = require('browser-sync'),
    reload       = browsersync.reload;
```

I like to group like-with-like, so I'll create a couple of variables for items I'll be reusing throughout my gulpfile.

```
var styles = {
    source: './source/scss/app.scss',
    destination: './source/css',
    productionDestination: './dist/css',
    sassOptions: {
        outputStyle: 'compact',
        precision: 10,
        sourceComments: true
    },
    prefixes: ['last 2 versions', 'ie >= 10'],
    cleancssOptions: {
        level: {
            2: {
                all: false,
                mergeMedia: true,
                restructureRules: true,
                removeDuplicateMediaBlocks: true
            }
        }
    }
};

var scripts = {
    vendor: {
        source: './source/js/vendor/**/*.js',
        filename: 'vendor'
    },
    custom: {
        source: './source/js/custom/main.js',
        filename: 'app'
    },
    destination: './dist/js'
};

var images = {
    source: './source/images/**/*',
    destination: './dist/img',
    imageminPlugins: [
        mozjpeg({
            quality: 85
        }),
        pngquant({
            speed: 1
        }),
        svgo()
    ],
    imageminOptions: {
        verbose: true
    }
};

var watchFiles = {
    html: '**/*.html',
    css: 'source/css/**/*.css',
    scss: 'source/scss/**/*.scss',
    jsVendor: 'source/js/vendor/**/*.js',
    jsCustom: 'source/js/custom/**/*.js',
    images: 'source/images/**/*'
};
```

### Setting up tasks

#### Browser Sync

```
gulp.task('browser-sync', function () {
  browsersync.init({
    proxy:         'http://your-development-domain.tld',
    open:          true,
    injectChanges: true
  });
});
// With this config, browsersync automatically opens a new window/tab in your default browser once it's ready to serve the page.
// Also, injectChanges allows resources that don't need a full page reload to be injected on the fly (ex: stylesheets)
```

#### Stylesheet-related tasks

```
gulp.task('styles', function () {
    gulp.src(styles.source)
        .pipe(plumber())
        .pipe(sourcemaps.init())
        .pipe(sass(styles.sassOptions))
        .pipe(autoprefixer(styles.prefixes))
        .pipe(gulp.dest(styles.destination))
        .pipe(rename({
            basename: 'styles',
            suffix: '.min'
        }))
        .pipe(cleancss(styles.cleancssOptions))
        .pipe(sourcemaps.write())
        .pipe(gulp.dest(styles.productionDestination))
        .pipe(plumber.stop())
        .pipe(browsersync.stream());
});
// gulp-plumber allows the .pipe stream to continue even in the event of a breaking error (I think? Don't quote me.)
// gulp-sourcemaps is initialized from the very beginning, and will keep track of all the changes that occur during sass compilation and css minification.
// This allows you to see exactly where in your sourcecode (even back into your scss files) a certain style rule is coming from. Helpful for debugging during development.
```

#### JavaScript-related tasks

```
gulp.task('jsVendor', function () {
    return gulp.src(scripts.vendor.source)
        .pipe(concat(scripts.vendor.filename + '.js'))
        .pipe(gulp.dest(scripts.destination))
        .pipe(rename({
            basename: scripts.vendor.filename,
            suffix: '.min'
        }))
        .pipe(uglify())
        .pipe(gulp.dest(scripts.destination));
});
gulp.task('watch-jsVendor', ['jsVendor'], function (done) {
    browsersync.reload();
    done();
});

gulp.task('jsCustom', function () {
    return gulp.src(scripts.custom.source)
        .pipe(sourcemaps.init())
        .pipe(concat(scripts.custom.filename + '.js'))
        .pipe(gulp.dest(scripts.destination))
        .pipe(rename({
            basename: scripts.custom.filename,
            suffix: '.min'
        }))
        .pipe(uglify())
        .pipe(sourcemaps.write())
        .pipe(gulp.dest(scripts.destination));
});
gulp.task('watch-jsCustom', ['jsCustom'], function (done) {
    browsersync.reload();
    done();
});
// I like to split the file-processing and watch tasks apart.
// Doing it this way means the file-processing task must be completely finished before browsersync reloads the page.
// I've generally had better results doing it this way. YMMV.
```

#### Image optimization

```
gulp.task('imageOptimization', function () {
    return gulp.src(images.source)
        .pipe(newer(images.destination))
        .pipe(imagemin(images.imageminPlugins, images.imageminOptions))
        .pipe(gulp.dest(images.destination))
});
gulp.task('watch-imageOptimization', ['imageOptimization'], function (done) {
    browsersync.reload();
    done();
});
// gulp-newer allows us to skip files that have already been optimized, making this task much more efficient.
```

##### Gulp default task

```
gulp.task('default', ['browser-sync', 'styles', 'jsCustom', 'jsVendor', 'imageOptimization'], function () {
    gulp.watch(watchFiles.html, browsersync.reload());
    gulp.watch(watchFiles.scss, ['styles']);
    gulp.watch(watchFiles.jsVendor, ['watch-jsVendor']);
    gulp.watch(watchFiles.jsCustom, ['watch-jsCustom']);
    gulp.watch(watchFiles.images, ['imageOptimization']);
});
// Before the default task can begin executing, all the tasks inside the array must finish.
```

 

## Finishing up

Open a command line window in the root of your project and run ```gulp``` to get started. Now, whenever you make changes to your stylesheets, gulp injects them into your page without having to refresh. As well, when you make changes to your JavaScript files, or add new vendor files, gulp will process them and reload your page. Gulp will optimize images as you drop them in, but it has not been configured to reload your page... yet.

If you have a few images already in your source folder by the time you run gulp for the first time, the default task could take a while to execute, as image optimization can potentially take a few seconds or more per image. However, because of the package ```gulp-newer```, any time you stop and start back up again, gulp will only optimize newer images, and will skip the images that have already been optimized.

Note the ```return``` statements before ```gulp.src()``` in some of the tasks above. As an example, when ```watch-imageOptimization``` calls ```imageOptimization``` (as a dependency), ```imageOptimization``` must fully complete before the function body of ```watch-imageOptimization``` will execute. That means we wait for the images to finish processing before reloading the browser. The more images you drag over/the larger the image, the longer it's going to take.

A complete gulpfile with all of what I've outlined here is also available. 

### Links to Documentation

- [gulp.js Home Page](https://gulpjs.com/)
  - [gulp.js Documentation](https://github.com/gulpjs/gulp/blob/master/docs/API.md)
- [gulp-sass](https://github.com/dlmanning/gulp-sass)
- [gulp-clean-css](https://github.com/scniro/gulp-clean-css)
- [gulp-autoprefixer](https://github.com/sindresorhus/gulp-autoprefixer)
- [gulp-concat](https://github.com/contra/gulp-concat)
- [gulp-uglify](https://github.com/terinjokes/gulp-uglify)
- [gulp-imagemin](https://github.com/sindresorhus/gulp-imagemin)
  - [imagemin-mozjpeg](https://github.com/imagemin/imagemin-mozjpeg)
  - [imagemin-pngquant](https://github.com/imagemin/imagemin-pngquant)
  - [imagemin-svgo](https://github.com/imagemin/imagemin-svgo)
- [gulp-newer](https://github.com/tschaub/gulp-newer)
- [gulp-rename](https://github.com/hparra/gulp-rename)
- [gulp-plumber](https://github.com/floatdrop/gulp-plumber)
- [gulp-sourcemaps](https://github.com/gulp-sourcemaps/gulp-sourcemaps)
- [browser-sync Home Page](https://www.browsersync.io/)
  - [browser-sync Documentation](https://www.browsersync.io/docs)
  - [browser-sync Gulp Integration](https://www.browsersync.io/docs/gulp)
var gulp = require('gulp'),

    // Style-related plugins
    sass = require('gulp-sass'),
    cleancss = require('gulp-clean-css'),
    autoprefixer = require('gulp-autoprefixer'),

    // JavaScript-related plugins
    concat = require('gulp-concat'),
    uglify = require('gulp-uglify'),

    // Image optimization plugins
    imagemin = require('gulp-imagemin'),
    svgo = require('imagemin-svgo'),
    mozjpeg = require('imagemin-mozjpeg'),
    pngquant = require('imagemin-pngquant'),

    // Utility plugins
    newer = require('gulp-newer'),
    rename = require('gulp-rename'),
    plumber = require('gulp-plumber'),
    sourcemaps = require('gulp-sourcemaps'),

    // Browsery Sync
    browsersync = require('browser-sync'),
    reload = browsersync.reload;

var styles = {
    source: './source/scss/app.scss',
    destination: './dist/css',
    sassOptions: {
        outputStyle: 'compact',
        precision: 10,
        sourceComments: true
    },
    prefixes: ['last 2 versions', 'ie >= 10'],
    cleancssOptions: {
        level: {
            2: {
                all: false,
                mergeMedia: true,
                restructureRules: true,
                removeDuplicateMediaBlocks: true
            }
        }
    }
};

var scripts = {
    vendor: {
        source: './source/js/vendor/**/*.js',
        filename: 'vendor'
    },
    custom: {
        source: './source/js/custom/main.js',
        filename: 'app'
    },
    destination: './dist/js'
};

var images = {
    source: './source/images/**/*',
    destination: './dist/img',
    imageminPlugins: [
        mozjpeg({
            quality: 85
        }),
        pngquant({
            speed: 1
        }),
        svgo()
    ],
    imageminOptions: {
        verbose: true
    }
};

var watchFiles = {
    html: '**/*.html',
    css: 'source/css/**/*.css',
    scss: 'source/scss/**/*.scss',
    jsVendor: 'source/js/vendor/**/*.js',
    jsCustom: 'source/js/custom/**/*.js',
    images: 'source/images/**/*'
};

// Browser Sync task
gulp.task('browser-sync', function () {
    browsersync.init({
        proxy: 'http://dev.bmacd.me',
        open: true,
        injectChanges: true
    });
});

// Styles-related tasks
gulp.task('styles', function () {
    gulp.src(styles.source)
        .pipe(plumber())
        .pipe(sourcemaps.init())
        .pipe(sass(styles.sassOptions))
        .pipe(autoprefixer(styles.prefixes))
        .pipe(gulp.dest(styles.destination))
        .pipe(rename({
            basename: 'styles',
            suffix: '.min'
        }))
        .pipe(cleancss(styles.cleancssOptions))
        .pipe(sourcemaps.write())
        .pipe(gulp.dest(styles.destination))
        .pipe(plumber.stop())
        .pipe(browsersync.stream());
});

// JavaScript-related tasks
gulp.task('jsVendor', function () {
    return gulp.src(scripts.vendor.source)
        .pipe(concat(scripts.vendor.filename + '.js'))
        .pipe(gulp.dest(scripts.destination))
        .pipe(rename({
            basename: scripts.vendor.filename,
            suffix: '.min'
        }))
        .pipe(uglify())
        .pipe(gulp.dest(scripts.destination));
});
gulp.task('jsCustom', function () {
    return gulp.src(scripts.custom.source)
        .pipe(sourcemaps.init())
        .pipe(concat(scripts.custom.filename + '.js'))
        .pipe(gulp.dest(scripts.destination))
        .pipe(rename({
            basename: scripts.custom.filename,
            suffix: '.min'
        }))
        .pipe(uglify())
        .pipe(sourcemaps.write())
        .pipe(gulp.dest(scripts.destination));
});
gulp.task('watch-jsVendor', ['jsVendor'], function (done) {
    browsersync.reload();
    done();
});
gulp.task('watch-jsCustom', ['jsCustom'], function (done) {
    browsersync.reload();
    done();
});

// Image optimization
gulp.task('imageOptimization', function () {
    return gulp.src(images.source)
        .pipe(newer(images.destination))
        .pipe(imagemin(images.imageminPlugins, images.imageminOptions))
        .pipe(gulp.dest(images.destination));
});
gulp.task('watch-imageOptimization', ['imageOptimization'], function (done) {
    browsersync.reload();
    done();
});

// Default task
gulp.task('default', ['browser-sync', 'styles', 'jsCustom', 'jsVendor', 'imageOptimization'], function () {
    gulp.watch(watchFiles.html, browsersync.reload());
    gulp.watch(watchFiles.scss, ['styles']);
    gulp.watch(watchFiles.jsVendor, ['watch-jsVendor']);
    gulp.watch(watchFiles.jsCustom, ['watch-jsCustom']);
    gulp.watch(watchFiles.images, ['watch-imageOptimization']);
});

以上是关于javascript Gulp.js工作流程的主要内容,如果未能解决你的问题,请参考以下文章

使用 Gulp.js 将版本化和构建(缩小)文件正确提交到 GitHub

Gulp基础教程

01. 人生苦短 gulp.js的简介与安装

gulp能做什么,前端装逼为何要用它

一个简单的gulp工作流项目

暑假60天打卡之07.29今日份(gulp.js )