二款打包工具简介
Rollup打包工具
极简配置,相对打包的更纯粹JS文件,打包后的也更清晰,这款打包做的事情比较少,只是JS模块打包器,不像其它打包工具比较庞大臃肿。
1 2 |
npm install -g rollup #全局安装 npm install --save-dev rollup #本地安装 |
gulp打包工具
极简配置,而且是打包基于类似流式管道编译(编译速度非常快),易于学习API也不太多,不像webpack复杂的构建打包
1 2 |
npm install -g gulp #全局安装,用全局命令要打包使用的 npm install --save-dev gulp #本地项目安装 |
二个命令都要安装的哦,一个全局一个本地
二款打包工具融合篇
每款打包工具应用场景不一样,所以融合起来让每一个工具作他优势的本份工作,先安装上面介绍的基础包,另外单个独立使用使用看官网是很容易上手的,本篇文章只作融合相关资料介绍
1、先安装gulp相关插件
gulp-uglify压缩插件,
gulp-concat合并插件
gulp-watch 监听
gulp-plumber错误提示
gulp-strip-comments 删除注释
gulp-sourcemaps生成map日志
相关每个插件集成安装命令
1 |
npm install --save-dev gulp-uglify gulp-concat gulp-watch gulp-plumber gulp-strip-comments gulp-sourcemaps |
gulp这二个组件的编译看自己需求安装,
gulp-babel编译语法插件,它提供二种下载模式,本次使用ES7编译模块
1 2 |
npm install --save-dev gulp-babel @babel/core @babel/preset-env 编译ES7语法 npm install --save-dev gulp-babel@7 babel-core babel-preset-env 编译ES6语法 |
gulp-streamify 提供给上面gulp-babel 插件组件使用
1 |
npm install --save-dev gulp-streamify |
2、安装rollup相关插件
rollup-plugin-babel 编译语法插件,此次使用了babel7的编译包
1 2 3 |
npm install --save-dev rollup-plugin-babel@latest #这个是编译babel7.X npm install --save-dev rollup-plugin-babel@3 #这个是编译babel 6.x |
rollup-plugin-commonjs 打包 commonjs模块
rollup-plugin-node-resolve 插件可以告诉 Rollup 如何查找外部模块
安装上面二个插件命令
1 |
npm install --save-dev rollup-plugin-commonjs rollup-plugin-node-resolve |
3、环境介绍
这是.babelrc文件
1 2 3 4 5 6 7 |
{ "presets": [ ["env",{ "modules": false }] ] } |
这是包情况(测试环境)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
"devDependencies": { "@babel/core": "^7.2.0", "@babel/preset-env": "^7.2.0", "gulp": "^3.9.1", "gulp-babel": "^8.0.0", "gulp-concat": "^2.6.1", "gulp-plumber": "^1.2.1", "gulp-sourcemaps": "^2.6.4", "gulp-streamify": "^1.0.2", "gulp-strip-comments": "^2.5.2", "gulp-uglify": "^3.0.1", "gulp-watch": "^5.0.1", "rollup": "^0.67.4", "rollup-plugin-babel": "^4.0.3", "rollup-plugin-commonjs": "^9.2.0", "rollup-plugin-node-resolve": "^3.4.0" } |
4、融合二个工具
为什么webpack有打包编译压缩,我们还要在单独融合另外二款软件呢??因为webpack打包太慢了,而且我们整合的打包工具只为打包我们在node及后面配置应用的打包编译压缩,利用rollup把多余未用到的代码压缩清除,在通过gulp流式打包(是否压缩看情况)
创建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 |
var gulp = require('gulp'), uglify = require('gulp-uglify'), // 压缩,也是看需求安装 concat = require('gulp-concat'), // 合并插件,看情况需求用,可不安装 watch = require('gulp-watch'), //监听 plumber = require('gulp-plumber'), //错误管理 提示 sourcemaps = require('gulp-sourcemaps'), // 生成map记录 strip = require('gulp-strip-comments'), //删除注释 streamify = require('gulp-streamify'), //只支持 buffer 的插件直接处理 stream babel = require('gulp-babel'); // babel编译,这个看需求安装 // var rollup = require('gulp-rollup'); // 虽然有一款这种插件,但还是在原生的 var rollup = require('rollup'); // 这是要本地在安装一份的哦,不然找不到 var resolve = require('rollup-plugin-node-resolve'); //插件可以告诉 Rollup 如何查找外部模块 var commonjs = require('rollup-plugin-commonjs'); //打包 commonjs模块 var rollupBabel = require('rollup-plugin-babel'); // 编译rollup,取名变量名不要和gulp的编译插件重名了 var path = { src: { // gulp要查找的目录,最终会打包清理注释,压缩文件夹 js: ['test/*.js','app.min.js'] // test目录下所有js文件 }, dist: { // 输出目录 js: "core/" } }; gulp.task('6to5', () => { return rollup.rollup({ input: './test/index.js', // 我要使用rollup先清理配置文件中多余的代码 watch: { exclude: 'node_modules/**' }, plugins: [ rollupBabel({ exclude: 'node_modules/**' }), commonjs({ // 转换es5供rollup使用 include: 'node_modules/**', // 排除文件 // exclude: [ 'node_modules/foo/**', 'node_modules/koa-static/**' ], }), resolve({ // 将自定义选项传递给解析插件,你自定义了一些组件配置引入,就写入这解析 customResolveOptions: { moduleDirectory: './config' } }), ], // 指出应将哪些模块视为外部模块,不编译 // 你引入了哪些模块就在这定义一下 external: [ 'koa', 'koa-static', 'koa-swig', 'co', 'log4js', 'koa-bodyparser', 'node-fetch','./Base' ] }) .then((bundle) => { bundle.write({ file: './app.min.js', // 输出到根目录下,并且名称叫app.min.js format: 'es', // iife规范下的全局变量名称 moduleName: 'zzq', }); }) .then(() => { // 待 rollup 打包 js 完毕之后,再进行如下的处理: gulp.src(path.src.js) // 打开指定需要压缩及去注释或压缩的文件(一般用于node相关配置或是其它配置) .pipe(watch(path.src.js)) // 监听指定文件 .pipe(plumber()) // 错误管理提示 .pipe(sourcemaps.init()) .pipe(strip()) //去除注释 // 编译 /*.pipe(streamify(babel( { "presets": ["重新定义babel里面的编译规则,这里就不写了"] } ))) */ .pipe(uglify()) // 压缩 .pipe(rename('name.min.js'))// 产出的压缩的文件名,可注释关闭,默认输出原文件名 .pipe(sourcemaps.write({ addComment: false })) .pipe(plumber.stop()) // 错误管理闭关 .pipe(gulp.dest(path.dist.js)) // 输出到到build目录内 }) }); // 默认任务配置 gulp.task('default', () => { gulp.run('6to5'); // 启动指定任务名 // 监听 js 原始文件的变化,有变化启用指定任务 gulp.watch(path.src.js, () => { gulp.run('6to5'); }) }); |
这时候融合结束,平常打包node相关配置或是其它指定文件的(非前端业务层),
启动压缩打包清理命令 ,默认会找到事件6to5,启动这个事件并且监听如有变动还会在重新编译
1 |
gulp |
这时候在node层的优化及给webpack层的配置会更精简(非人看),因为里面还有一份原代码供自己调试,并且随时打包编译压缩
gulp常用插件介绍整理
到哪儿去找最好用的gulp插件
1、gulp-plugins搜索
https://gulpjs.com/plugins/
列表中的每个插件都有归类的标签,可以点相关标签去查看相近的插件有哪些
2、npm插件搜索
输入gulp,即可列出所有包名带gulp的插件,还可以从最佳,受欢迎程度,代码质量,维护等几个纬度对搜索结果进行排名
3、别人的team总结的资源
https://github.com/Platform-CUF/use-gulp
这个team总结的常用的gulp插件比较详细,每一个都有github的连接.还列有gulp相关的视频资源连接
匹配符 *、**、!、{}
1 2 3 4 |
gulp.src('./js/*.js') // * 匹配js文件夹下所有.js格式的文件 gulp.src('./js/**/*.js') // ** 匹配js文件夹的0个或多个子文件夹 gulp.src(['./js/*.js','!./js/index.js']) // ! 匹配除了index.js之外的所有js文件 gulp.src('./js/**/{omui,common}.js') // {} 匹配{}里的文件名 |
我常用的gulp插件
file文件操作
del (替代gulp-clean)
1 2 3 |
var del = require('del'); del('./dist'); // 删除整个dist文件夹 |
gulp-rename
描述:重命名文件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
var rename = require("gulp-rename"); gulp.src('./hello.txt') .pipe(rename('gb/goodbye.md')) // 直接修改文件名和路径 .pipe(gulp.dest('./dist')); gulp.src('./hello.txt') .pipe(rename({ dirname: "text", // 路径名 basename: "goodbye", // 主文件名 prefix: "pre-", // 前缀 suffix: "-min", // 后缀 extname: ".html" // 扩展名 })) .pipe(gulp.dest('./dist')); |
gulp-concat
描述:合并文件。
1 2 3 4 5 6 7 8 9 |
var concat = require('gulp-concat'); gulp.src('./js/*.js') .pipe(concat('all.js')) // 合并all.js文件 .pipe(gulp.dest('./dist')); gulp.src(['./js/demo1.js','./js/demo2.js','./js/demo2.js']) .pipe(concat('all.js')) // 按照[]里的顺序合并文件 .pipe(gulp.dest('./dist')); |
gulp-filter
描述:在虚拟文件流中过滤文件。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
var filter = require('gulp-filter'); const f = filter(['**', '!*/index.js']); gulp.src('js/**/*.js') .pipe(f) // 过滤掉index.js这个文件 .pipe(gulp.dest('dist')); const f1 = filter(['**', '!*/index.js'], {restore: true}); gulp.src('js/**/*.js') .pipe(f1) // 过滤掉index.js这个文件 .pipe(uglify()) // 对其他文件进行压缩 .pipe(f1.restore) // 返回到未过滤执行的所有文件 .pipe(gulp.dest('dist')); // 再对所有文件操作,包括index.js |
gulp-header
描述:给文件头部添加信息
1 2 3 4 5 6 7 |
var header = require('gulp-header'); /*载入gulp-header模块*/ var pkg = require("./package.json"); /*获取json文件*/ var banner = "/** \n\ * " + pkg.name + " V" + pkg.version + " \n\ * By 小珍\n\ */\n"; |
压缩
gulp-uglify
描述:压缩js文件大小。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
var uglify = require("gulp-uglify"); gulp.src('./hello.js') .pipe(uglify()) // 直接压缩hello.js .pipe(gulp.dest('./dist')) gulp.src('./hello.js') .pipe(uglify({ mangle: true, // 是否修改变量名,默认为 true compress: true, // 是否完全压缩,默认为 true preserveComments: 'all' // 保留所有注释 })) .pipe(gulp.dest('./dist')) |
gulp-csso
描述:压缩优化css。
1 2 3 4 5 |
var csso = require('gulp-csso'); gulp.src('./css/*.css') .pipe(csso()) .pipe(gulp.dest('./dist/css')) |
gulp-html-minify
描述:压缩HTML。
1 2 3 4 5 |
var htmlminify = require('gulp-html-minify'); gulp.src('index.html') .pipe(htmlminify()) .pipe(gulp.dest('./dist')) |
gulp-imagemin
描述:压缩图片。
1 2 3 4 5 6 7 8 9 10 11 |
var imagemin = require('gulp-imagemin'); gulp.task('imagemin', function() { gulp.src(basePath + 'src/images/*.{png,jpg,gif,ico}') .pipe(imagemin({ optimizationLevel: 3, //类型:Number默认:3取值范围:0-7(优化等级) progressive: false, //类型:Boolean 默认:false 无损压缩jpg图片 interlaced: true, //类型:Boolean 默认:false 隔行扫描gif进行渲染 multipass: true //类型:Boolean 默认:false 多次优化svg直到完全优化 })) .pipe(gulp.dest(basePath + 'dist/images/')); }); |
gulp-zip
描述:ZIP压缩文件。
1 2 3 4 5 |
var zip = require('gulp-zip'); gulp.src('./src/*') .pipe(zip('all.zip')) // 压缩成all.zip文件 .pipe(gulp.dest('./dist')) |
JS/CSS自动注入
gulp-autoprefixer
描述:自动为css添加浏览器前缀。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
var autoprefixer = require('gulp-autoprefixer'); gulp.src('./css/*.css') .pipe(autoprefixer()) // 直接添加前缀 .pipe(gulp.dest('dist')) gulp.src('./css/*.css') .pipe(autoprefixer({ browsers: ['last 2 versions'], // 浏览器版本 cascade:true // 美化属性,默认true add: true // 是否添加前缀,默认true remove: true // 删除过时前缀,默认true flexbox: true // 为flexbox属性添加前缀,默认true })) .pipe(gulp.dest('./dist')) |
查看更多配置:options
更多浏览器版本:browsers
gulp-useref
描述:解析构建块在HTML文件来代替引用未经优化的脚本和样式表。
作用:src中的html文件中引用多个样式文件,通过构建工具的文件合并多个文件为*all.css. 新的html文件里就自动删除以前的多个样式文件的引用,重新引用*all.css文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
// index.html <!-- build:css /css/all.css --> <link rel="stylesheet" href="css/normalize.css"> <link rel="stylesheet" href="css/main.css"> <!-- endbuild --> // gulpfile.js var useref = require('gulp-useref'); gulp.src('index.html') .pipe(useref()) .pipe(gulp.dest('./dist')) |
替换之后的index.html中就会变成:
1 |
<link rel="stylesheet" href="css/all.css"> // 之前的两个<link>替换成一个了 |
gulp-rev
描述:给静态资源文件名添加hash值:unicorn.css => unicorn-d41d8cd98f.css
1 2 3 4 5 |
var rev = require('gulp-rev'); gulp.src('./css/*.css') .pipe(rev()) .pipe(gulp.dest('./dist/css')) |
gulp-rev-replace
描述:重写被gulp-rev重命名的文件名。
1 2 3 4 5 6 7 8 9 |
var rev = require('gulp-rev'); var revReplace = require('gulp-rev-replace'); var useref = require('gulp-useref'); gulp.src('index.html') .pipe(useref()) // 替换HTML中引用的css和js .pipe(rev()) // 给css,js,html加上hash版本号 .pipe(revReplace()) // 把引用的css和js替换成有版本号的名字 .pipe(gulp.dest('./dist')) |
gulp-html-replace
描述:替换html中的构建块。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
// index.html <!-- build:css --> // css是buildName,可以自己定义 <link rel="stylesheet" href="css/normalize.css"> <link rel="stylesheet" href="css/main.css"> <!-- endbuild --> // gulpfile.js var htmlreplace = require('gulp-html-replace'); gulp.src('index.html') .pipe(htmlreplace({ 'css':'all.css' // css是index.html中定义的buildName })) .pipe(gulp.dest('./dist')) |
替换之后的index.html中就会变成:
1 |
<link rel="stylesheet" href="all.css"> // 之前的两个<link>替换成一个了 |
gulp-uncss
描述: gulp插件去除css文件中的 未用到的css
1 2 3 4 5 6 7 8 |
var uncss = require('gulp-uncss'); gulp.task('uncss', ["csso", "cssmin"], function() { gulp.src(basePath + 'dist/css/*.css') .pipe(uncss({ html: [basePath + 'dist/*.html'] /*这里是项目所有的html目录*/ })) .pipe(gulp.dest(basePath + 'dist/uncss')); }) |
gulp-cssmin
描述: css压缩
1 2 3 4 5 6 7 8 9 10 |
var cssmin = require('gulp-cssmin'); var ext_replace = require('gulp-ext-replace'); /*文件扩展名替换插件*/ gulp.task('cssmin', ["less"], function() {/*先执行less任务,再执行cssmin任务*/ gulp.src([basePath + 'dist/css/*.css', '!' + basePath + 'dist/css/*.min.css']) .pipe(cssmin()) .pipe(header(banner)) .pipe(ext_replace('.min.css')) .pipe(gulp.dest(basePath + 'src/css/')); }); |
流控制
gulp-if
描述:有条件地运行一个任务。
1 2 3 4 5 6 7 8 |
var gulpif = require('gulp-if'); var uglify = require('gulp-uglify'); var concat = require('gulp-concat'); var condition = true; gulp.src('./js/*.js') .pipe(gulpif(condition, uglify(), concat('all.js'))) // condition为true时执行uglify(), else 执行concat('all.js') .pipe(gulp.dest('./dist/')); |
工具
gulp-load-plugins
描述:从包的依赖和附件里加载gulp插件到一个对象里给你选择。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
// package.json "devDependencies": { "gulp": "^3.9.1", "gulp-concat": "^2.6.1", "gulp-rename": "^1.2.2", "gulp-uglify": "^2.0.1" } // gulpfile.js var $ = require('gulp-load-plugins')(); // $ 是一个对象,加载了依赖里的插件 gulp.src('./**/*.js') .pipe($.concat('all.js')) // 使用插件就可以用$.PluginsName() .pipe($.uglify()) .pipe($.rename('all.min.js')) .pipe(gulp.dest('./dist')) |
gulp-sass
描述:编译sass。
1 2 3 4 5 6 7 8 9 |
var sass = require('gulp-sass'); gulp.src('./sass/**/*.scss') .pipe(sass({ outputStyle: 'compressed' // 配置输出方式,默认为nested })) .pipe(gulp.dest('./dist/css')); gulp.watch('./sass/**/*.scss', ['sass']); // 实时监听sass文件变动,执行sass任务 |
gulp-babel
描述:将ES6代码编译成ES5。
1 2 3 4 5 6 7 |
var babel = require('gulp-babel'); gulp.src('./js/index.js') .pipe(babel({ presets: ['es2015'] })) .pipe(gulp.dest('./dist')) |
gulp-util
描述:一个实用工具,当初为了知道为何js压缩失败而找到这个工具用来打印错误日志
1 2 3 4 5 6 7 8 9 10 11 |
var gutil = require('gulp-util'); gulp.task('*****', function() { gulp.src('*****') .pipe('***某个插件任务**') /*这个任务可能错误,下面监听错误*/ .on('error', function(err) { gutil.log(gutil.colors.red('[Error]'), err.toString()); /*字符[Error]设置为了红色,后面追加打印错误日志*/ }) .pipe(gulp.dest('*****')); }); |
gulp-connect
描述: connect 本地服务器
1 2 3 4 5 6 7 8 9 10 |
var connect = require("gulp-connect"); gulp.task('server', function() { connect.server({ root: './' + basePath + 'dist/', livereload: true }); }); |
1 2 3 4 5 |
/*html文件重新加载*/ gulp.task('htmlreload', function() { gulp.src(basePath + 'dist/*.html') .pipe(connect.reload()); }); |
gulp watch
描述: gulp 观察,定义哪些文件发生变化时,执行哪些gulp任务
1 2 3 4 |
gulp.task('watch', function() { gulp.watch(basePath + 'src/css/*.less', ['less','html']); gulp.watch(basePath + 'src/*.html', ['ejs',,'html']); }); |
gulp task
描述: gulp 任务,定义gulp任务名和任务流
1 2 |
gulp.task("default", ['watch', 'server']); gulp.task("build", ['ejs', 'imagemin', 'uglify', 'uncss']); |