2-1作业参考答案

2020-08-27  本文已影响0人  Vicky丶Amor

2-1作业参考答案

简答题

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

答案:工程化是根据业务特点,将前端开发流程规范化,标准化,它包括了开发流程,技术选型,代码规范,构建发布等,用于提升前端工程师的开发效率和代码质量。

  1. 制定各项规范,编码规范,开发流程规范,前后端接口规范等等
  2. 使用版本控制工具 git,commit描述规范
  3. 使用合适前端技术和框架,提高生产效率,降低维护难度,采用模块化,组件化,数据分离等
  4. 代码可测试,单元测试,端到端测试等
  5. 开发部署自动化
2、你认为脚手架除了为我们创建项目结构,还有什么更深的意义?

编程题

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

说明:实现了创建不同主题的,选择不同内容的静态应用

//cli.js 参考
#!/usr/bin/env 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?'
  },
  {
    type: 'list',
    name: 'theme',
    message: 'Select the theme color',
    choices: ['Dark', 'Light'],
    filter: function (val) {
      return val.toLowerCase();
    },
  },
  {
    type: 'checkbox',
    message: 'Select what to include',
    name: 'content',
    choices: [
      {
        name: 'Header',
      },
      {
        name: 'Body',
      },
      {
        name: 'Footer',
      },
    ],
    validate: function (answer) {
      if (answer.length < 1) {
        return 'You must choose at least one content.';
      }

      return true;
    },
  },
  
])
.then(anwsers => {
  const tmplDir = path.join(__dirname, 'templates')
  const destDir = process.cwd()

  fs.readdir(tmplDir, (err, files) => {
    if (err) throw err
    files.forEach(file => {
      ejs.renderFile(path.join(tmplDir, file), anwsers, (err, result) => {
        if (err) throw err

        fs.writeFileSync(path.join(destDir, file), result)
      })
    })
  })
})
2、尝试使用 Gulp 完成项目的自动化构建

​ 查找 gulp 插件:https://gulpjs.com/plugins/

  yarn lint
  yarn compile
  yarn serve
  yarn build
  yarn start
  yarn deploy
  yarn clean
  //并能实现一下 扩展参数命令
  yarn serve --port 5210 --open
//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 autoprefixer = require('autoprefixer');
const stylelint = require('stylelint');
const scss = require('postcss-scss');
const reporter = require('postcss-reporter');
const minimist = require('minimist');

const plugins = loadPlugins();
const bs = browserSync.create();
const cwd = process.cwd();

const args = minimist(process.argv.slice(2));

const isProd = process.env.NODE_ENV ? process.env.NODE_ENV === 'production' : args.production || args.prod || false;

const bsInit = {
  notify: false,
  port: args.port || 2080,
  open: args.open || false,
};

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/**/*.{jpg,jpeg,png,gif,svg}',
      fonts: 'assets/fonts/**/*.{eot,svg,ttf,woff,woff2}',
    },
  },
};

try {
  const loadConfig = require(`${cwd}/pages.config.js`);
  config = { ...config, ...loadConfig };
} catch (e) { }

const clean = () => del([config.build.dist, config.build.temp]);

const style = () => src(config.build.paths.styles, { base: config.build.src, cwd: config.build.src, sourcemaps: !isProd })
  .pipe(plugins.sass({ outputStyle: 'expanded' }))
  .pipe(plugins.postcss([
    autoprefixer(),
  ]))
  .pipe(dest(config.build.temp, { sourcemaps: '.' }))
  .pipe(bs.reload({ stream: true }));

const stylesLint = () => src(config.build.paths.styles, { base: config.build.src, cwd: config.build.src })
  .pipe(plugins.postcss([
    stylelint({ fix: args.fix }),
    reporter(),
  ], { syntax: scss }));

const script = () => src(config.build.paths.scripts, {
  base: config.build.src, cwd: config.build.src, sourcemaps: !isProd,
})
  .pipe(plugins.babel({ presets: [require('@babel/preset-env')] }))
  .pipe(dest(config.build.temp, { sourcemaps: '.' }))
  .pipe(bs.reload({ stream: true }));

const scriptsLint = () => src(config.build.paths.scripts, {
  base: config.build.src, cwd: config.build.src,
})
  .pipe(plugins.eslint({ fix: args.fix }))
  .pipe(plugins.eslint.format())
  .pipe(plugins.eslint.failAfterError());

const page = () => src(config.build.paths.pages, {
  base: config.build.src, cwd: config.build.src, ignore: ['{layouts,partials}/**'],
})
  .pipe(plugins.swig({ data: config.data, defaults: { cache: false } }))
  .pipe(dest(config.build.temp))
  .pipe(bs.reload({ stream: true }));

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

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

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

const devServe = () => {
  watch(config.build.paths.styles, { cwd: config.build.src }, style);
  watch(config.build.paths.scripts, { cwd: config.build.src }, script);
  watch(config.build.paths.pages, { cwd: config.build.src }, page);

  watch([
    config.build.paths.images,
    config.build.paths.fonts,
  ], { cwd: config.build.src }, bs.reload);

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

  bs.init({
    ...bsInit,
    server: {
      baseDir: [config.build.temp, config.build.dist, config.build.public, config.build.src],
      routes: {
        '/node_modules': 'node_modules',
      },
    },
  });
};

const prodServe = () => {
  bs.init({
    ...bsInit,
    server: {
      baseDir: config.build.dist,
    },
  });
};

const useref = () => src(
  config.build.paths.pages,
  { base: config.build.temp, cwd: config.build.temp },
)
  .pipe(plugins.useref({ searchPath: [config.build.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(config.build.dist));

const publish = () => src('**', { base: config.build.dist, cwd: config.build.dist })
  // .pipe(plugins.gzip())
  .pipe(plugins.ghPages());

const lint = parallel(stylesLint, scriptsLint);

const compile = parallel(style, script, page);

// 上线之前执行的任务
const build = series(
  clean,
  parallel(
    series(compile, useref),
    image,
    font,
    extra,
  ),
);

const serve = series(compile, devServe);

const start = series(build, prodServe);

const deploy = series(build, publish);

module.exports = {
  clean,
  lint,
  compile,
  serve,
  build,
  start,
  deploy,
};
3、使用 Grunt 完成项目的自动化构建

说明:

​ 查找 grunt 插件:https://www.gruntjs.net/plugins

​```javascript
//gruntfile.js 参考配置
const path = require('path');
const sass = require('sass');

const del = require('del');
const browserSync = require('browser-sync');

const loadGruntTasks = require('load-grunt-tasks');
const autoprefixer = require('autoprefixer');
const stylelint = require('stylelint');
const scss = require('postcss-scss');
const reporter = require('postcss-reporter');
const minimist = require('minimist');

const bs = browserSync.create();
const cwd = process.cwd();

const args = minimist(process.argv.slice(2));

const isProd = process.env.NODE_ENV ? process.env.NODE_ENV === 'production' : args.production || args.prod || false;

const bsInit = {
notify: false,
port: args.port || 2080,
open: args.open || false,
};

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/
/.{jpg,jpeg,png,gif,svg}',
fonts: 'assets/fonts/*/.{eot,svg,ttf,woff,woff2}',
},
},
};

try {
const loadConfig = require(${cwd}/pages.config.js);
config = { ...config, ...loadConfig };
} catch (e) { }

module.exports = (grunt) => {
grunt.initConfig({
sass: {
options: {
sourceMap: !isProd,
implementation: sass,
outputStyle: 'expanded',
},
main: {
expand: true,
cwd: config.build.src,
src: [config.build.paths.styles],
dest: config.build.temp,
ext: '.css',
},
},
postcss: {
main: {
options: {
processors: [
autoprefixer(),
],
},
expand: true,
cwd: config.build.temp,
src: ['assets/styles/*/.css'],
dest: config.build.temp,
},

  lint: {
    options: {
      processors: [
        stylelint({ fix: args.fix }),
        reporter(),
      ],
    },
    src: `${path.join(config.build.src, config.build.paths.styles)}`,
  },
},

eslint: {
  options: {
    fix: args.fix,
  },
  main: `${path.join(config.build.src, config.build.paths.scripts)}`,
},
babel: {
  options: {
    sourceMap: !isProd,
    presets: ['@babel/preset-env'],
  },
  main: {
    expand: true,
    cwd: config.build.src,
    src: [config.build.paths.scripts],
    dest: config.build.temp,
    ext: '.js',
  },
},
html_template: {
  options: {
    cache: false,
    locals: config.data,
  },
  main: {
    expand: true,
    cwd: config.build.src,
    src: [config.build.paths.pages, '!layouts/**', '!partials/**'],
    dest: config.build.temp,
    ext: '.html',
  },
},
imagemin: {
  image: {
    expand: true,
    cwd: config.build.src,
    src: [config.build.paths.images],
    dest: config.build.dist,
  },
  font: {
    expand: true,
    cwd: config.build.src,
    src: [config.build.paths.fonts],
    dest: config.build.dist,
  },
},
copy: {
  main: {
    expand: true,
    cwd: config.build.public,
    src: ['**'],
    dest: config.build.dist,
  },
  html: {
    expand: true,
    cwd: config.build.temp,
    src: [config.build.paths.pages],
    dest: config.build.dist,
  },
},
useminPrepare: {
  main: {
    expand: true,
    cwd: config.build.temp,
    src: [config.build.paths.pages],
  },
  options: {
    dest: config.build.dist,
    root: [config.build.temp, '.', '..'],
  },
},

usemin: {
  main: {
    expand: true,
    cwd: config.build.dist,
    src: [config.build.paths.pages],
  },
  options: {

  },
},
'gh-pages': {
  options: {
    base: config.build.dist,
    branch: 'gh-pages-grunt',
  },
  main: ['**'],
},
watch: {
  script: {
    files: [`${path.join(config.build.src, config.build.paths.scripts)}`],
    tasks: ['babel'],
  },
  style: {
    files: [`${path.join(config.build.src, config.build.paths.styles)}`],
    tasks: ['style'],
  },
  page: {
    files: [`${path.join(config.build.src, config.build.paths.pages)}`],
    tasks: ['html_template'],
  },
},
browserSync: {
  dev: {
    bsFiles: {
      src: [
        config.build.temp,
        config.build.dist,
      ],
    },
    options: {
      ...bsInit,
      watchTask: true,
      server: {
        baseDir: [config.build.temp, config.build.dist, config.build.public, config.build.src],
        routes: {
          '/node_modules': 'node_modules',
        },
      },
    },
  },
  prod: {
    bsFiles: {
      src: config.build.dist,
    },
    options: {
      ...bsInit,
      server: {
        baseDir: config.build.dist,
      },
    },
  },
},

});

loadGruntTasks(grunt);

grunt.registerTask('reload', () => {
bs.reload();
});

grunt.registerTask('stylesLint', []);

grunt.registerTask('scriptsLint', []);

grunt.registerTask('clean', () => {
del.sync([config.build.dist, config.build.temp, '.tmp']);
});

grunt.registerTask('style', ['sass', 'postcss:main']);

grunt.registerTask('compile', ['style', 'babel', 'html_template']);

grunt.registerTask('build', [
'clean',
'compile',
'copy',
'useminPrepare',
'concat:generated',
'cssmin:generated',
'uglify:generated',
'usemin',
'imagemin',
]);

grunt.registerTask('serve', ['compile', 'browserSync:dev', 'watch']);

grunt.registerTask('start', ['build', 'browserSync:prod']);

grunt.registerTask('deploy', ['build', 'gh-pages']);

grunt.registerTask('lint', ['postcss:lint', 'eslint']);
};


上一篇下一篇

猜你喜欢

热点阅读