使用grunt
完成项目的自动化构建
一、准备工作
grunt快要退出历史舞台了,简单学习下
mkdir my-grunt
yarn init --yes //创建package模块
yarn add grunt //安装grunt模块
二、创建gruntfile.js文件
//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进行
grunt.registerTask("async-task",function(){
const done = this.async()
setTimeout(()=>{
console.log("async...")
done()
},1000)
})
测试运行
yarn grunt foo
yarn grunt bar
yarn grunt default
yarn grunt async-task
三、grunt标记任务失败
可以通过在任务体中直接return false实现
//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
强制执行
grunt.registerTask("testBad",["foo","bad","bar"])
//执行
yarn grunt testBad --force
四、grunt配置方法
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,如下
//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插件的使用
流程:安装插件载入插件根据插件文档完成相关选项
yarn add grunt-contrib-clean //安裝插件 自动清除临时文件
使用方法,使用loadNpmTasks载入插件
/** * 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
//安装依赖
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载入所有安装的插件,最后完成相关的配置选项。
//安裝
yarn add load-grunt-tasks --dev
//使用
const loadGruntTasks = require("load-grunt-tasks")
//自动加载所有的grunt插件
loadGruntTasks(grunt)
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
yarn init --yes
yarn add gulp --dev
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')
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的异步任务
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自带的读取流写入流
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
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案例-样式编译
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'))
}
十四、脚本编译
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
}
十五、页面模板编译
<div class="row">
{% for item in [1, 2, 3, 4, 5, 6] %}
</div>
以上面模板为例
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
}
十六、图片和文字字体转换
安装依赖
yarn add gulp-imagemin --dev
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
}
十七、其他文件及文件清除
npm i del -D // 不是gulp插件
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
}
十八、自动加载插件
yarn add gulp-load-plugins --dev
不用每次都去引入插件,可以使用plugins自动引入插件
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'))
}
十九、开发服务器
安装依赖
yarn add browser-sync --dev
yarn add bootstrap@4.0.0-alpha.6 --dev
任务创建
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
}
yarn gulp serve
二十、监视变化以及构建优化
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"
}
}
})
}
可以简化
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以及额外的文件,热更没有太大的必要,因为图片压缩是无损压缩,太多的监视会一定程度上消耗性能,所以一般不对其就行监视,修改
watch("src/assets/styles/*.scss",style)
watch("src/assets/scripts/*.js",script)
watch("src/*.html",page)
//修改basedir
baseDir:["dist","public","src"]
二十一、useref文件引用处理
打包之后部署线上找不到引入文件,用useref插件,注意注释,都是有规律的
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
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-rev
、gulp-rev-collector
// 压缩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做路径替换
最后效果
二十四、补充
"scripts": {
"clean": "gulp clean",
"build": "gulp build",
"develop": "gulp develop"
}
yarn clean
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
{
"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
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 是全是模块,给个入口,剩下的全交给它处理
- 工作原理不同:
webpack
:- 首先通过入口文件(
entry
)找到项目中所有的模块(module
)。
将这些模块进行静态分析和处理,最终打包成一个或多个bundle
文件。 - 在打包的过程中,
webpack
会根据依赖关系进行代码拆分,将公共代码抽离成独立的chunk
,使得代码的加载变得更加高效。 webpack
还可以通过loade
r来转换非JavaScript
文件,并且可以使用各种插件
进行自定义构建流程和优化。
- 首先通过入口文件(
gulp
:gulp
通过定义不同的任务(task)
来执行各种构建操作。- 通过
gulp.src
获取需要进行处理的文件流,再通过一系列插件进行处理,最后通过gulp.dest
输出到指定的位置。 gulp
的插件可以进行多个操作,比如压缩、合并、重命名等,同时也可以定制自己的插件并加以使用。
HMR
是Webpack的一个功能,即热模块替换,它可以在不刷新浏览器的情况下更新模块。和热更新不同,HMR只会更新其中一个模块,而不是整个页面。这种机制是针对模块化开发而设计的。Gulp并没有自带的HMR功能,但可以使用一些插件或工具来实现类似的效果。例如,使用gulp-connect、browser-sync和lite-server等插件,可以实现自动刷新浏览器,节省手动刷新时间。但是,它们并没有模块热替换的功能。如果需要使用模块热替换,还是需要结合webpack等打包工具来实现。- webpack可以很容易地做
tree-shaking
,gulp不行 - 但是gulp解决不了模块化js文件的问题,于是使用
ts
或者配置sea.js
、require.js
的插件用来解决js模块化,而webpack本身就是模块化为核心。。 gulp
在单页面应用方面输出乏力,而且对流行的单页技术有些难以处理(比如 Vue 单文件组件,使用 gulp 处理就会很困难,而 webpack 一个 loader 就能轻松搞定)- 使用方式上不同,
webpack
里面有大量的loader
和plugin
用来处理和打包资源文件,gulp
有大量的插件,根据定义不同的task
任务去处理和打包资源 - gulp更易于学习,易于使用,webpack相对学习难度更难一些
- 这里没有明确的好坏界限,只是看你的项目使用场景而做选择,也不乏有很多大型项目使用
gulp
,比如vscode
二十七、FIS的基本使用
百度团队开发的构建工具
yarn global add fis3
fis3 release
fis3 release -d output
// 指定到output文件夹
fis-conf.js
fis.match('*.{js,scss,png}',{
release:'/assets/$0'
})
静态资源配置
yarn global add fis-parser-node-sass
把sass语法转换为正常的css语法
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') //压缩
})
今天的文章gradle自动化构建_搭建jenkins实现自动化部署「建议收藏」分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/85905.html