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