溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

怎么使用yeoman打造自己的項目腳手架

發(fā)布時間:2023-03-09 10:28:19 來源:億速云 閱讀:148 作者:iii 欄目:開發(fā)技術(shù)

本篇內(nèi)容主要講解“怎么使用yeoman打造自己的項目腳手架”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學(xué)習(xí)“怎么使用yeoman打造自己的項目腳手架”吧!

yeoman 介紹

Yeoman 是一個通用的腳手架系統(tǒng),允許創(chuàng)建任何類型的應(yīng)用程序(Web,Java,Python,C#等)。用 yeoman 寫腳手架非常簡單, yeoman 提供了 yeoman-generator 讓我們快速生成一個腳手架模板,我們的主要工作就是把模板文件寫好?,F(xiàn)在我們來用 yeoman 寫一個生成 javascript 插件的腳手架吧。

腳手架功能:

  • 自動構(gòu)建編譯和打包

  • 支持 es6 語法

  • 支持單元測試

  • 支持 jsdoc 生成文檔

  • 支持 eslint 語法檢查

  • 自動生成 changelog

準(zhǔn)備工作

首先需要全局安裝 yo 和 generator-generator

npm install yo -g
npm install generator-generator -g

生成腳手架模板

yo generator

怎么使用yeoman打造自己的項目腳手架

在這個終端界面里輸入項目名、描述等項目信息。注意項目名稱要寫成generator-xxx的格式,這樣用戶就可以通過yo xxx安裝你的腳手架了。

生成的腳手架模板目錄結(jié)構(gòu)如下:

.
├── generators/
│   └── app/
│       ├── index.js
│       └── templates/
│           └── dummyfile.txt
├── .editorconfig
├── .eslintignore
├── .gitattributes
├── .gitignore
├── .travis.yml
├── .yo-rc.json
├── LICENSE
├── README.md
├── package.json
└── __tests__/
    └── app.js

接下來我們就在generators/app/index.js里寫腳手架的邏輯。

編寫自己的腳手架

腳手架所做的事情:

  • 接收用戶輸入

  • 根據(jù)用戶輸入生成模板文件

  • 將模板文件拷貝到目標(biāo)目錄(通常是用戶運行腳手架的目錄)

  • 安裝依賴

yeoman 提供了一個基本生成器,你可以擴展它以實現(xiàn)自己的行為。這個基礎(chǔ)生成器將幫你減輕大部分工作量。在生成器的 index.js 文件中,以下是擴展基本生成器的方法:

var Generator = require("yeoman-generator");
module.exports = class extends Generator {};

yeoman 生命周期函數(shù)執(zhí)行順序如下:

  • initializing - 初始化函數(shù)

  • prompting - 接收用戶輸入階段

  • configuring - 保存配置信息和文件

  • default - 執(zhí)行自定義函數(shù)

  • writing - 生成項目目錄結(jié)構(gòu)階段

  • conflicts - 統(tǒng)一處理沖突,如要生成的文件已經(jīng)存在是否覆蓋等處理

  • install - 安裝依賴階段

  • end - 生成器結(jié)束階段

我們常用的就是 initializing、prompting、default、writing、install 這四種生命周期函數(shù)。看下例子:

"use strict";
const Generator = require("yeoman-generator");
const chalk = require("chalk"); // 讓console.log帶顏色輸出
const yosay = require("yosay");
const mkdirp = require("mkdirp"); // 創(chuàng)建目錄
module.exports = class extends Generator {
  initializing() {
    this.props = {};
  }
  // 接受用戶輸入
  prompting() {
    // Have Yeoman greet the user.
    this.log(
      yosay(
        `Welcome to the grand ${chalk.red(
          "generator-javascript-plugin"
        )} generator!`
      )
    );
    const prompts = [
      {
        type: "confirm",
        name: "someAnswer",
        message: "Would you like to enable this option?",
        default: true
      }
    ];
    return this.prompt(prompts).then(props => {
      // To access props later use this.props.someAnswer;
      this.props = props;
    });
  }
  // 創(chuàng)建項目目錄
  default() {
    if (path.basename(this.destinationPath()) !== this.props.name) {
      this.log(`\nYour generator must be inside a folder named
        ${this.props.name}\n
        I will automatically create this folder.\n`);
      mkdirp(this.props.name);
      this.destinationRoot(this.destinationPath(this.props.name));
    }
  }
  // 寫文件
  writing() {
    // 將templates目錄的代碼拷貝到目標(biāo)目錄
    // templates目錄默認(rèn)路徑是generators/app/templates
    this.fs.copy(
      this.templatePath("dummyfile.txt"),
      this.destinationPath("dummyfile.txt")
    );
    this._writingPackageJSON();
  }
  // 以下劃線_開頭的是私有方法
  _writingPackageJSON() {
    // this.fs.copyTpl(from, to, context)
    this.fs.copyTpl(
      this.templatePath("_package.json"),
      this.destinationPath("package.json"),
      {
        name: this.props.name,
        description: this.props.description,
        keywords: this.props.keywords.split(","),
        author: this.props.author,
        email: this.props.email,
        repository: this.props.repository,
        homepage: this.props.homepage,
        license: this.props.license
      }
    );
  }
  // 安裝依賴
  install() {
    this.installDependencies();
  }
};

編寫模板代碼

前面我們把一個腳手架的基本框架都寫好了,它可以接受用戶輸入的內(nèi)容,可以寫文件,可以安裝依賴,但接收用戶輸入的數(shù)據(jù)怎么用?寫進什么文件?安裝什么依賴呢?這些都是模板文件做的事情?,F(xiàn)在就開始最主要的一部分:編寫模板文件。

模板文件是你為用戶生成的一個項目 demo,讓用戶看著這些示例代碼就可以開工了,用戶應(yīng)該只需要專注于業(yè)務(wù)邏輯,而不用管打包構(gòu)建這些事。

首先建好模板目錄:

├── .editorconfig
├── .eslintignore
├── .eslintrc.js
├── .gitignore
├── .babelrc
├── jsdoc.json
├── README.md
├── package.json
├── build/
    └── rollup.js
├── src/
    └── index.js
├── test/
    └── index.js

我們的模板package.json里已經(jīng)寫好這些命令:

"scripts": {
  "prebuild": "npm run lint && npm run test && npm run doc",
  "build": "node ./build/rollup.js",
  "lint": "eslint --ext .js, src",
  "test": "mocha --require babel-register --require babel-polyfill --bail",
  "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s",
  "doc": "jsdoc -c ./jsdoc.json"
}
  • npm run lint 用 eslint 進行語法檢查,在編譯前就避免語法錯誤和統(tǒng)一代碼風(fēng)格。

  • npm test 運行單元測試

  • npm run doc 根據(jù)注釋生成文檔

  • npm run changelog 根據(jù)git log生成項目日志,改動記錄一目了然

  • npm run prebuild 編譯前的語法檢查、 運行測試、生成文檔

  • npm run build 編譯打包

我們可以使用<%= name %>這樣的模板語法使用腳手架中的context上下文,無論是用戶輸入的數(shù)據(jù),還是程序自己的變量:

{
  "name": "<%= name %>",
  "description": "<%= description %>",
  "version": "1.0.0",
  "private": false,
  "main": "dist/<%= name %>.umd.js",
  "module": "dist/<%= name %>.es.js"
}

詳細(xì)代碼請到github查看。

運行測試用例

為了保證代碼的健壯性,我們必須進行單元測試。其實我們用generator生成的腳手架代碼中已經(jīng)有測試代碼示例了,改成自己的邏輯就可以測試我們的腳手架邏輯了?,F(xiàn)在我們來測試下文件是否生成:

'use strict';
const path = require('path');
const assert = require('yeoman-assert');
const helpers = require('yeoman-test');
describe('generator-javascript-plugin:app', () => {
  beforeAll(() => {
    return helpers
      .run(path.join(__dirname, '../generators/app'))
      .withPrompts({ someAnswer: true });
  });
  it('creates files', () => {
    assert.file(['build/rollup.js']);
    assert.file(['dist']);
    assert.file(['src']);
    assert.file(['test']);
    assert.file(['package.json']);
    assert.file(['.babelrc']);
    ...
  });
});

執(zhí)行命令

npm test

運行腳手架

到此,我們的腳手架開發(fā)完了,接下來實際運行下看看是否正確。

由于我們的腳手架還是本地開發(fā),它尚未作為全局 npm 模塊提供。我們可以使用 npm 創(chuàng)建全局模塊并將其符號鏈接到本地模塊。在項目根目錄運行:

npm link

這樣就可以調(diào)用yo javascript-plugin運行腳手架了。你可以在終端看到運行過程。

到此,相信大家對“怎么使用yeoman打造自己的項目腳手架”有了更深的了解,不妨來實際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進入相關(guān)頻道進行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI