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字段定义脚本命令。
//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/**' } } }