前端工程化

概述

1.多人协作开发,无法硬性统一大家的代码风格 从仓库中pull回来的代码质量无法保证
2.部分功能开发时需要等待后端服务接口提前完成
3.传统语言或语法的弊端
4.无法使用模块化/组件化
5.重复的机械式工作
6.整体依赖后端项目

脚手架工具概要

1.创建项目基础结构、提供项目规范和约定
相同的组织结构
相同的开发范式
相同的模块依赖
相同的工具配置
相同的基础代码

2.常用脚手架工具
react项目:create-react-app
vue项目:vue-cli
angular项目:angular-cli
Yeoman

Yeoman

网站:https://yeoman.io/generators/
1.yarn global add yo(必须要搭配generator使用)
2.yarn global generator-node
3.yo node
4.eslint和babel实现 cliyo node:cli
5.yarn link 全局命令使用
6.yarn 安装依赖
7.my-yeoman --help 使用

Yeoman使用步骤

1.明确你的需求
2.找到合适的generator
3.全局范围安装找到的generator
4.通过yo运行对应的generator
5.通过命令行交互填写选项
6.生成你所需要的项目结构

1.构建一个网页
yarn global add generator-webapp
2.运行这个generator
yo webapp

1.构建一个vue生成器目录
yarn init
yarn add yeoman-generator 提供生成器积累 工具函数 创建生成器更加便捷
2.创建一个generators/app/index.js 此文件作为generator的核心入口
需要导出一个继承自Yeoman Generator 的类型
Yeoman Generator在工作时会自动调用我们在此类型中定义的一些生命周期方法
我们在这些方法中可以通过调用父类提供的一些工具方法实现一些功能 列如文件写入
3.yarn link 链接到全局范围

grunt、gulp和FLS

1.grunt
优点:最早的前端构建工具 可以完成任何搭建工作
缺点:基于临时文件构建的 读写次数过多 构建速度慢
2.gulp
优点:基于内存实现的 处理文件在内存中 可同时执行多个任务 使用方式直观易懂 解决了grunt构建慢的问题
3.FLS(百度推行的)
绑定式的 自由度不高

Grunt 基本使用

(1)准备工作

mkdir my-grunt
cd my-grunt
yarn init --yes  //初始化package文件

(2)安装gulp

yarn add grunt --dev //安裝gulp模块

(3)安装所需插件

//將sass转化为浏览器可识别的css文件
yarn add grunt-sass sass -dev
//将ECMAScript新特性转化
yarn add grunt-babel @babel/core @babel/preset-env --dev
//自动载入文件
yarn add load-grunt-tasks --dev
//监视文件变化
yarn add grunt-contrib-watch --dev
//清除指定文件夹下的文件
yarn add grunt-contrib-clean --dev
//浏览器
yarn add browser-sync --dev
//html文件编译处理
yarn add grunt-web-swig --dev

(3)创建gruntfile.js文件

//Grunt的入口文件
//用于定义一些需要Grunt自动执行的任务
//需要导出一个函数,接收一个grunt的参数
/*** yarn add grunt-contrib-clean* 自动清除临时文件*/
const sass = require("sass")
const loadGruntTasks = require("load-grunt-tasks")
const browserSync = require("browser-sync")
const bs = browserSync.create()module.exports = grunt => {grunt.initConfig({//sass转化为css功能sass: {options: {sourceMap: true, //设置后会生成相应的sourceMap文件implementation: sass},main: {files: {// 目标文件:源文件'dist/css/main.css': 'src/scss/main.scss'}}},//js转化功能babel: {options: {sourceMap: true,//设置后会生成相应的sourceMap文件presets: ["@babel/preset-env"]},main: {files: {// 目标文件:源文件'dist/js/app.css': 'src/js/app.js'}}},web_swig: {options: {swigOptions: {//缓存设置为falsecache: false},getData: function (tpl) {//模板文件的数据return { myGruntTitle: 'hello,grunt-web-swig' };}},main: {expand: true,cwd: 'src/',//源文件文件夹src: "**/*.html",//后缀名匹配dest: "dist/"//目标文件夹},},//监视功能watch: {js: {//文件地址files: ['src/js/*.js'],//执行的任务tasks: ['babel']},css: {//文件地址files: ['src/scss/*.scss'],//执行的任务tasks: ['sass']},html: {//文件地址files: ['src/*.html'],//执行的任务tasks: ['web_swig', 'bs-reload']}},//清除功能clean: {//所要清除的文件路径files: 'dist/**'}})// grunt.loadNpmTasks('grunt-sass')loadGruntTasks(grunt) //自动加载所有的grunt插件grunt.registerTask('default', ['clean', 'sass', 'babel', 'watch'])grunt.registerTask('bs-reload', function () {bs.reload()})grunt.registerTask('bs', function () {const done = this.async()bs.init({server: {port: 8080,// baseDir: 'dist',baseDir: ["dist", "public", "src"],files: 'dist/**',// open:false,routes: {'/node_modules': "node_modules"}}})})grunt.registerTask('compile', ['clean', 'sass', 'babel'])
}

(4)package.json

{"name": "my-grunt","version": "1.0.0","main": "index.js","license": "MIT","scripts": {// yarn clean ---->清除dist文件夹"clean":"grunt clean",// yarn compile ---->编译"compile":"grunt compile",//yarn reload ----->重载"reload":"grunt bs-reload"},"dependencies": {"@babel/core": "^7.10.4","@babel/preset-env": "^7.10.4","grunt": "^1.2.1","grunt-babel": "^8.0.0","grunt-sass": "^3.1.0"},"devDependencies": {"browser-sync": "^2.26.7","grunt-contrib-clean": "^2.0.0","grunt-contrib-watch": "^1.1.0","grunt-tasks": "^1.0.0","grunt-web-swig": "^0.3.1","load-grunt-tasks": "^5.1.0","sass": "^1.26.10"}
}

1、概述脚手架实现的过程,并使用 NodeJS 完成一个自定义的小型脚手架工具

(1)创建目录
(2)创建 package.json

yarn init
{"name": "lrj-scaffolding", // 文件名 在全局使用时"version": "0.1.0","main": "index.js","bin": "cli.js", // 指定cli文件的入口文件: “bin”:"cli.js""author": "lrj","license": "MIT","dependencies": {"ejs": "^2.6.2",  //询问"inquirer": "^7.0.0" //添加模板引擎}}

(3)安装所需依赖

yarn/npm install

(5)创建cli.js文件

#!/usr/bin/env node
// 这段话的意思是让使用 node 进行脚本的解释程序,那下面的就可以使用 node 的语法了const fs = require('fs');
const path = require('path');
const inquirer = require('inquirer'); // 命令行交互插件
const ejs = require('ejs'); // 模板引擎inquirer.prompt([{type: 'input',name: 'name',message: 'Project name?',default: 'my-project'},{type: 'input',name: 'desc',message: 'Project description?'}
])
.then(answers => {// 根据用户回答的结果生成文件// 拿到模板文件const tmplDir = path.join(__dirname, 'templates');// 目标目录const destDir = process.cwd();// 将模板下的文件全部转换到目标目录fs.readdir(tmplDir, (err, files) => {if (err) throw err;files.forEach(file => {// file => 文件相对于 templates 目录的相对路径// 通过模板引擎渲染文件ejs.renderFile(path.join(tmplDir, file), answers, (err, result) => {if (err) throw err;// 将结果写入目标文件fs.writeFileSync(path.join(destDir, file), result);});});})
});

(6)yarn link关联到全局变量
(7)使用

mkdir my-moudle //创建测试文件夹
cd my-moudle    //切换文件夹
lrj-scaffolding  //执行脚手架

2.尝试使用 Gulp 完成项目的自动化构建

(1)准备工作

mkdir my-grunt
cd my-grunt
yarn init --yes  //初始化package文件

(2)安装gulp

yarn add grunt --dev //安裝gulp模块

(3)安装所需插件

  "devDependencies": {"@babel/core": "^7.5.5", //将ECMAScript新特性转化"@babel/preset-env": "^7.5.5", //将ECMAScript新特性转化"browser-sync": "^2.26.7", //启动一个服务"del": "^5.1.0",// 清除文件插件"gulp": "^4.0.2","gulp-babel": "^8.0.0", //将ECMAScript新特性转化"gulp-clean-css": "^4.2.0", //css压缩"gulp-htmlmin": "^5.0.1", //html压缩"gulp-if": "^3.0.0",// 判断"gulp-imagemin": "^6.1.0", //图片压缩"gulp-load-plugins": "^2.0.1", // 自动加载所有的 gulp 插件"gulp-sass": "^4.0.2", //將sass转化为浏览器可识别的css文件  "gulp-swig": "^0.9.1", //html文件编译处理"gulp-uglify": "^3.0.2", //js压缩"gulp-useref": "^3.1.6", // 用于将所有文件打包到一个构建注释的文件中"minimist": "^1.2.5", // 解析命令行参数},"dependencies": {"bootstrap": "^4.3.1","jquery": "^3.4.1","popper.js": "^1.15.0"}

(3)创建gruntfile.js文件

// 实现这个项目的构建任务const { src, dest, parallel, series, watch } = require('gulp');
const path = require('path');
const minimist = require('minimist'); // 解析命令行参数
const del = require('del'); // 清除文件插件
// const Comb = require('csscomb'); // css编码风格格式化
// const standard = require('standard'); // js编码风格格式化
const borwserSync = require('browser-sync'); //建立一个服务
const loadPlugins = require('gulp-load-plugins'); // 自动加载所有的 gulp 插件const plugins = loadPlugins(); //变成这个对象的属性
const bs = borwserSync.create();
const argv = minimist(process.argv.slice(2)); // 获取并处理命令行参数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 = () => {// 'src/**/*.html'  匹配到 src 目录以及子目录下所有的html文件// .pipe(plugins.swig({ data, defaults: { cache: false } })) // 防止模板缓存导致页面不能及时更新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 devServer = () => { //监测到更新 更新dist相应模块watch('src/assets/styles/*.scss', style);watch('src/assets/scripts/*.js', script);watch('src/*.html', page);watch(['src/assets/images/**','src/assets/fonts/**','public/**'], bs.reload);bs.init({notify: false,port: argv.port === undefined ? 2080 : argv.port,// open: false,open: argv.open === undefined ? false : argv.open,// 不使用 files 字段,使用 .pipe(bs.reload({ stream: true })); 也可以// files: 'dist/**', // 监听文件的改变server: {baseDir: ['temp', 'src', 'public'],routes: {'/node_modules': 'node_modules'}}})
};const distServer = () => {bs.init({notify: false,port: argv.port === undefined ? 2080 : argv.port,open: argv.open === undefined ? false : argv.open,server: 'dist'});
}// 使用 useref 之前需要执行 compile 编译
const useref = () => {// 下载useref插件 <!-- build:css assets/styles/vendor.css --><!-- endbuild -->用于将所有文件打包到一个构建注释的文件中// 这里文件名最好不要跟 dist 相同,防止文件读写冲突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 serve = series(compile, devServer);// 上线之前执行的任务。将 image, font 的任务放在这里
const build = series(clean, parallel(series(compile, useref), image, font, extra))  //组合任务//启动打包后的任务
const start = series(build, distServer);module.exports = {clean,lint,serve,build,start
}

(3)启动

  "scripts": {// yarn clean ---->清除dist文件夹"clean":"grunt clean",// yarn compile ---->编译"compile":"grunt compile",// yarn serve---->启动编译后的服务"serve": "gulp serve",// yarn build---->打包"build": "gulp build",// yarn start---->启动打包后的服务"start": "gulp start"},

开发脚手架及封装自动化构建工作流相关推荐

  1. altium designer无法创建工程_前端工程化之开发脚手架及封装自动化构建

    工程化笔记 .  . 光 前端工程化简述 简述 一切能提升前端开发效率,提高前端应用质量的手段和工具都是前端工程化. 模块化,组件化,规范化,自动化. 解决的问题 传统语言或语法的弊端. 无法使用模块 ...

  2. 大前端学习--开发脚手架与自动化构建工作流封装

    开发脚手架与自动化构建工作流封装 去年6月24号开始工作,到今天刚好一周年了,纪念一下,分享最近学习的前端工程化笔记. 一.前端工程化 前端工程化是指遵循一定的标准和规范,通过工具去提高效率.降低成本 ...

  3. 开发脚手架与自动化构建

    一.前端工程化 概念:遵循一定的标准和规范,通过工具去提高效率,降低成本的一种手段 1.遇到的主要问题 想要使用ES6+新特性,但是兼容有问题 想要使用Less/Sass/PostCSS增强CSS的编 ...

  4. 前端工程化——脚手架及自动化构建

    定义 一切以提高效率.降低成本.质量保证为目的的手段,都属于工程化 前端工程化主要解决的问题 传统语言或语法的弊端 无法使用模块化/组件化 重复性的机械工作 代码风格统一.质量保证 依赖后端服务接口的 ...

  5. 浅谈前端自动化构建 -- Grunt、Gulp、FIS

    前言 笔记来源:拉勾教育 大前端高薪训练营 阅读建议:内容较多,建议通过左侧导航栏进行阅读 前端自动化构建 基本介绍 一切重复工作本应自动化.将开发中的源代码,自动化的转换成生产环境中可以运行的程序, ...

  6. 前端工程化实战 - 自动化构建工具

    文章目录 一.自动化构建简介 二.自动化构建初体验 2.1 场景描述 2.2 实际操作体验 三.常用的自动化构建工具 3.1 Grunt 3.2 Gulp 3.3 FIS 四.自动化构建工具 Grun ...

  7. 【Linux】三、Linux 环境基础及开发工具使用(上篇)|开发工具|编辑器-vim使用|sudo提升权限问题|编译器 - gcc/g++使用|项目自动化构建工构建工具-make/Makefile

    目录 一.开发工具 二.Linux编辑器 - vim使用 2.1 vim 的基本概念 2.2 vim的基本操作 2.3 vim正常模式命令集 2.4 vim末行模式命令集 2.5 简单vim配置 2. ...

  8. ios架构与开发第二课 代码规范管理与自动化构建

    05 自动化准备:如何使用 Fatlane 管理自动化操作? 要成为一个优秀的 iOS 开发者,我们要做的事情远多于"开发",例如我们要构建和打包 App,管理证书,为 App 进 ...

  9. 打包node服务端_如何基于NodeJS从零构建线上自动化打包工作流?

    前言 NodeJS在前端领域正扮演着越越重要的地位,它不仅可以让前端工作者使用javascript编写后端代码,还能方便地搭建响应速度快.易于扩展的网络应用.Node.js 使用事件驱动,非阻塞I/O ...

最新文章

  1. python 抛出异常raise
  2. 北大元培系AI公司,一年狂揽三轮融资,最新A轮斩获数千万美元
  3. docker 逃逸 简介
  4. Educational Codeforces Round 37-F.SUM and REPLACE (线段树,线性筛,收敛函数)
  5. mysql 查询不为0的数据_查询数据库中所有记录总数不为0的数据表名称
  6. vue3数据绑定显示列表数据局
  7. Comparable接口的使用:(知识回顾)
  8. element ui实现动态显示textarea剩余字数
  9. 理工科学生计算机要求,理工科学生
  10. vue .native 方法未定义_技术分享谈谈Vue的响应式原理
  11. JDY-24M级蓝牙简介
  12. 在delphi的dbgrid中插入其他可视组件_delphi教程
  13. 计算机上缺少vsix安装程序,使用MSI安装程序部署VSIX
  14. 恐怖的aliedit
  15. phpstudy升级mysql5.6_phpstudy升级mysql数据库
  16. flexbox的基本概念
  17. cs1.6服务器ip地址文件,cs1.6服务器端封禁的IP在那个文件夹里?
  18. java中怎么输入中文_MultiMC下载-MultiMC中文实用版 v1.0
  19. IOS – OpenGL ES 图像柏林噪点/花边噪点 GPUImagePerlinNoiseFilter
  20. 终于解决了hao123锁定主页的问题~

热门文章

  1. Laravel PDF 导出
  2. k8s-滚动更新与健康检查
  3. 深信服2008校园招聘笔试题
  4. vlan 虚拟局域⽹
  5. GetLastError函数封装显示具体错误信息
  6. Windows10升级21H1黑屏解决办法
  7. Koa koa-combine-routers 分路由管理
  8. 修改MAC地址 (苹果电脑)
  9. 标准logo大小尺寸设置标准是什么? logo大小参数详解。
  10. org.postgresql.util.psqlexception总结