我是靠谱客的博主 稳重纸鹤,这篇文章主要介绍自动化构建工具Grunt、Gulp,现在分享给大家,希望可以做个参考。

使用grunt完成项目的自动化构建

一、准备工作

grunt快要退出历史舞台了,简单学习下

复制代码
1
2
3
4
5
mkdir my-grunt yarn init --yes //创建package模块 yarn add grunt //安装grunt模块

二、创建gruntfile.js文件

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//Grunt的入口文件 //用于定义一些需要Grunt自动执行的任务 //需要导出一个函数,接收一个grunt的参数 // 运行 yarn grunt foo module.exports = grunt => { grunt.registerTask('foo',() => { console.log("hello grunt") }) } //可以在第二个参数添加描述信息,会作为当前任务的描述信息存在 grunt.registerTask('bar',"任务描述",() => { console.log("hello grunt") }) //如果任务名称为default,则会作为默认任务存在,yarn grunt即可执行 grunt.registerTask('default',"任务描述",() => { console.log("hello default grunt") }) //也可通过数组进行任务组合,会依次执行数组中的任务,串联操作 grunt.registerTask("default",["foo","bar"])

注意:grunt默认执行同步任务,所以如果是异步任务,则需要通过this.async进行

复制代码
1
2
3
4
5
6
7
8
9
grunt.registerTask("async-task",function(){ const done = this.async() setTimeout(()=>{ console.log("async...") done() },1000) })

测试运行

复制代码
1
2
3
4
5
6
yarn grunt foo yarn grunt bar yarn grunt default yarn grunt async-task

三、grunt标记任务失败

可以通过在任务体中直接return false实现

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//grunt标记任务失败 grunt.registerTask('bad', "任务描述", () => { console.log("bad") return false }) //异步标记失败 grunt.registerTask("bad-async",function(){ const done = this.async() setTimeout(()=>{ console.log("bad-async") done(false) },1000) })

如果是串行的任务,如果有一个出现问题,则后续任务不会被执行,但是可以指定参数--force强制执行

复制代码
1
2
3
4
5
grunt.registerTask("testBad",["foo","bad","bar"]) //执行 yarn grunt testBad --force

四、grunt配置方法

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
module.exports = grunt => { grunt.initConfig({ // foo:'bar', foo:{ bar:123 } }) grunt.registerTask('foo', () => { // grunt.config 可以取出配置中foo对应的值 console.log(grunt.config('foo')) //属性值 console.log(grunt.config('foo.bar')) //对象值 }) }

五、grunt多目标任务

多目标任务需要使用registerMultiTask进行任务的注册,必须要为对应的多目标任务在initConfig中添加target,如下

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//grunt多目标任务 module.exports = grunt => { grunt.initConfig({ build: { //options作为任务的配置选项 options:{ foo:"bar" }, css: { options:{ foo:"baz" //会覆盖任务中的options } }, js: "2" } }) grunt.registerMultiTask('build', function () { console.log(this.options()) console.log(`target:${this.target},data:${this.data}`) }) }

六、Grunt插件的使用

流程:安装插件载入插件根据插件文档完成相关选项

复制代码
1
2
3
yarn add grunt-contrib-clean //安裝插件 自动清除临时文件

使用方法,使用loadNpmTasks载入插件

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/** * yarn add grunt-contrib-clean * 自动清除临时文件 */ module.exports = grunt => { grunt.initConfig({ clean: { // temp: 'temp/app.js' // temp: 'temp/*.txt' temp: 'temp/**' } }) grunt.loadNpmTasks('grunt-contrib-clean') }

yarn grunt clean

七、grunt常用插件

  • babel:将es6语法新特性进行转化
  • sass:将sass转化为可识别的css
  • html:将文件模板输出到指定目录
  • watch:监视变化,热更新
  • clean:清除指定文件夹的文件

sass

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//安装依赖 yarn add grunt-sass sass -dev //引入插件 const sass = require("sass") //使用 module.exports = grunt => { grunt.initConfig({ //sass转化为css功能 sass: { options: { sourceMap: true, implementation: sass }, main: { files: { 'dist/css/main.css': 'src/scss/main.scss' } } } }) } grunt.loadNpmTasks('grunt-sass')

yarn grunt sass

babel
gruntfile中使用loadGruntTasks载入所有安装的插件,最后完成相关的配置选项。

复制代码
1
2
3
4
5
6
7
//安裝 yarn add load-grunt-tasks --dev //使用 const loadGruntTasks = require("load-grunt-tasks") //自动加载所有的grunt插件 loadGruntTasks(grunt)
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
const sass = require('sass') const loadGruntTasks = require('load-grunt-tasks') module.exports = grunt => { grunt.initConfig({ sass: { options: { sourceMap: true, implementation: sass }, main: { files: { 'dist/css/main.css': 'src/scss/main.scss' } } }, babel: { options: { sourceMap: true, presets: ['@babel/preset-env'] }, main: { files: { 'dist/js/app.js': 'src/js/app.js' } } }, watch: { //监听文件 自动打包 js: { files: ['src/js/*.js'], tasks: ['babel'] }, css: { files: ['src/scss/*.scss'], tasks: ['sass'] } } }) // grunt.loadNpmTasks('grunt-sass') loadGruntTasks(grunt) // 自动加载所有的 grunt 插件中的任务 grunt.registerTask('default', ['sass', 'babel', 'watch']) }

八、Gulp的基本使用

https://www.cnblogs.com/xqbiii/p/8406978.html

复制代码
1
2
3
4
yarn init --yes yarn add gulp --dev
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
exports.foo = (done) => { console.log('任务foo') done() // 标识任务执行完成 } //yarn gulp foo // default 是默认任务 // 在运行是可以省略任务名参数 exports.default = done => { console.log('default task working~') done() } // yarn gulp // v4.0 之前需要通过 gulp.task() 方法注册任务 // 这种方式已经不被推荐了 const gulp = require('gulp') gulp.task('bar', done => { console.log('bar task working~') done() })

九、Gulp的组合任务

const { series, parallel } = require('gulp')

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
const { series, parallel } = require('gulp') const task1 = done => { setTimeout(() => { console.log('task1 working~') done() }, 1000) } const task2 = done => { setTimeout(() => { console.log('task2 working~') done() }, 1000) } const task3 = done => { setTimeout(() => { console.log('task3 working~') done() }, 1000) } // 让多个任务按照顺序依次执行 exports.foo = series(task1, task2, task3) // 让多个任务同时执行 exports.bar = parallel(task1, task2, task3)

十、Gulp的异步任务

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
const fs = require('fs') // 一回调 exports.callback = done => { console.log('callback task') done() } exports.callback_error = done => { console.log('回调报错处理') done(new Error('task failed')) } //二 通过promise,这里也是支持promise的,resolve不需要返回值,就算返回也会被忽略,直接resolve() exports.promise = done => { console.log('promise') return Promise.resolve() } exports.promise_error = () => { console.log('promise_error') return Promise.reject(new Error('promise failed')) } // 三async await const timeOut = (time) => { return new Promise(resolve => { setTimeout(resolve(), time); }) } exports.async = async () => { await timeOut(1000) console.log('1秒后打印') } // stream exports.stream = () => { const read = fs.createReadStream('yarn.lock') const write = fs.createWriteStream('a.txt') read.pipe(write) return read }

十一、Gulp构建过程核心工作原理

在这里插入图片描述
eg:这里用node自带的读取流写入流

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
const fs = require('fs') const { Transform } = require('stream') exports.default = () => { // 文件读取流 const readStream = fs.createReadStream('normalize.css') // 文件写入流 const writeStream = fs.createWriteStream('normalize.min.css') // 文件转换流 const transformStream = new Transform({ // 核心转换过程 transform: (chunk, encoding, callback) => { const input = chunk.toString() const output = input.replace(/s+/g, '').replace(//*.+?*//g, '') callback(null, output) } }) return readStream .pipe(transformStream) // 转换 .pipe(writeStream) // 写入 }

十二、文件操作API

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
const { src, dest } = require('gulp') const cleanCSS = require('gulp-clean-css')//转换流插件压缩css const rename = require('gulp-rename')//重命名后缀 exports.default = () => { return src('src/*.css') .pipe(cleanCSS()) .pipe(rename({ extname: '.min.css' })) .pipe(dest('dist')) }

十三、Gulp案例-样式编译

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
const { src, dest } = require('gulp') const cleanCSS = require('gulp-clean-css')//转换流插件压缩css const rename = require('gulp-rename')//重命名后缀 exports.default = () => { return src('src/*.css') .pipe(cleanCSS()) .pipe(rename({ extname: '.min.css' })) .pipe(dest('dist')) }

十四、脚本编译

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
const { src, dest } = require('gulp') const babel = require('gulp-babel') const script = () => { return src('src/assets/scripts/*.js', { base: 'src' }) .pipe(plugins.babel({ presets: ['@babel/preset-env'] })) .pipe(dest('temp')) .pipe(bs.reload({ stream: true })) } module.exports = { script }

十五、页面模板编译

复制代码
1
2
3
4
<div class="row"> {% for item in [1, 2, 3, 4, 5, 6] %} </div>

以上面模板为例

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
const data = { menus: [ { name: 'Home', icon: 'aperture', link: 'index.html' }, { name: 'Features', link: 'features.html' }, { name: 'About', link: 'about.html' }, { name: 'Contact', link: '#', children: [ { name: 'Twitter', link: 'https://twitter.com/w_zce' }, { name: 'About', link: 'https://weibo.com/zceme' }, { name: 'divider' }, { name: 'About', link: 'https://github.com/zce' } ] } ], pkg: require('./package.json'), date: new Date() } const { src, dest } = require('gulp') const swig = require('gulp-swig') // 编译模板 const page = () => { return src('src/*.html', { base: 'src' }) .pipe(plugins.swig({ data})) .pipe(dest('dist')) } module.exports = { page }

十六、图片和文字字体转换

安装依赖

复制代码
1
2
yarn add gulp-imagemin --dev
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
const imagemin = require('gulp-imagemin') const image = () => { return src("src/assets/images/**",{base:'src'}).pipe(imagemin()).pipe(dest('dist')) } const fonts = () => { return src("src/assets/fonts/**",{base:'src'}).pipe(imagemin()).pipe(dest('dist')) } module.exports = { image,fonts }

十七、其他文件及文件清除

复制代码
1
2
npm i del -D // 不是gulp插件
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
const { src, dest, parallel, series, watch } = require('gulp') const del = require('del') const clean = () => { return del(['dist', 'temp']) } const compile = parallel(style,script,page,image,font) const build = series(clean,parallel(compile,extra)) module.exports = { compile, build }

十八、自动加载插件

复制代码
1
2
yarn add gulp-load-plugins --dev

不用每次都去引入插件,可以使用plugins自动引入插件

复制代码
1
2
3
4
5
6
const loadPlugins = require('gulp-load-plugins') const plugin = new loadPlugins() const page = () => { return src("src/*.html",{base:'src'}).pipe(plugin.swig({data})).pipe(dest('dist')) }

十九、开发服务器

安装依赖

复制代码
1
2
3
yarn add browser-sync --dev yarn add bootstrap@4.0.0-alpha.6 --dev

任务创建

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const browserSync = require('browser-sync') const bs = browserSync.create() const serve = () => { bs.init({ server: { baseDir: 'dist', files: 'dist/**', routes: { //处理静态文件,进行路由映射 '/node_modules': "node_modules" } } }) } module.exports = { compile, image, fonts, extra, serve }
复制代码
1
2
yarn gulp serve

二十、监视变化以及构建优化

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
const { dest, src,series,parallel,watch } = require('gulp') const serve = () => { watch("src/assets/styles/*.scss",style) // 后面是任务 watch("src/assets/scripts/*.js",script) watch("src/*.html",page) watch("src/assets/images/**",image) watch("src/assets/fonts/**",fonts) watch("public/**",extra) bs.init({ server: { baseDir: 'dist', files:'dist/**', //监听的是哪个文件 // open:false, routes: { '/node_modules': "node_modules" } } }) }

可以简化

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
const serve = () => { watch('src/assets/styles/*.scss', style) watch('src/assets/scripts/*.js', script) watch('src/*.html', page) // watch('src/assets/images/**', image) // watch('src/assets/fonts/**', font) // watch('public/**', extra) watch([ 'src/assets/images/**', 'src/assets/fonts/**', 'public/**' ], bs.reload)

font与image以及额外的文件,热更没有太大的必要,因为图片压缩是无损压缩,太多的监视会一定程度上消耗性能,所以一般不对其就行监视,修改

复制代码
1
2
3
4
5
6
7
watch("src/assets/styles/*.scss",style) watch("src/assets/scripts/*.js",script) watch("src/*.html",page) //修改basedir baseDir:["dist","public","src"]

二十一、useref文件引用处理

在这里插入图片描述
打包之后部署线上找不到引入文件,用useref插件,注意注释,都是有规律的

复制代码
1
2
3
4
5
6
7
const userref = () => { return src('dist/*.html',{base: 'dist'}) .pipe(plugins.useref({ searchPath: ['dist', '.'] })) .pipe(dest('dist')) }

二十二、文件压缩

npm i gulp-htmlmin gulp-uglify gulp-clean-css -D
gulp-uglify压缩js
npm i gulp-if -D

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const useref = () => { return src('temp/*.html', { base: 'temp' }) .pipe(plugins.useref({ searchPath: ['temp', '.'] })) // html js css .pipe(plugins.if(/.js$/, plugins.uglify())) .pipe(plugins.if(/.css$/, plugins.cleanCss())) .pipe(plugins.if(/.html$/, plugins.htmlmin({ collapseWhitespace: true, minifyCSS: true, minifyJS: true }))) .pipe(dest('dist')) }

二十三、处理文件重命名添加hash编码

gulp-revgulp-rev-collector

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// 压缩html gulp.task('html', async function () { const options = { removeComments: true, //清除HTML注释 collapseWhitespace: true, //压缩HTML collapseBooleanAttributes: true, //省略布尔属性的值 <input checked="true"/> ==> <input checked /> removeEmptyAttributes: true, //删除所有空格作属性值 <input id="" /> ==> <input /> removeScriptTypeAttributes: true, //删除<script>的type="text/javascript" removeStyleLinkTypeAttributes: true, //删除<style>和<link>的type="text/css" minifyJS: true, //压缩页面JS minifyCSS: true, //压缩页面CSS } await gulp .src(['./rev/*/*.json', './*.html']) //要压缩的html文件 .pipe(revCollector()) // 做路径替换 .pipe(htmlmin(options)) .pipe(gulp.dest('./share-page')) .pipe(browserSync.reload({ stream: true })) // 服务重载 html }) // 压缩css gulp.task('css', function () { return gulp.src('./css/*.css') //要压缩的css文件 .pipe(rev()) //给文件添加hash编码 .pipe(minifyCss()) .pipe(gulp.dest('./share-page/css')) .pipe(rev.manifest()) //生成rev-mainfest.json文件作为文件名字映射记录 .pipe(gulp.dest('rev/css/')) .pipe(browserSync.reload({ stream: true })) // 服务重载 css })

生成的rev-manifest.json文件,作用是做文件名字映射。方便打包是html做路径替换
在这里插入图片描述
最后效果
在这里插入图片描述
在这里插入图片描述

二十四、补充

复制代码
1
2
3
4
5
6
"scripts": { "clean": "gulp clean", "build": "gulp build", "develop": "gulp develop" }

yarn clean

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
const { src, dest, parallel, series, watch } = require('gulp') const del = require('del') const browserSync = require('browser-sync') const loadPlugins = require('gulp-load-plugins') const plugins = loadPlugins() const bs = browserSync.create() const data = { // 模板里的数据 menus: [ { name: 'Home', icon: 'aperture', link: 'index.html' }, { name: 'Features', link: 'features.html' }, { name: 'About', link: 'about.html' }, { name: 'Contact', link: '#', children: [ { name: 'Twitter', link: 'https://twitter.com/w_zce' }, { name: 'About', link: 'https://weibo.com/zceme' }, { name: 'divider' }, { name: 'About', link: 'https://github.com/zce' } ] } ], pkg: require('./package.json'), date: new Date() } const clean = () => { return del(['dist', 'temp']) } const style = () => { return src('src/assets/styles/*.scss', { base: 'src' }) .pipe(plugins.sass({ outputStyle: 'expanded' })) .pipe(dest('temp')) .pipe(bs.reload({ stream: true })) } const script = () => { return src('src/assets/scripts/*.js', { base: 'src' }) .pipe(plugins.babel({ presets: ['@babel/preset-env'] })) .pipe(dest('temp')) .pipe(bs.reload({ stream: true })) } const page = () => { return src('src/*.html', { base: 'src' }) .pipe(plugins.swig({ data, defaults: { cache: false } })) // 防止模板缓存导致页面不能及时更新 .pipe(dest('temp')) .pipe(bs.reload({ stream: true })) } const image = () => { return src('src/assets/images/**', { base: 'src' }) .pipe(plugins.imagemin()) .pipe(dest('dist')) } const font = () => { return src('src/assets/fonts/**', { base: 'src' }) .pipe(plugins.imagemin()) .pipe(dest('dist')) } const extra = () => { return src('public/**', { base: 'public' }) .pipe(dest('dist')) } const serve = () => { watch('src/assets/styles/*.scss', style) watch('src/assets/scripts/*.js', script) watch('src/*.html', page) // watch('src/assets/images/**', image) // watch('src/assets/fonts/**', font) // watch('public/**', extra) watch([ 'src/assets/images/**', 'src/assets/fonts/**', 'public/**' ], bs.reload) bs.init({ notify: false, port: 2080, // open: false, // files: 'dist/**', server: { baseDir: ['temp', 'src', 'public'], routes: { '/node_modules': 'node_modules' } } }) } const useref = () => { return src('temp/*.html', { base: 'temp' }) .pipe(plugins.useref({ searchPath: ['temp', '.'] })) // html js css .pipe(plugins.if(/.js$/, plugins.uglify())) .pipe(plugins.if(/.css$/, plugins.cleanCss())) .pipe(plugins.if(/.html$/, plugins.htmlmin({ collapseWhitespace: true, minifyCSS: true, minifyJS: true }))) .pipe(dest('dist')) } const compile = parallel(style, script, page) // 上线之前执行的任务 const build = series( clean, parallel( series(compile, useref), image, font, extra ) ) const develop = series(compile, serve) module.exports = { clean, build, develop }

二十五、gulp项目实战

本人做了一个gulp的简单打包示例:
目录结构:
static里面放的是不需要打包的资源
在这里插入图片描述
package.json

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
{ "name": "share-page-dev-glup", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "build": "gulp build", "server": "gulp server" }, "repository": { "type": "git", "url": "https://codeup.aliyun.com/619eeba89cbfc1b4f046737c/share-page.git" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "browser-sync": "^2.29.1", "del": "^6.0.0", "gulp": "^4.0.2", "gulp-htmlmin": "^5.0.1", "gulp-imagemin": "^6.0.0", "gulp-minify-css": "^1.2.4", "gulp-nodemon": "^2.5.0", "gulp-rev": "^9.0.0", "gulp-rev-collector": "^1.3.3", "gulp-uglify": "^3.0.2" } }

gulpfile.js

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
const gulp = require('gulp'); const del = require('del'); const htmlmin = require('gulp-htmlmin'); const minifyCss = require('gulp-minify-css'); const rev = require('gulp-rev'); const revCollector = require('gulp-rev-collector'); const uglify = require('gulp-uglify'); const imagemin = require('gulp-imagemin'); const browserSync = require('browser-sync').create(); const nodemon = require('gulp-nodemon'); // 压缩html gulp.task('html', async function () { const options = { removeComments: true, //清除HTML注释 collapseWhitespace: true, //压缩HTML collapseBooleanAttributes: true, //省略布尔属性的值 <input checked="true"/> ==> <input checked /> removeEmptyAttributes: true, //删除所有空格作属性值 <input id="" /> ==> <input /> removeScriptTypeAttributes: true, //删除<script>的type="text/javascript" removeStyleLinkTypeAttributes: true, //删除<style>和<link>的type="text/css" minifyJS: true, //压缩页面JS minifyCSS: true, //压缩页面CSS } await gulp .src(['./rev/*/*.json', './*.html']) //要压缩的html文件 .pipe(revCollector()) .pipe(htmlmin(options)) .pipe(gulp.dest('./share-page')) .pipe(browserSync.reload({ stream: true })) // 服务重载 html }) // 压缩css gulp.task('css', function () { return gulp.src('./css/*.css') //要压缩的css文件 .pipe(rev()) //给文件添加hash编码 .pipe(minifyCss()) .pipe(gulp.dest('./share-page/css')) .pipe(rev.manifest()) //生成rev-mainfest.json文件作为记录 .pipe(gulp.dest('rev/css/')) .pipe(browserSync.reload({ stream: true })) // 服务重载 css }) // 压缩js gulp.task('js', async function () { await gulp .src('./js/*.js') .pipe(rev()) //给文件添加hash编码 .pipe(uglify()) .pipe(gulp.dest('./share-page/js')) .pipe(rev.manifest()) //生成rev-mainfest.json文件作为记录 .pipe(gulp.dest('rev/js/')) .pipe(browserSync.reload({ stream: true })) // 服务重载 js }) gulp.task('imagemin', () => { return gulp.src('image/**/*') .pipe(imagemin()) .pipe(gulp.dest('share-page/image/')) }) gulp.task('copy', function () { return gulp.src('static/**/*') .pipe(gulp.dest('share-page/static')) }); gulp.task('clean', function () { return del(['share-page']) }) // 热更新 const update = gulp.parallel('css', 'html', 'js') // 打包 const build = gulp.series('clean', gulp.parallel('copy', 'css', 'js', 'imagemin'), 'html') gulp.task('build', build, function () { }) gulp.task('server', async function () { browserSync.init( { port: 8080, open: true, startPath: "./index.html", server: { baseDir: ['./'] } }, function () { console.log('browser refreshed.') } ) await build() // nodemon({ // script: 'cluster.js', // // 忽略部分对程序运行无影响的文件的改动,nodemon只监视js文件,可用ext项来扩展别的文件类型 // ignore: ['*'], // env: { // NODE_ENV: 'development', // }, // }).on('start', async function () { await gulp .watch(['./*.html', './js/', './css/']) .on('change', async function () { await update() browserSync.reload() }) // }) })

二十六、webpack和gulp有哪些区别

想必面试会经常被问到这个问题,本人做了一些总结 仅供参考:

面试,我觉得应该先把重点的工作原理说出来,gulp 其实是配置的任务流,一个一个执行,让它怎么执行,就怎么执行,webpack 是全是模块,给个入口,剩下的全交给它处理

  1. 工作原理不同:
  • webpack:
    • 首先通过入口文件(entry)找到项目中所有的模块(module)。
      将这些模块进行静态分析和处理,最终打包成一个或多个bundle文件。
    • 在打包的过程中,webpack会根据依赖关系进行代码拆分,将公共代码抽离成独立的chunk,使得代码的加载变得更加高效。
    • webpack还可以通过loader来转换非JavaScript文件,并且可以使用各种插件进行自定义构建流程和优化。
  • gulp:
    • gulp通过定义不同的任务(task)来执行各种构建操作。
    • 通过gulp.src获取需要进行处理的文件流,再通过一系列插件进行处理,最后通过gulp.dest输出到指定的位置。
    • gulp的插件可以进行多个操作,比如压缩、合并、重命名等,同时也可以定制自己的插件并加以使用。
  1. HMR是Webpack的一个功能,即热模块替换,它可以在不刷新浏览器的情况下更新模块。和热更新不同,HMR只会更新其中一个模块,而不是整个页面。这种机制是针对模块化开发而设计的。Gulp并没有自带的HMR功能,但可以使用一些插件或工具来实现类似的效果。例如,使用gulp-connect、browser-sync和lite-server等插件,可以实现自动刷新浏览器,节省手动刷新时间。但是,它们并没有模块热替换的功能。如果需要使用模块热替换,还是需要结合webpack等打包工具来实现。
  2. webpack可以很容易地做tree-shaking,gulp不行
  3. 但是gulp解决不了模块化js文件的问题,于是使用ts或者配置sea.jsrequire.js的插件用来解决js模块化,而webpack本身就是模块化为核心。。
  4. gulp在单页面应用方面输出乏力,而且对流行的单页技术有些难以处理(比如 Vue 单文件组件,使用 gulp 处理就会很困难,而 webpack 一个 loader 就能轻松搞定)
  5. 使用方式上不同,webpack里面有大量的loaderplugin用来处理和打包资源文件,gulp有大量的插件,根据定义不同的task任务去处理和打包资源
  6. gulp更易于学习,易于使用,webpack相对学习难度更难一些
  7. 这里没有明确的好坏界限,只是看你的项目使用场景而做选择,也不乏有很多大型项目使用gulp,比如vscode

二十七、FIS的基本使用

百度团队开发的构建工具
yarn global add fis3
fis3 release
fis3 release -d output // 指定到output文件夹
在这里插入图片描述
fis-conf.js

复制代码
1
2
3
4
fis.match('*.{js,scss,png}',{ release:'/assets/$0' })

静态资源配置
在这里插入图片描述
yarn global add fis-parser-node-sass
把sass语法转换为正常的css语法

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
fis.match('*.{js,scss,png}',{ release: '/assets/$0' }) fis.match('**/*.scss',{ rExt: '.css', // rename paeser: fis.plugin('node-sass') }) fis.match('**/*.js',{ parser: fis.plugin('babel-6.x'), optimizer: fis.plugin('uglify-js') //压缩 })

最后

以上就是稳重纸鹤最近收集整理的关于自动化构建工具Grunt、Gulp的全部内容,更多相关自动化构建工具Grunt、Gulp内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(90)

评论列表共有 0 条评论

立即
投稿
返回
顶部