工程化概述

2020-06-18  本文已影响0人  酸菜牛肉
前端工程化解决的问题:
脚手架工具

脚手架本质作用:创建项目基础结构、提供项目规范和约定

步骤:

yeoman的常规使用步骤
  1. 明确你的需求
  2. 找到合适的Generator
  3. 全局范围安装找到的Generator
  4. 通过Yo运行对应的Generator
  5. 通过命令行交互填写选项
  6. 生成你所需要的项目结构
自定义Generator
Generator基本结构
index.js1
index.js2
Plop

小而美的脚手架

自动化构建工具

grunt 的基本使用:
gruntfile.js 文件

module.exports = grunt => {
    grunt.registerTask('foo', () => {
        console.log('hello grunt~')
    })

    grunt.registerTask('bar', '任务描述', () => {
        console.log('other task~')
    })

    grunt.registerTask('default', ['foo', 'bar'])

    // grunt.registerTask('async-task', () => {
    //     setTimeout(() => {
    //         console.log('async task working~')
    //     }, 1000)
    // })
     grunt.registerTask('async-task', function () {
        const done = this.async()
        setTimeout(() => {
            console.log('async task working~')
            done(false) //标记任务失败
        }, 1000)
    })
}

grunt的配置

module.exports = grunt => {
    grunt.initConfig({
        foo: {
            bar: 123
        }
    })
    
    grunt.registerTask('foo', () => {
        console.log(grunt.config('foo'))
    })
}
grunt 的多目标任务
module.exports = grunt => {
    grunt.initConfig({
        build:{
            options: {
                foo: 'bar'
            },
            css: {
                options: {
                    foo: 'baz'
                }
            },
            js: '2'
        }
    })
    //多目标模式,可以让任务根据配置形成多个子任务
    grunt.registerMultiTask('build', function () {
        console.log(this.options())
        console.log(`target: ${this.target}, data: ${this.data}`)
    })
}
grunt 的插件的使用

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/main.js'
                }
            }
        },
        watch: {
            js: {
                files: ['src/js/*.js'],
                task: ['babel']
            },
            css: {
                files: ['src/scss/*.scss'],
                tasks: ['sass']
            }
        }
    })

    //自动加载所有grunt 插件任务
    loadGruntTasks(grunt)

    grunt.registerTask('default', ['sass', 'babel', 'watch'])
    // grunt.loadNpmTasks('grunt-sass')
}

gulp

gulpfile.js

exports.foo = (done) => {
    console.log('foo task working~')
    done() //回调函数,标识任务完成
}

exports.default = (done) => {
    console.log('default task working~')
    done() //回调函数,标识任务完成
}
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文件操作API
const {src, dest} = require('gulp')
const cleanCss = require('gulp-clean-css')
const rename = require('gulp-rename')

exports.default = () => {
    return src('src/*.css')
        .pipe(cleanCss())
        .pipe(rename({extname: '.min.css'}))
        .pipe(dest('dist'))
}
gulp-demo
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
}

上一篇下一篇

猜你喜欢

热点阅读