使用yeoman-generator 構建自己的腳手架

yeoman-generator

?yeoman-generator是一個構建腳手架的工具,如果你還不了解你自行google到官網看下,這里只簡單介紹一下,它是一個腳手架生成工具,比如在之前寫 ASP.NET MVC 的時候,Visual Studio 會給你選模板,然后生成一個項目的基本結構(腳手架),這對提升開發體驗是很有幫助的,節省了重復勞動。然而前端沒有什么 IDE(WebStorm?或許吧),沒有一個固定的開發模式,可能你喜歡 jshint,我想用 eslint,你覺得 angular 順手,我覺得 vue 更合適,這時就可以使用 Yeoman 這個工具,生成一個適合自己技術棧的腳手架,需要的一些文件都預先生成好,給自己省點事

yeoman-generator的開發配置

環境準備

安裝或者更新一下你的node和npm

npm install -g n? //首先安裝n模塊

n stable? //升級node.js到最新穩定版

n 5.0.0? //或者指定版本升級

node -v? //檢查更新是否成功

然后安裝yeoman

npm install -g yo

創建目錄

新建一個名為generator-xxx(yeoman腳手架命名規范)的文件夾,我這里叫generator-vue-webpack。然后在目錄下執行npm init創建package.json文件。修改為

{

? ? ?"name":"generator-vue-webpack",

? ? ? "version":"1.0.0",

? ? ?"description":"vue2+webpack2腳手架",

? ? ? ?"main":"generators/index.js",

"scripts": {

? ? ? ? "test":"echo \"Error: no test specified\" && exit 1"

},

"files": [

? ? ? ?"generators"

],

"repository": {

? ? ? ? ? ? "type":"git",

? ? ? ? ? ? "url":"git+https://github.com/xiaoxinghug/generator-vuepackage.git"

},

"keywords": [

? ? ? ? ? "yeoman-generator"

],

"dependencies": {

? ? ? ? "deep-extend":"^0.4.1",

? ? ? ? ? "generator-license":"^3.1.1",

? ? ? ? ? ? ? "yeoman-generator":"^0.22.0",

? ? ? ? ? ?"chalk":"^1.1.3",

? ? ? ? ?"yosay":"^1.2.1",

? ? ? ? ? "lodash":"^4.11.1",

? ? ? ? ? ?"mkdirp":"^0.5.1"

},

"author":"chenxiaoxing",

"license":"ISC",

"bugs": {

? ? ? ? ? "url":"https://github.com/xiaoxinghug/generator-vuepackage/issues"

},

"homepage":"https://github.com/xiaoxinghug/generator-vuepackage#readme",

"license":"Apache-2.0"

}

然后在此目錄下新建generators->app->index.js,generators-app-templates,如下圖所示:



generator-reactpackage是整個npm包的項目文件夾

templates目錄里面就是我們最后要用到的項目模版文件,里面的內容是一個完整的前端項目,可以自定義。

index.js是開發腳手架的主要邏輯文件。

開始開發

然后編輯index.js文件:

const yeoman=require('yeoman-generator');

cons tpath=require('path');

const fs=require('fs');

const chalk=require('chalk');

const yosay=require('yosay');

const _=require('lodash');

const extend=require('deep-extend');

const utils=require('./utils/misc');

const CONFIG=require('./templates/config');

const boilerplatesMap=CONFIG.boilerplatesMap;

module.exports=yeoman.Base.extend({

info:function() {?

? ? ? ? ? ? this.log(chalk.green('I am going to build your app!'));

},

initializing:function() {

? ? ? ? ? ?this.props={};

},

prompting:function() {

? ? ? ? ? ? ?vardone=this.async();

? ? ? ? ? ? ?letallBoilerplates=_.keys(boilerplatesMap);

varprompts=[ ? ??

?{

? ? ? ? ? ? ? ? ? ? ? ?name:'boilerplate',

? ? ? ? ? ? ? ? ? ? ? type:'list',

? ? ? ? ? ? ? ? ? ? ? choices:allBoilerplates,

? ? ? ? ? ? ? ? ? ? ? default:allBoilerplates[0],

? ? ? ? ? ? ? ? ? ? ? message:'boilerplate'

}, {

? ? ? ? ? ? ? ? ? ? name:'name',

? ? ? ? ? ? ? ? ? ? message:'Your project name',

? ? ? ? ? ? ? ? ? ?default:path.basename(process.cwd())// Default to current folder name

}, {

? ? ? ? ? ? ? ? ? name:'version',

? ? ? ? ? ? ? ? ?default:'0.1.0',

? ? ? ? ? ? ? ? ?message:'version'

},

{

? ? ? ? ? ? ?name:'description',

? ? ? ? ? ? default:'vue project',

? ? ? ? ? ? ?message:'description'

},

{

? ? ? ? ? ? ? ?name:'repo',

? ? ? ? ? ? default:utils.getGitOrigin(),

? ? ? ? ? ? message:'git repository'

},

{

? ? ? ? ? ? name:'keywords',?

? ? ? ? ? default:'vue',

? ? ? ? ? message:'keywords',

?filter:function(words) {

? ? ? ? ? returnwords.split(/\s*,\s*/g);

}

},

{

? ? ? ? ? ? name:'author',

? ? ? ? ?default:this.user.git.name(),

? ? ? ?message:'author'

},

{

? ? ? ? ?name:'email',?

? ? ? ?default:this.user.git.email(),

? ? ? ?message:'E-Mail'

}

];

this.prompt(prompts,function(props) {

? ? ? ? ? this.props=props;

// To access props later use this.props.someAnswer;

? ? ? ? ? ? done();

}.bind(this));

},

/*

* 生成 LICENSE

*

* */

default:function() {

? ? ?this.composeWith('license', {?

options:{

? ? ? ? ? name:this.props.author,

? ? ? ? ?email:this.props.email,

? ? ? ? ? ?website:''

}

}, {

local:require.resolve('generator-license/app')

});

},

writing:{

"init":function() {

? ? ? ? ? ?this.currentDir=boilerplatesMap[this.props.boilerplate]||_.keys(boilerplatesMap)[0];

},

/*

* 生成 package.json

*

* */

"package_json":function() {

? ? ? ? ? ? ?varcurrentPkg=this.fs.readJSON(this.destinationPath('package.json'), {});

? ? ? ? ? varpkg_json={

? ? ? ? ? ? ? ? ?"webpack2+vue2+router2":{

? ? ? ? ? ? ? ? ? ?devDependencies:{

? ? ? ? ? ? ? ? ? ? ? ? ? ?"autoprefixer":"^6.7.2",

? ? ? ? ? ? ? ? ? ? ? ? ? ? "babel-core":"^6.22.1",

? ? ? ? ? ? ? ? ? ? ? ? ? ? "babel-loader":"^6.2.10",

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "babel-plugin-transform-runtime":"^6.22.0",

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "babel-preset-env":"^1.3.2",

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"babel-preset-stage-2":"^6.22.0",

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"babel-register":"^6.22.0",

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"chalk":"^1.1.3",

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "compression-webpack-plugin":"^0.4.0",

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"connect-history-api-fallback":"^1.3.0",

? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"copy-webpack-plugin":"^4.0.1",

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "css-loader":"^0.28.0",

? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"eventsource-polyfill":"^0.9.6",

? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"express":"^4.14.1",

? ? ? ? ? ? ? ? ? ? ? ? ? ? "extract-text-webpack-plugin":"^2.0.0",

? ? ? ? ? ? ? ? ? ? ? ? "file-loader":"^0.11.1",

? ? ? ? ? ? ? ? ? ? ? ?"friendly-errors-webpack-plugin":"^1.1.3",

? ? ? ? ? ? ? ? ? ? ? ? "html-webpack-plugin":"^2.28.0",

? ? ? ? ? ? ? ? ? ? ? ? ?"http-proxy-middleware":"^0.17.3",

? ? ? ? ? ? ? ? ? ? ? ? ? ?"isomorphic-fetch":"^2.2.1",

? ? ? ? ? ? ? ? ? ? ? "less":"^2.7.2",

? ? ? ? ? ? ? ? ? ? ?"less-loader":"^4.0.3",

"opn":"^4.0.2",

"optimize-css-assets-webpack-plugin":"^1.3.0",

"ora":"^1.2.0",

"rimraf":"^2.6.0",

"semver":"^5.3.0",

"shelljs":"^0.7.6",

"url-loader":"^0.5.8",

"vue-datepicker":"^1.3.0",

"vue-datepicker-simple":"^1.5.1",

"vue-loader":"^11.3.4",

"vue-style-loader":"^2.0.5",

"vue-template-compiler":"^2.2.6",

"vuex":"^2.3.1",

"webpack":"^2.3.3",

"webpack-bundle-analyzer":"^2.2.1",

"webpack-dev-middleware":"^1.10.0",

"webpack-hot-middleware":"^2.18.0",

"webpack-merge":"^4.1.0"

},

dependencies:{


},

scripts:{

"dev":"node build/dev-server.js",

"start":"node build/dev-server.js",

"build":"node build/build.js"

}

}


author:{

name:this.props.author,

email:this.props.email

},

keywords:[],

"dependencies":pkg_json.dependencies||{},

"devDependencies":pkg_json.devDependencies||{},

"scripts":pkg_json.scripts||{},

"bugs":{

"url":"http://"+utils.getHomeUrl(this.props.repo)+"/issues"

},

"homepage":"http://"+utils.getHomeUrl(this.props.repo)

},currentPkg);

// Combine the keywords

if(this.props.keywords) {

this.pkg.keywords=_.uniq(this.props.keywords.concat(this.pkg.keywords));

}

// Let's extend package.json so we're not overwriting user previous fields

this.fs.writeJSON(this.destinationPath('package.json'),this.pkg);

},

/*

* 生成 README.md

*

* */

"directories":function() {

this.fs.copy(this.templatePath('./'+this.currentDir+'/static')+"/gitignore",this.destinationPath('./.gitignore'));

this.fs.copy(this.templatePath('./'+this.currentDir+'/static')+"/babelrc",this.destinationPath('./.babelrc'));

this.fs.copy(this.templatePath('./'+this.currentDir+'/static')+"/**/*.*",this.destinationPath('./'));

// this.fs.copyTpl(this.templatePath('./' + this.currentDir + '/tpl') + "/**/*.*", this.destinationPath('./'), {AppName: this.pkg.name});

}

},

install(){//安裝依賴

letopt={

cwd:this.destinationPath('./')

};

switch(this.props.boilerplate) {

case'webpack2+vue2':

this.spawnCommandSync('yarn', ['install'],opt);

// this.spawnCommandSync('webpack',[],opt);

this.spawnCommandSync('npm',['start'],opt);

break;

case'webpack2+vue2+router2':

this.spawnCommandSync('yarn', ['install'],opt);

// this.spawnCommandSync('webpack',[],opt);

this.spawnCommandSync('npm',['start'],opt);

break;

default:

break;

}

}

});

更多詳細配置你轉到?generator-vuepackage?或者加我qq咨詢1083590865

yeoman-generator的使用

> npm install -g yo

> npm install -g generator的包名。使用yeoman-generator的腳手架包名需要以 generator-取名字,比如說你發布的npm包名是generator-angular就可以直接

> yo angular

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容