# fed-e-task-02-01
**Repository Path**: tammylights/fed-e-task-02-01
## Basic Information
- **Project Name**: fed-e-task-02-01
- **Description**: 作业
第二阶段
第一部分
- **Primary Language**: JavaScript
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2021-07-28
- **Last Updated**: 2021-08-05
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
## 简答题
**1、谈谈你对工程化的初步认识,结合你之前遇到过的问题说出三个以上工程化能够解决问题或者带来的价值。**
答:
- 工程化概念:
```
前端工程化是指遵循一定标准和规范,通过工具去提高效率、降低成本的一种手段。
工程化是一种概念上的思想,而非单单一门或特定技术。
```
- 工程化因素:
模块化、组件化、规范化、自动化四方面因素
- 模块化:
```
将一个大的文件拆分成多个模块,按照一个个小模块来划分,利于复用和组合
```
- 组件化:
```
将展现层内容拆分成功能独立的小单元,利于维护、复用
模块化不等于组件化,模块化偏向于文件资源层面划分,而组件化偏向于UI展现层划分,提高开发效率和代码复用率
```
- 规范化:
```
遵循公共或一定的标准规范,可以提高项目与代码的质量,利于多人协作开发和后期维护,降低后期成本
```
- 自动化:
```
简单、重复性的工作交由工具(或程序)来完成,既可以提高开发效率,也可以减少人为因素出错概率
```
- 工程化解决的问题:
- 传统语言或语法的弊端
> 如想要使用ES6+新特性,但兼容有问题;想要使用Less/Sass/PostCSS增强CSS的编程性,但是运行环境不能直接支持
- 无法使用模块化、组件化
> 想要使用模块化的方式提高项目的可维护性,但运行环境不能直接支持
- 重复的机械式工作
> 部署上线前需要手动压缩代码及资源文件,部署过程需要手动上传代码到服务器
- 代码风格统一,质量保证
> 多人协作开发, 无法硬性统一大家的代码风格,从仓库pull回来的代码质量无法保证
- 依赖后端服务接口支持
> 部分功能开发时需要等待后端服务接口提前完成
- 整体依赖后端项目
> 需要部署到后端项目相应目录中,依赖项目结构和服务环境
- 之前开发中遇到的问题及带来的价值
- sass/less模块写法
> 在书写样式表时难免会遇到样式造成全局污染,自己覆盖了全局样式或其他人覆盖了自己的样式,造成程序无法正常渲染问题。使用module.scss写法,使样式仅在该模块生效
- 页面路由地址难以维护问题
> 当一个项目迭代时间久远时,路由已经变得复杂,如若依然使用原本在一个router文件中维护,会造成路由冲突,无法解耦。使用工程化(规范化、自动化)的目录结构不可以相同规则,可以有效避免(文件夹目录结构即为路由地址)
- 图片压缩
> 项目发布时自动进行压缩,减少每次上线前手动压缩处理
**2、你认为脚手架除了为我们创建项目结构,还有什么更深的意义?**
答:
> 目录结构中默认提供了统一的标准规范、自动化流程(如压缩、构建、开发环境、发布等),保证了项目质量和风格,减少了后期维护成本
## 编程题
**1、概述脚手架实现的过程,并使用 NodeJS 完成一个自定义的小型脚手架工具**
答:
> 概述:
- 1、mkdir xx-jgs-cli(项目或者说cli工具名称自定义)
- 2、cd xx-jgs-cli,进入cli目录
- 3、yarn init --yes,通过yarn初始化package.json(也可使用npm init)
- 4、touch cli.js,创建cli命令文件
- 5、修改package.json文件,添加 `bin` 字段,路径为cli文件路径,此处为根目录 `"bin": "cli.js"`, 其他作者等信息自行酌情添加
- 6、根目录创建 `templates` 目录,并在其目录下创建其项目所需目录结构
- 7、打开cli文件,开始编写命令代码,如下:
```
#!/usr/bin/env node
console.log('这里是cli工具')
// 此处的开头必须是此语句
// 脚手架的工作过程
// 1、通过命令行交互询问用户问题
// 2、根据用户回答的结果生成文件(目录)
// 命令行交互模块:inquirer
// 文件读写模块 ejs
const fs = require('fs');
const path = require('path');
const inquirer = require('inquirer');
const ejs = require('ejs');
// inquirer 提供了一个 prompt 方法,用户向用户询问一些问题,并拿到用户回答的结果
inquirer.prompt([ // 第一个参数接受数组的参数,表示需要询问的问题集合
{
type: 'input', // 代表需要用户输入
name: 'name', // 最终回答内容放入的变量,后续也可以通过这个变量在文件内拿到结果
message: '创建的项目名称是?' // 给用户的提示内容
}
]).then(answers => {
// 拿到输入结果后进行生成文件
// 首先拿到模板目录
const tempDir = path.join(__dirname, 'templates');
// 其次是拿到目标目录
const targetDir = process.cwd();
// 接着将模板目录下文件全部输出到目标目录
fs.readdir(tempDir, (error, files) => { // 首先去扫描tempDir下全部文件, 通过回调函数的files拿到全部的目录文件
if (error) throw error; // 错误优先原则,且如果有错误则直接抛出错误并停止
files.forEach(file => { // 没有错误时,通过files.forEach去遍历每个文件,结果是相对于tempDir的文件相对路径
// 拿到路径后,通过模板引擎去渲染文件
ejs.renderFile(path.join(tempDir, file), answers, (err, result) => {
if (err) throw err;
console.log(result);
// 执行成功后通过文件的写入流将文件写入目标目录
fs.writeFileSync(path.join(targetDir, file), result); // 写入时需要文件的绝对路径,因此也需要path拿,最后参数是内容,是这里的result
}) // 第一个参数是文件的绝对略经,所以需要使用path工具拿到, 第二个参数是数据上下文,第三个是回调
})
})
});
```
- 7、yarn link, 将本cli注册到全局作用域内(软连接,不发布时可进行调试)
> 如果是正常使用时,则会将本代码进行发布到npm,在自己的开发环境(一般为自己电脑)全局安装npm包
> yarn add xx-jgs-cli -g
- 8、运行cli命令,根据问题输入相应信息,最终生成项目目录
> 当前版本cli为创建文件类型,附带目录类型创建需优化
**2、尝试使用 Gulp 完成项目的自动化构建** ( **[先要作的事情](https://gitee.com/lagoufed/fed-e-questions/blob/master/part2/%E4%B8%8B%E8%BD%BD%E5%8C%85%E6%98%AF%E5%87%BA%E9%94%99%E7%9A%84%E8%A7%A3%E5%86%B3%E6%96%B9%E5%BC%8F.md)** )
(html,css,等素材已经放到code/pages-boilerplate目录)
答:
> gulp 自动化构建npm包地址: https://github.com/jiaguishan/gulp-jgs-cli
> cli说明详见 [gulp-jgs-cli.md](./gulp-jgs-cli.md)
## 说明:
本次作业中的编程题要求大家完成相应代码后
- 提交一个项目说明文档,要求思路流程清晰。
- 或者简单录制一个小视频介绍一下实现思路,并演示一下相关功能。
- 说明文档和代码统一提交至作业仓库。