脚手架发展进程

yeoman

全局安装yarn 

npm install yarn -g 

在全局范围安装yo

npm install yo -g   或 yarn global add yo
安装对应的generator
npm install generator-node -g  或 yarn global add generator-node 
通过yo运行generator生成器

mkdir my-demo

cd my-demo

yo node 自动生成项目结构

sub generator 运行generator-node里面的子集生成器

在上面生成的文件夹运行下面指令

yo node:cli

前端自动化构建工具 ---- Plop

下面随便写了个小列子验证

首先安装

npm install plop --save-dev

 创建

1、plopfile.js

//plop入口文件,需要导出一个函数
//此函数接受一个plop对象,用于创建生成器任务

module.exports = plop => {
  plop.setGenerator('fileName', { // fileName 就是接下来的yarn plop命令后面带来指令名称
    description: 'create a fileName',
    prompts: [
      {
        type: 'input',
        name: 'name',
        message: 'fileName name',
        default: 'MyfileName'
      }
    ],
    actions: [
      {
        type: 'add', // 代表添加文件
        path: 'src/views/{{name}}/index.tsx', // 要生成的文件路径
        templateFile: 'plop-templates/index.hbs' // 文件模板
      },
      {
        type: 'add', // 代表添加文件
        path: 'src/views/{{name}}/index.less', // 要生成的文件路径
        templateFile: 'plop-templates/index.less.hbs' // 文件模板
      },
      {
        type: 'add', // 代表添加文件
        path: 'src/views/{{name}}/store.ts', // 要生成的文件路径
        templateFile: 'plop-templates/store.ts.hbs' // 文件模板
      },
      {
        type: 'add', // 代表添加文件
        path: 'src/views/{{name}}/actor.ts', // 要生成的文件路径
        templateFile: 'plop-templates/actor.ts.hbs' // 文件模板
      },
      {
        type: 'add', // 代表添加文件
        path: 'src/views/{{name}}/webapi.ts', // 要生成的文件路径
        templateFile: 'plop-templates/webapi.ts.hbs' // 文件模板
      },
      {
        type: 'add', // 代表添加文件
        path: 'src/views/{{name}}/types.ts', // 要生成的文件路径
        templateFile: 'plop-templates/types.ts.hbs' // 文件模板
      }
    ]
  })

}

 2、plop-templates文件夹

 这里面就是我需要公用的模板文件

运行指令

yarn plop fileName (生成器名字)

 

这样需要的文件就生成了

 

 -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

npm scripts介绍  :npm 允许在package.json文件里面,使用scripts字段定义脚本命令。

scripts字段是一个对象。它的每一个属性,对应一段脚本。
"build":"sass scss/main.scss css/style.css"
对应. ode_modules.binsass scss/main.scss css/style.css
 
Browsersync能让浏览器实时、快速响应您的文件更改(html、js、css、sass、less等)并自动刷新页面
npm install browser-sync --save-dev
"serve":"browser-sync"
 
需要启动serve命令之前运行build
npm 脚本有pre和post两个钩子
"preserve":"yarn build",
 
也可以同时运行多个命令
运行多个命令时,npm-run-all提供了多种运行多个命令的方式
npm install npm-run-all --save-dev
 "openBrowser":"npm-run-all preserve serve"
gulp
//gulp入口文件
//series 串行(顺序)执行
//parallel 并行执行
const {series,parallel} = require('gulp');

const task1 = done =>{
  setTimeout(()=>{
    console.log("task1");
    done();
  },1000)
}

const task2 = done =>{
  setTimeout(()=>{
    console.log("task2");
    done();
  },1000)
}

const task3 = done =>{
  setTimeout(()=>{
    console.log("task3");
    done();
  },1000)
}
//series 串行(顺序)执行
exports.foo = series(task1, task2, task3);
//parallel 并行执行
exports.bar = parallel(task1, task2, task3);

  

//gulpfile.js
//gulp结合node
const fs= require('fs');
//转换流
const { Transform } =require('stream');
exports.default =()=>{
  //文件读取流
  const read = fs.createReadStream('normalize.css');
  //文件写入流
  const write=fs.createWriteStream('normalize.min.css');

  //文件流转换 
  // 转换流也是双工流。
  const transform = new Transform({
    transform(chunk, encoding, callback){
      //chunk => 读取流中读取的内容(Buffer)
      const data= chunk.toString();
      //替换空格和注释
      const outData=data.replace(/s+/g,'').replace(//*.+?*//g,'');
      callback(null,outData)
    }
  })

  //把读取出来的文件流写入到新的文件流 pipe充当管道的作用
  read
    .pipe(transform) //转换
    .pipe(write); //写入

  return read;
} 

 使用gulp来实现以上情形,注意要使用gulp插件

1安装压缩css 插件  gulp-clean-css,相对来说gulp更加简洁

//创建一个流,用于从文件系统读取 Vinyl 对象。
const {src, dest} = require('gulp');
const gulpCleanCss = require('gulp-clean-css')

exports.default = ()=> {
  return src('src/*.css')
  .pipe(gulpCleanCss())
  .pipe(dest('dist'))
}
//创建一个流,用于从文件系统读取 Vinyl 对象。
const {src, dest} = require('gulp');
const gulpCleanCss = require('gulp-clean-css');
//自定义后缀名称
const rename = require('gulp-rename');

exports.default = ()=> {
  return src('src/*.css')
  .pipe(gulpCleanCss())
  .pipe(rename({
    extname:'.min.css'
  }))  
  .pipe(dest('dist'))
}

 gulp项目使用从简如深

const {src, dest, parallel, series} = require('gulp');
const sass = require('gulp-sass');
const babel = require('gulp-babel');
const swig = require('gulp-swig');
const imagemin = require('gulp-imagemin');
const del = require('del');
/*清空文件*/
const clean = () => {
  return del([
    'dist'
  ])
}

const style = () =>{
  return src('src/assets/styles/*.scss', {base: 'src'})/*保留原有结构*/
    .pipe(sass({outputStyle: 'expanded'})) /*设置{}样式展示*/
    .pipe(dest('dist'));
}

const scripts = () => {
  return src('src/assets/scripts/*.js', {base: 'src'})
    .pipe(babel({
      presets: ['@babel/preset-env']
    }))
    .pipe(dest('dist'))
}

const pages = () => {
  return src('src/*.html', {base: 'src'})
    .pipe(swig({data}))
    .pipe(dest('dist'))
}

const images = ()  =>{
  return src('src/assets/images/**', {base: 'src'})
    .pipe(imagemin())
    .pipe(dest('dist'))
}

const font = ()  =>{
  return src('src/assets/fonts/**', {base: 'src'})
    .pipe(imagemin())
    .pipe(dest('dist'))
}

const extra = () => {
  return src('public/**' , {base: 'public'})
    .pipe(dest('dist'))
}


//并行执行
const compile = parallel(style, scripts, pages);

const build = series(clean, parallel(compile, extra, images, font)); 
module.exports={ build}

 yarn gulp build就可以看到效果了

进一步

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 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 scripts = () => {
  return src('src/assets/scripts/*.js', { base: 'src' })
    .pipe(plugins.babel({
      presets: ['@babel/preset-env']
    }))
    .pipe(dest('temp'))
    .pipe(bs.reload({ stream: true }))  //以流的方式传递
}

const pages = () => {
  return src('src/*.html', { base: 'src' })
    .pipe(plugins.swig({ data }))
    .pipe(dest('temp'))
    .pipe(bs.reload({ stream: true }))  //以流的方式传递
}

const images = () => {
  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', scripts)
  watch('src/*.html', pages)
  // watch('src/assets/images/**',images)
  // 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', '.']
    }))
    .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, scripts, pages);

const develop = series(compile, serve);

const build = series(
  clean,
  parallel(
    series(compile, useref),
    extra,
    images,
    font
  )
);

module.exports = {
  clean,
  develop,
  build
}

上一个package.json安装

//package.json
{
  "name": "zce-gulp-demo-master",
  "version": "1.0.0",
  "main": "index.js",
  "author": "yjx",
  "license": "MIT",
  "scripts":{
    "clean": "gulp clean",
    "develop": "gulp develop",
    "build": "gulp build"
  },
  "dependencies": {
    "@babel/core": "^7.14.6",
    "@babel/preset-env": "^7.14.5",
    "gulp": "^4.0.2",
    "gulp-babel": "^8.0.0",
    "gulp-sass": "^4.1.0",
  },
  "devDependencies": {
    "bootstrap": "^5.0.1",
    "browser-sync": "^2.26.14",
    "del": "^6.0.0",
    "gulp-clean-css": "^4.3.0",
    "gulp-htmlmin": "^5.0.1",
    "gulp-if": "^3.0.0",
    "gulp-load-plugins": "^2.0.7",
    "gulp-uglify": "^3.0.2",
    "gulp-swig": "^0.9.1"
    "gulp-imagemin": "^7.1.0",
    "gulp-useref": "^5.0.0"
  }
}
    

 在进一步

首先pckage.json里面添加运行指令,同上图

然后是gulpfile.js

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 cwd = process.cwd();
let config = {
  build:{
    src: 'src',
    dist: 'dist',
    temp: 'temp',
    public: 'public',
    paths:{
      styles:'assets/styles/*.scss',
      scripts:'assets/scripts/*.js',
      pages: '*.html',
      images: 'assets/images/**',
      fonts:'assets/fonts/**'
    }
  }
}
try{
  const loadConfig = require(`${cwd}/pages.config.js`)
  config = Object.assign({}, config,loadConfig)
}catch (e) {}


const clean = () => {
  return del([
    config.build.dist,
    config.build.temp
  ])
}

const styles = () => {
  return src(config.build.paths.styles, { base: config.build.src, cwd: config.build.src})/*保留原有结构*/
    .pipe(plugins.sass({ outputStyle: 'expanded' })) /*设置{}样式展示*/
    .pipe(dest(config.build.temp))
    .pipe(bs.reload({ stream: true }))  //以流的方式传递
}

const scripts = () => {
  return src(config.build.paths.scripts, { base: config.build.src, cwd: config.build.src })
    .pipe(plugins.babel({
      presets: ['@babel/preset-env']
    }))
    .pipe(dest(config.build.temp))
    .pipe(bs.reload({ stream: true }))  //以流的方式传递
}

const pages = () => {
  return src(config.build.paths.pages, { base: config.build.src, cwd: config.build.src })
    .pipe(plugins.swig({ data: config.data, defaults: { cache: false }  }))
    .pipe(dest(config.build.temp))
    .pipe(bs.reload({ stream: true }))  //以流的方式传递
}

const images = () => {
  return src(config.build.paths.images, { base: config.build.src, cwd: config.build.src })
    .pipe(plugins.imagemin())
    .pipe(dest(config.build.dist))
}

const font = () => {
  return src(config.build.paths.fonts, { base: config.build.src, cwd: config.build.src })
    .pipe(plugins.imagemin())
    .pipe(dest(config.build.dist))
}

const extra = () => {
  return src('**', { base: config.build.public, cwd: config.build.public })
    .pipe(dest(config.build.dist))
}

const serve = () => {
  /**监听文件的变化 */
  watch(config.build.paths.styles, { cwd: config.build.src }, styles)
  watch(config.build.paths.scripts, { cwd: config.build.src }, scripts)
  watch(config.build.paths.pages, { cwd: config.build.src }, pages)
  // watch('src/assets/images/**',images)
  // watch('src/assets/fonts/**',font)
  // watch('public/**',extra)
  //减少请求
  watch([
    config.build.paths.images,
    config.build.paths.fonts
  ],{ cwd: config.build.src }, bs.reload)

  watch('**', { cwd: config.build.public }, bs.reload)

  bs.init({
    notify: false, //去掉右侧连接提示
    port: 2080,
    //open:false,
    // files:'dist/**',//指定文件变化监听  (加了流就可以去掉这个)
    server: {
      baseDir: [config.build.temp, config.build.dist, config.build.public],
      routes: {
        '/node_modules': 'node_modules'
      }
    }
  })
}

const useref = () => {
  return src(config.build.paths.pages, { base: config.build.temp, cwd: config.build.temp })
    .pipe(plugins.useref({
      searchPath: [config.build.temp, '.']
    }))
    .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(config.build.dist))
}
//并行执行
const compile = parallel(styles, scripts, pages);

const develop = series(compile, serve);

const build = series(
  clean,
  parallel(
    series(compile, useref),
    extra,
    images,
    font
  )
);

module.exports = {
  clean,
  develop,
  build
}  

为了方便修改文件路径,代码里面加了一个浅拷贝,新建一个pages.config.js 来做配置

//pages.config.js
module.exports={
  build:{
    src: 'src',
    dist: 'dist',
    temp: 'temp',
    public: 'public',
    paths:{
      styles:'assets/styles/*.scss',
      scripts:'assets/scripts/*.js',
      pages: '*.html',
      images: 'assets/images/**',
      fonts: 'assets/fonts/**'
    }
  }
}

  

日常所遇,随手而记。
原文地址:https://www.cnblogs.com/zhihou/p/14868479.html