part2

it2023-07-25  65

简答题

1、谈谈你对工程化的初步认识,结合你之前遇到过的问题说出三个以上工程化能够解决问题或者带来的价值。

解答:

传统语言或语法项目中不能直接支持无法使用模块化 / 组件化重复的机械工作代码风格统一/质量保证依赖后端服务接口支持整体依赖后端项目

2、你认为脚手架除了为我们创建项目结构,还有什么更深的意义?

解答:

提供项目规范和约定将重复工作利用脚手架完成利用脚手架快速搭建特定项目骨架,后续基于这个骨架进行开发

编程题

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

在全局范围安装 yo

$ npm install yo -- global # or yarn global add yo

创建一个generator-< name > 的文件夹 (< name >为脚手架名称)

利用yarn init 创建一个package.json

安装一个yeoman-generator(提供了工具函数)

yarn add yeoman-generator

按照 generator 目录结构穿件目录

generators --> app ---> index.js //index.js const Generator = require('yeoman-generator') module.exports = class extends Generator { // 命令行交互方式获取数据 prompting(){ return this.prompt([ { type: 'input', name: 'name', mesage: 'Your project name', default: this.appname } ]).then(answers => { this.answers = answers }) } writing(){ // 把每一个文件通过模板转换到目标路径 const templates = [ //目标相对路径数组 '.browserslistrc', '.editorconfig', '.env.development', '.env.production', '.eslintrc.js', '.gitignore', 'babel.config.js', 'package.json', 'postcss.config.js', 'README.md', 'public/favicon.ico', 'public/index.html', 'src/App.vue', 'src/main.js', 'src/router.js', 'src/assets/logo.png', 'src/components/HelloWorld.vue', 'src/store/actions.js', 'src/store/getters.js', 'src/store/index.js', 'src/store/mutations.js', 'src/store/state.js', 'src/utils/request.js', 'src/views/About.vue', 'src/views/Home.vue' ] templates.forEach(item => { // item => 每个文件路径 this.fs.copyTpl( this.templatePath(item), this.destinationPath(item), this.answers ) }) } }

通过 yarn link 到全局

在新的工作目录 运行 yo < name >

发布 Generator 将代码托管到GitHub仓库

echo node_modules > .gitignore //忽略 node_modules 文件提交 git init //初始化 git 仓库 git status //查看仓库状态 git add . git commit -m "meat: initial commit" git remote add origin 远端仓库地址 // 为远端仓库添加一个别名 git push -u origin master

通过 yarn publish 发布

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

对项目进行分析,需要对HTML、SCSS、JS进行构建并压缩,对图片字体文件进行压缩1、将 scss 文件转换成css文件 gulp-sass2、将 js 文件中 es6 新特性转换 gulp-babel @babel/core @babel/preset-env3、处理页面中的模板语法 gulp-swig 将动态数据添加到模板引擎中4、压缩 img 图片 gulp-imagemin5、压缩 字体文件 gulp-imagemin6、创建编译任务 用 parallel 将 scss js HTML img font 并行处理7、拷贝 public 文件下的所有文件8、创建项目编译任务 build 将 6,7 中任务合并处理9、自动清除 dist 目录下的文件 del10、将 9 中的清除任务添加到 8 中,先清除后编译11、通过 gulp-load-plugins 自动加载插件,运用的插件越来越多手动加载不方便12、启动开发服务器 – 自动编译和刷新文件改变时进行编译操作13、构建 start 任务启动服务前先编译生成 dis 目录14、处理页面中 引用模块 URL 路径问题 gulp-useref15、对 useref 处理的文件进行压缩 利用 plugins.if 判断类型做不同的操作 gulp-htmlmin gulp-uglify gulp-clean-css gulp-if16、解决 useref 读写冲突写入新的目录内17、重新规划目录结构const {src, dest, parallel, series, watch} = require('gulp') const del = require('del') const browserSync = require('browser-sync') const bs = browserSync.create() const loadPlugins = require('gulp-load-plugins') const plugins = loadPlugins() const clean = () => { return del(['dist', 'temp']) } 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 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 compile = parallel(style, script, page) 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/**', // 监听 dist 文件变化刷新 server: { baseDir: ['temp', 'src', 'public'], routes: { '/node_modules': 'node_modules' } } }) } const start = series(compile, serve) 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 build = series(clean, parallel(series(compile,useref), image, font, extra)) module.exports = { build, clean, serve, start }

3、使用 Grunt 完成项目的自动化构建 实现这个项目的构建任务 需要对 src 下的文件进行编译和 public 项目中的文件最终都编译到dist 目录并且启动一个sever自动更新修改的结果

1、安装 load-grunt-tasks 自动加载所有的 grunt 插件中的任务

2、处理项目中的 css 文件 grunt-sass sass

3、处理项目中的 js 文件 @babel/core @babel/preset-env grunt-babel

4、处理页面中的模板语法 grunt-swigtemplates 将动态数据添加到模板引擎中

5、img 图片,fonts 字体处理 grunt-contrib-imagemin

6、拷贝 public 文件下的所有文件到 dist 目录 grunt-contrib-copy

7、创建编译任务 将处理完的文件集体编译到 dist 目录

8、 自动清除 dist 目录下的文件 grunt-contrib-clean

9、启动开发服务器 – grunt-browser-sync 并行执行watch 和 server grunt-concurrent

10、监听文件的变化后自动编译 grunt-contrib-watch

11、处理页面中引用模块 URL 路径问题 grunt-useref grunt-css grunt-contrib-uglify grunt-contrib-concat

12、压缩html grunt-contrib-htmlmin

13、构建build任务

const loadGruntTasks = require('load-grunt-tasks') const sass = require('sass') 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() } module.exports = grunt => { grunt.initConfig({ sass: { options: { // sourceMap: true, implementation: sass }, dist: { files: [{ expand: true, cwd: 'src/assets/styles', src: ['*.scss'], dest: 'dist/assets/styles', ext: '.css' }] } }, babel:{ options: { // sourceMap: true, presets: ['@babel/preset-env'] }, dist: { files:[{ expand: true, cwd: 'src/assets/scripts', src: ['*.js'], dest: 'dist/assets/scripts' }] } }, swigtemplates: { options: { defaultContext: data, templatesDir: 'src' }, production: { dest: 'dist', src: ['src/*.html'] } }, imagemin: { dist: { options: { // optimizationLevel: 3 //定义 PNG 图片优化水平 }, files: [{ expand: true, cwd: 'src/assets/images', // 图片在imagemin目录下 src: ['**'], // 优化 imagemin 目录下所有 png/jpg/jpeg 图片 dest: 'dist/assets/images' // 优化后的图片保存位置,覆盖旧图片,并且不作提示 }, { expand: true, cwd: 'src/assets/fonts', // 图片在imagemin目录下 src: ['**'], // 优化 imagemin 目录下所有 png/jpg/jpeg 图片 dest: 'dist/assets/fonts' // 优化后的图片保存位置,覆盖旧图片,并且不作提示 }] } }, copy: { main: { files: [{ expand: true, cwd: 'public', src: ['**'], dest: 'dist', filter: 'isFile', }], }, }, clean: { build: { src: ['dist'] } }, watch: { js: { files: ['src/assets/scripts/*.js'], tasks: ['babel'] }, css: { files: ['src/assets/styles/*.scss'], tasks: ['sass'] } }, browserSync: { build:{ open: false, notify: false, bsFiles: { src : ['dist', 'src', 'public'] }, options: { port: 2080, //watchTask: true, server: { baseDir: ['dist', 'src', 'public'], routes: { '/node_modules': 'node_modules' } } } } }, concurrent: { target: { tasks: ['browserSync', 'watch'], options: { logConcurrentOutput: true } } }, useref: { html: 'dist/*.html', temp: 'dist' }, htmlmin: { options: { removeComments: true, collapseWhitespace: true, minifyCSS: true, minifyJS: true, }, build: { expand: true, cwd: 'dist', src: '*.html', dest: 'dist', }, }, }) loadGruntTasks(grunt) grunt.registerTask('compile', ['sass','babel','swigtemplates']) grunt.registerTask('htmlbuild', ['useref', 'concat', 'uglify', 'cssmin']) grunt.registerTask('build', ['clean','compile','htmlbuild','copy','htmlmin','imagemin']) grunt.registerTask('start', ['compile','concurrent:target']) }
最新回复(0)