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