簡答題
1.談談你多工程化的初步認識,結合你之前遇到過的問題說出三個以上工程化能夠解決問題或者帶來的價值午笛。
解:
??????工程化指的是在遵循一定標準和規(guī)范的基礎上府怯,通過使用工具來提高效率煎饼,降低成本的一種手段;工程化不等于某種工具谤专,一切以提高效率躁锡、降低成本和質(zhì)量保證為目的的手段都稱之為工程化。
解決的問題:
??????1.無法使用模塊化/組件化組織代碼
??????2.代碼風格統(tǒng)一置侍,使得項目多人協(xié)作開發(fā)稚铣,質(zhì)量得以保證
??????3.部分功能需要等待后端服務接口完成以后才可以進行開發(fā)
??????4.重復的機械工作,比如部署上線前需要手動壓縮代碼及資源文件墅垮,部署過程需要手動上傳代碼到服務器惕医。
帶來的價值:
??????1.壓縮圖片大小,使得請求圖片時間降低
??????2.代碼合并壓縮算色,減少項目整體體積
2.你認為腳手架除了為我們創(chuàng)建項目結構抬伺,還有什么更深的意義。
解:
??????腳手架的本質(zhì)作用除了為我們創(chuàng)建項目結構灾梦,還為我們提供了項目規(guī)范和約定峡钓。腳手架創(chuàng)建的項目包含相同的組織結構、相同的開發(fā)范式若河、相同的模塊依賴能岩、相同的工程配置以及相同的基礎代碼。腳手架作為一種創(chuàng)建項目初始文件的工具被廣泛地應用于新項目或迭代初始階段萧福。使用工具代替人工操作能夠避免人為失誤引起的低級錯誤拉鹃,同時結合整體前端工程化方案,快速生成功能模塊配置、自動安裝依賴等膏燕,優(yōu)化了時間成本钥屈。在公司中使用同一套腳手架工具創(chuàng)建的項目,使得項目成員更換時坝辫,能夠馬上上手篷就,提高開發(fā)效率。
編程題
1.概述腳手架是實現(xiàn)的過程近忙,并使用NodeJS完成一個自定義的小型腳手架工具竭业。
解:
??????實現(xiàn):
??????1.創(chuàng)建一個新的倉庫目錄:small-node-js
??????2.通過yarn init --yes初始化項目并生成package.json文件
??????3.創(chuàng)建cli.js文件,并將其路徑添加到package.json中bin對應的值
{
"name": "small-node-js",
"version": "1.0.0",
"main": "index.js",
"bin": "lib/cli.js",
"license": "MIT",
"devDependencies": {},
"dependencies": {
"ejs": "^3.1.3",
"inquirer": "^7.3.3"
}
}
??????4.編寫cli.js中的內(nèi)容
#!/usr/bin/env node
// Node CLI 應用入口文件必須要有這樣的文件頭
// 如果Linux 或者 Mac 系統(tǒng)下及舍,還需要修改此文件權限為755: chmod 755 cli.js
// 腳手架工作過程:
// 1. 通過命令行交互詢問用戶問題
// 2. 根據(jù)用戶回答的結果生成文件
const path = require('path')
const fs = require('fs') // 讀取文件
const inquirer = require('inquirer') // 發(fā)起命令行交互詢問
const ejs = require('ejs') // 模板引擎
inquirer.prompt([
{
type: 'input',
name: 'title',
message: 'Project name?'
},
{
type: 'input',
name: 'name',
message: 'your name?'
},
{
type: 'input',
name: 'age',
message: 'your age?'
},
]).then(answer => {
// 模板目錄
const tempDir = path.join(__dirname, 'templates')
// 目標目錄 --當前文件夾路徑
const destDir = process.cwd()
// 將模板下的文件全部轉換到目標目錄
fs.readdir(tempDir, (err, files) => {
if (err) throw err
files.forEach(file => {
// 通過模板引擎渲染文件
ejs.renderFile(path.join(tempDir, file), answer, (err, result) => {
if(err) throw err
// 將結果寫入到目標目錄
fs.writeFileSync(path.join(destDir, file), result)
})
})
})
})
??????5.創(chuàng)建模板文件index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><%= title %></title>
</head>
<body>
<p><%= name %></p>
<p><%= age %></p>
</body>
</html>
??????6.執(zhí)行yarn link命令將該cli程序link到全局
??????7.在命令行中執(zhí)行small-node-js未辆,,并根據(jù)提示輸入相應的值,則會在項目根目錄下創(chuàng)建由該模板生成的index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>nodejs</title>
</head>
<body>
<p>Tom</p>
<p>18</p>
</body>
</html>
2.嘗試使用Gulp完成項目的自動化構建击纬。
視頻地址:Gulp腳手架-項目自動化構建
Gulp講解:
- gulpfile.js
// 實現(xiàn)這個項目的構建任務
//導入 gulp 下需要使用到的庫
const { src, dest, parallel, series, watch} = require('gulp')
const del = require('del')
// 自動加載插件
const loadPlugins = require('gulp-load-plugins')
const plugins = loadPlugins()
const {sass, babel, swig, imagemin, uglify, cleanCss, htmlmin} = plugins
// 提供開發(fā)服務器,在代碼修改后能夠熱更新
const browserSync = require('browser-sync')
const bs = browserSync.create()
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(sass({outputStyle: 'expanded'}))
.pipe(dest('temp'))
.pipe(bs.reload({stream: true}))
}
// 腳本編譯
const script = () => {
return src('src/assets/scripts/*.js', { base: 'src'})
.pipe(babel({presets: ['@babel/preset-env']}))
.pipe(dest('temp'))
.pipe(bs.reload({stream: true}))
}
// 模板編譯
const page = () => {
return src('src/*.html', { base: 'src'})
.pipe(swig({data, defaults: {cache: false}})) // 防止模板緩存導致頁面不能及時更新
.pipe(dest('temp'))
.pipe(bs.reload({stream: true}))
}
// 圖片壓縮
const image = () => {
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'))
}
// 額外的編譯:public
const extra = () => {
return src('public/**', {base: 'public'})
.pipe(dest('dist'))
}
// 開發(fā)服務器
const server = () => {
// 監(jiān)視文件钾麸,決定是否要執(zhí)行任務
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,
// files:'dist/**',
server: {
baseDir:['temp', 'src', 'public'],//圖片只是壓縮了更振,請求dist和src上并無區(qū)別,只是進行壓縮了下饭尝,這里讓他請求原文件肯腕,減少了一次構建,提高開發(fā)效率
routes:{
'/node_modules' : 'node_modules'
}
}
})
}
// 文件引用處理---合并
const useref = () => {
return src('temp/*.html',{base: 'temp'})
.pipe(plugins.useref({searchPath: ['temp','.']}))
.pipe(plugins.if(/\.js$/,uglify()))
.pipe(plugins.if(/\.css$/,cleanCss()))
.pipe(plugins.if(/\.html$/,htmlmin({
collapseWhitespace: true, // 折疊空白字符和換行符
minifyCSS: true, // 樣式壓縮
minefyJS: true // 腳本壓縮
})))
.pipe(dest('dist'))
}
// 編譯任務
const compile = parallel(style, script, page)
// 完成所有文件的編譯 上線之前執(zhí)行的任務
const build = series(
clean,
parallel(
series(compile, useref),
image,
font,
extra
)
)
// 開發(fā)任務
const develop = series(compile, server)
module.exports = {
build,
develop,
compile,
}
/**
* 運行命令
* yarn gulp build
* yarn gulp develop
* yarn gulp compile
*/
- pacjage.json
{
"name": "pages-boilerplate",
"version": "0.1.0",
"private": true,
"description": "Always a pleasure scaffolding your awesome static sites.",
"keywords": [
"pages-boilerplate",
"boilerplate",
"pages",
"zce"
],
"homepage": "https://github.com/zce/pages-boilerplate#readme",
"bugs": {
"url": "https://github.com/zce/pages-boilerplate/issues"
},
"repository": {
"type": "git",
"url": "git+https://github.com/zce/pages-boilerplate.git"
},
"license": "MIT",
"author": {
"name": "zce",
"email": "w@zce.me",
"url": "https://zce.me"
},
"scripts": {
"clean": "gulp clean",
"lint": "gulp lint",
"serve": "gulp serve",
"build": "gulp build",
"start": "gulp start",
"deploy": "gulp deploy --production"
},
"browserslist": [
"last 1 version",
"> 1%",
"maintained node versions",
"not dead"
],
"dependencies": {
"bootstrap": "4.4.1",
"jquery": "3.4.1",
"popper.js": "1.16.1"
},
"devDependencies": {
"@babel/core": "^7.11.1",
"@babel/preset-env": "^7.11.0",
"browser-sync": "^2.26.12",
"del": "^5.1.0",
"gulp": "^4.0.2",
"gulp-babel": "^8.0.0",
"gulp-clean-css": "^4.3.0",
"gulp-htmlmin": "^5.0.1",
"gulp-if": "^3.0.0",
"gulp-imagemin": "^7.1.0",
"gulp-load-plugins": "^2.0.3",
"gulp-sass": "^4.1.0",
"gulp-swig": "^0.9.1",
"gulp-uglify": "^3.0.2",
"gulp-useref": "^4.0.1"
},
"engines": {
"node": ">=6"
}
}
3.使用Grunt完成項目的自動化構建钥平。
未完待續(xù)实撒。。涉瘾。知态。。