前端工程化

為何工程化

在我們的實際開發(fā)中刀荒,我們想用最新的es語法代嗤,想用less,sass等樣式預處理。我們想要使用模塊化的方式提高項目的可維護性缠借,但是運行環(huán)境卻不支持干毅。多人協(xié)作,代碼風格不統(tǒng)一泼返。發(fā)布上線需要手動壓縮與上傳硝逢,這些問題的出現(xiàn)需要我們去有一種方式去解決這些問題。工程化就是解決這些問題的一個體現(xiàn)绅喉。

工程化的體現(xiàn)

一切以提高效率渠鸽,降低成本,質量保證為目的的手段都屬于工程化柴罐。
一些成熟的工程化集成 如vue-cli , angular-cli , create-react-app
前端工程化的實現(xiàn) nodejs有巨大貢獻徽缚。

腳手架工具yeoman的使用

1.全局安裝yo

cnpm i yo -g //或者 yarn global add yo

2.安裝對應的generator

npm i generator-node -g //或者 yarn global add generator-node

3.通過yo運行generator

yo node
yeoman的sub generator使用

1.明確需求。
2.找到合適的Generator革屠。
3.全局范圍安裝找到的Generator凿试。
4.通過yo安裝找到的Generator。
5.通過命令交互填寫選項似芝。
6.生成所需要的項目結構那婉。

自定義Generator

基于yeoman搭建自己的腳手架
1.創(chuàng)建Generator模塊(generator本質上就是一個NPM模塊)


圖片.png

yeoman的generator模塊名稱必須是 generator-<name>

mkdir generator-sample //創(chuàng)建文件
cd generator-sample 
yarn init //初始化
yarn add yeoman-generator //安裝基類 提供了一些方法

按照格式創(chuàng)建


圖片.png
//作為generator核心入口
//需要導出一個繼承自 yeoman generator的類型
//yeoman generator  在工作時會自動調用我們在此類型中定義的一些聲明周期方法
//在這些方法中可以通過調用父類提供的一些工具方法實現(xiàn)一些功能  比如文件寫入

const Generator = require('yeoman-generator')

module.exports = class extends Generator {
  writing() {
    //yoman 自動在生成文件階段調用此方法
    //我們在這里嘗試往項目目錄中寫入文件
    // this.fs.write(
    //   this.destinationPath('test.txt'),
    //   Math.random().toString()
    // )

    //通過模板方式寫入文件到目標目錄
    //三個參數(shù) 1.模板文件路徑 2.輸出文件路徑 3.模板數(shù)據(jù)上下文
    const tmpl = this.templatePath('foo.txt')//模板文件路徑
    const output = this.destinationPath('foo.txt')//模板文件路徑
    const context = { title: 'hello tem', success: true }//模板數(shù)據(jù)上下文
    this.fs.copyTpl(tmpl, output, context)
  }
}

通過yarn link鏈接到全局范圍 使其成為一個全局模塊包

yarn link

在其它地方就可以運行這個生成器

yo sample //剛才起的生成器名稱

創(chuàng)建一個自己的vue Generator

mkdir generator-my-vue
cd generator-my-vue
yarn init
yarn add yeoman-generator
code . //vscode 打開文件

1.還是先創(chuàng)建模板文件


圖片.png

2.寫模板代碼

const Generator = require('yeoman-generator')

module.exports = class extends Generator{
  prompting(){
    return this.prompt([
      {
        type:'input',
        name:'name',
        message:'your project name',
        default:this.appname
      }
    ])
    .then(answers => {
      this.answers = answers
    })
  }
  writing(){
    
  }
}

3.將項目結構放入template文件夾中


圖片.png

4.將項目結構可能發(fā)生變化的地方用模板語法替換 如:


圖片.png
  1. yarn link 到全局
    6.使用 yo my-vue 安裝到對應目錄

發(fā)布generator

//先創(chuàng)建一個本地的git倉庫
//先創(chuàng)建一個gitignore
echo node_modules > .gitignore
//初始化一個本地空倉庫
git init
//查看本地倉庫狀態(tài)
git status

git add .
//創(chuàng)建一次提交
git commit -m "initial commit"

//提交到遠端倉庫
//創(chuàng)建一個遠端新倉庫 gitee或者github
git remote add origin https://gitee.com/wkpkko/generator-myvue.git
//這樣為本地倉庫添加了一個遠端倉庫的別名 push的時候可以使用這個別名
git push -u origin master //推送到遠端倉庫
//通過npm publish 發(fā)布這個模塊  yarn publish 
yarn publish
//在使用淘寶鏡像發(fā)布時會出現(xiàn)問題
//發(fā)布的時候設置鏡像
yarn publish --registry=https://registry.yarnpkg.com
//自動推送到y(tǒng)arn的官方鏡像  yarn的鏡像與npm鏡像時同步的  此時模塊發(fā)布成功了

//在npm官網(wǎng)  npmjs.com/package/generator-myvue 
//此時模塊已經(jīng)被推送上來了

Plop一個小而美的腳手架工具

主要用于創(chuàng)建項目中特定類型文件的一個小工具,類似與yeoman中的subgeneraor,一般不會單獨使用国觉。一般會把plop集成在項目中吧恃,用來自動化創(chuàng)建同類型的項目文件

yarn add plop --dev

在項目根目錄下創(chuàng)建plopfile.js

// Plop 入口文件,需要導出一個函數(shù)
// 此函數(shù)接收一個 plop 對象麻诀,用于創(chuàng)建生成器任務

module.exports = plop => {
  plop.setGenerator('component', {
    description: 'create a component',
    prompts: [
      {
        type: 'input',
        name: 'name',
        message: 'component name',
        default: 'MyComponent'
      }
    ],
    actions: [
      {
        type: 'add', // 代表添加文件
        path: 'src/components/{{name}}/{{name}}.js',
        templateFile: 'plop-templates/component.hbs'
      },
      {
        type: 'add', // 代表添加文件
        path: 'src/components/{{name}}/{{name}}.css',
        templateFile: 'plop-templates/component.css.hbs'
      },
      {
        type: 'add', // 代表添加文件
        path: 'src/components/{{name}}/{{name}}.test.js',
        templateFile: 'plop-templates/component.test.hbs'
      }
    ]
  })
}

創(chuàng)建模板文件
plop-templates/component.hbs

import React from 'react';

export default () => (
  <div className="{{name}}">
    <h1>{{name}} Component</h1>
  </div>
)

component.css.hbs

.{{name}} {
  
}

component.test.hbs

import React from 'react';
import ReactDOM from 'react-dom';
import {{name}} from './{{name}}';

it('renders without crashing', () => {
  const div = document.createElement('div');
  ReactDOM.render(<{{name}} />, div);
  ReactDOM.unmountComponentAtNode(div);
});

yarn plop component (剛才定義的生成器的名稱)

腳手架工作原理

大部分腳手架都是設置一些問題痕寓,通過這些問題為你創(chuàng)建一些模板的項目結構。
腳手架工具就是一個nodecli應用蝇闭。
通過nodejs開發(fā)一個小型的腳手架工具

mkdir sample-cli
cd sample-cli
yarn init//初始化一個package.json文件

//package.json中添加bin字段作為cli的入口文件
{
  "name": "sample-cli",
  "version": "1.0.0",
  "description": "sample cli",
  "bin":"cli.js",
  "main": "index.js",
  "license": "MIT"
}

創(chuàng)建cli.js
cli文件必須要有一個特定的文件頭

#!/usr/bin/env node

// Node CLI 應用入口文件必須要有這樣的文件頭
// 如果是 Linux 或者 macOS 系統(tǒng)下還需要修改此文件的讀寫權限為 755
// 具體就是通過 chmod 755 cli.js 實現(xiàn)修改
console.log('sample cli')

通過yarn link 鏈接到全局
此時就可以使用sample-cli命令執(zhí)行


圖片.png
// 腳手架的工作過程:
// 1. 通過命令行交互詢問用戶問題
// 2. 根據(jù)用戶回答的結果生成文件

node通過用戶詢問 我們使用inquirer模塊

yarn add inquirer
此時我們可以在cli.js載入它

const inquirer = require('inquirer')
inquirer.prompt([
  {
    type: 'input',
    name: 'name',
    message: 'Project name?'
  }
]).then(answer => {
  console.log(answer)
})
圖片.png

創(chuàng)建模板文件


圖片.png
#!/usr/bin/env node

// Node CLI 應用入口文件必須要有這樣的文件頭
// 如果是 Linux 或者 macOS 系統(tǒng)下還需要修改此文件的讀寫權限為 755
// 具體就是通過 chmod 755 cli.js 實現(xiàn)修改

//腳手架的工作過程
//1.通過命令行交互詢問用戶問題
//2.根據(jù)用戶回答的結果生成文件
const path = require('path')
const fs = require('fs')
const inquirer = require('inquirer')

inquirer.prompt([
  {
    type: 'input',
    name: 'name',
    message: 'Project name?'
  }
]).then(answer => {
  //根據(jù)用戶回答結果生成文件

  //模板目錄
  const templDir = path.join(__dirname,'templates')
  //輸出目錄 命令行執(zhí)行路徑
  const destDir = process.cwd()
  //將模板下的文件全部轉換到目錄 fs的readdir方法會自動掃描目錄下所有文件
  fs.readdir(templDir,(err,files) => { //files拿到所有文件列表
    if(err) throw err
    files.forEach(file => {
      // console.log(file) //每個file就是相對于templates下的相對路徑
      //可以通過模板引擎去渲染這個路徑所對應的文件
      
    })
  })

})

先安裝對應的模板引擎 (安裝一個ejs模板引擎)

yarn add ejs
之后引入模板引擎

#!/usr/bin/env node

// Node CLI 應用入口文件必須要有這樣的文件頭
// 如果是 Linux 或者 macOS 系統(tǒng)下還需要修改此文件的讀寫權限為 755
// 具體就是通過 chmod 755 cli.js 實現(xiàn)修改

//腳手架的工作過程
//1.通過命令行交互詢問用戶問題
//2.根據(jù)用戶回答的結果生成文件
const path = require('path')
const fs = require('fs')
const inquirer = require('inquirer')
const ejs = require('ejs')

inquirer.prompt([
  {
    type: 'input',
    name: 'name',
    message: 'Project name?'
  }
]).then(answer => {
  //根據(jù)用戶回答結果生成文件

  //模板目錄
  const templDir = path.join(__dirname, 'templates')
  //輸出目錄 命令行執(zhí)行路徑
  const destDir = process.cwd()
  //將模板下的文件全部轉換到目錄 fs的readdir方法會自動掃描目錄下所有文件
  fs.readdir(templDir, (err, files) => { //files拿到所有文件列表
    if (err) throw err
    files.forEach(file => {
      // console.log(file) //每個file就是相對于templates下的相對路徑
      //可以通過模板引擎去渲染這個路徑所對應的文件
      //renderFile三個參數(shù) 1.文件的絕對路徑 2.工作時的數(shù)據(jù)上下文answer 3.回調函數(shù)
      ejs.renderFile(path.join(templDir, file), answer, (err, result) => {
        if (err) throw err
        //通過文件寫入寫入到目標目錄
        fs.writeFileSync(path.join(destDir, file), result)
      })
    })
  })

})

資料來源:拉勾教育-前端訓練營

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末呻率,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子呻引,更是在濱河造成了極大的恐慌礼仗,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,640評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異元践,居然都是意外死亡韭脊,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,254評論 3 395
  • 文/潘曉璐 我一進店門单旁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來沪羔,“玉大人,你說我怎么就攤上這事象浑∧枋危” “怎么了?”我有些...
    開封第一講書人閱讀 165,011評論 0 355
  • 文/不壞的土叔 我叫張陵愉豺,是天一觀的道長篓吁。 經(jīng)常有香客問我,道長蚪拦,這世上最難降的妖魔是什么杖剪? 我笑而不...
    開封第一講書人閱讀 58,755評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮外盯,結果婚禮上摘盆,老公的妹妹穿的比我還像新娘。我一直安慰自己饱苟,他們只是感情好孩擂,可當我...
    茶點故事閱讀 67,774評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著箱熬,像睡著了一般类垦。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上城须,一...
    開封第一講書人閱讀 51,610評論 1 305
  • 那天蚤认,我揣著相機與錄音,去河邊找鬼糕伐。 笑死砰琢,一個胖子當著我的面吹牛,可吹牛的內容都是我干的良瞧。 我是一名探鬼主播陪汽,決...
    沈念sama閱讀 40,352評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼褥蚯!你這毒婦竟也來了挚冤?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,257評論 0 276
  • 序言:老撾萬榮一對情侶失蹤赞庶,失蹤者是張志新(化名)和其女友劉穎训挡,沒想到半個月后澳骤,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,717評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡澜薄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,894評論 3 336
  • 正文 我和宋清朗相戀三年为肮,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片肤京。...
    茶點故事閱讀 40,021評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡弥锄,死狀恐怖,靈堂內的尸體忽然破棺而出蟆沫,到底是詐尸還是另有隱情,我是刑警寧澤温治,帶...
    沈念sama閱讀 35,735評論 5 346
  • 正文 年R本政府宣布饭庞,位于F島的核電站,受9級特大地震影響熬荆,放射性物質發(fā)生泄漏舟山。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,354評論 3 330
  • 文/蒙蒙 一卤恳、第九天 我趴在偏房一處隱蔽的房頂上張望累盗。 院中可真熱鬧,春花似錦突琳、人聲如沸若债。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,936評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蠢琳。三九已至,卻和暖如春镜豹,著一層夾襖步出監(jiān)牢的瞬間傲须,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,054評論 1 270
  • 我被黑心中介騙來泰國打工趟脂, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留泰讽,地道東北人。 一個月前我還...
    沈念sama閱讀 48,224評論 3 371
  • 正文 我出身青樓昔期,卻偏偏與公主長得像已卸,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子镇眷,可洞房花燭夜當晚...
    茶點故事閱讀 44,974評論 2 355

推薦閱讀更多精彩內容