自动化构建工具Grunt、Gulp 讲解及实战

自动化构建工具Grunt、Gulp 讲解及实战使用 grunt 完成项目的自动化构建 一 准备工作 grunt 快要退出历史舞台了 简单学习下 mkdir my grunt yarn init yes 创建 package 模块 yarn add grunt 安装 grunt 模块 二 创建 gruntfile js 文件 Grunt 的入口文件

大家好,我是讯享网,很高兴认识大家。

使用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-revgulp-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 是全是模块,给个入口,剩下的全交给它处理

  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

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') //压缩 }) 
小讯
上一篇 2025-02-08 17:52
下一篇 2025-01-07 19:29

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/17843.html