babel+webpackでビルド可能なchrome拡張の雛形をYoemanで作成
generator-generatorのインストール
$ npm i -g generator-generator
雛形の雛形を生成
$ mkdir generator-chrome-extension $ cd generator-chrome-extension $ yo generator
yoemanからgeneratorとして呼び出させるようにするために、以下のコマンドをgenerator-chrome-extension内で実行します。
$ npm link
generator-chrome-extensionが必要になくなった場合は、以下のコマンドでnpm link
を取り消すことができます。
$ npm unlink -g generator-chrome-extension
雛形をカスタマイズ
最初にgenerators/app/templates
以下に雛形として生成するファイルやディレクトリを配置します。
. ├── index.js └── templates ├── _bower.json ├── _manifest.json ├── _package.json ├── dist ├── js │ ├── background.js │ └── main.js └── webpack.config.js
続いて雛形生成の処理を記述していきます。
yoemanが雛形を生成する処理はgenerators/app/index.js
に記述してあるため、こちらを編集することで雛形生成の処理をカスタマイズすることが出来ます。
'use strict'; var yeoman = require('yeoman-generator'); var chalk = require('chalk'); var yosay = require('yosay'); var mkdirp = require('mkdirp') module.exports = yeoman.Base.extend({ prompting: function () { // Have Yeoman greet the user. this.log(yosay( 'Welcome to the fine ' + chalk.red('generator-chrome-extension') + ' generator!' )); // 設定ファイルに記述する値を対話的に入力してもらう処理 var prompts = [ { name: 'name', message: 'What is your app name', default: '' }, { name: 'description', message: 'What is your app description', default: '' }, { name: 'author', message: 'What is your name', default: '' } ]; return this.prompt(prompts).then(function (props) { // To access props later use this.props.someAnswer; this.props = props; }.bind(this)); }, // 雛形のファイルやディレクトリを書き込み writing: function () { // ディレクトリをコピー this.directory( this.templatePath('js'), this.destinationPath('js') ) // 空のディレクトリを生成 mkdirp(this.destinationPath('dist')) this.fs.copyTpl( this.templatePath('_bower.json'), this.destinationPath('bower.json'), { name: this.props.name, description: this.props.description } ) this.fs.copyTpl( this.templatePath('_manifest.json'), this.destinationPath('manifest.json'), { name: this.props.name, description: this.props.description } ) this.fs.copyTpl( this.templatePath('_package.json'), this.destinationPath('package.json'), { name: this.props.name, description: this.props.description, author: this.props.author } ) this.fs.copy( this.templatePath('.babelrc'), this.destinationPath('.babelrc') ) this.fs.copy( this.templatePath('webpack.config.js'), this.destinationPath('webpack.config.js') ) }, // bower & npm のインストール実行 install: function () { this.installDependencies(); } });
こちらの記述はプロンプトでユーザーにプロジェクト名等を入力してもらい、prompt
変数に格納していきます。
prompting: function () { // Have Yeoman greet the user. this.log(yosay( 'Welcome to the fine ' + chalk.red('generator-chrome-extension') + ' generator!' )); // 設定ファイルに記述する値を対話的に入力してもらう処理 var prompts = [ { name: 'name', message: 'What is your app name', default: '' }, { name: 'description', message: 'What is your app description', default: '' }, { name: 'author', message: 'What is your name', default: '' } ]; return this.prompt(prompts).then(function (props) { // To access props later use this.props.someAnswer; this.props = props; }.bind(this)); },
templates/_package.json
の中身を見てみます。
<%= %>
で囲まれた部分が入力さた値が埋め込まれる箇所を示しています。
{ "name": "<%= name %>", "version": "1.0.0", "description": "<%= description %>", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack --watch" }, "author": "<%= author %>", "license": "ISC", "devDependencies": { "babel-cli": "^6.11.4", "babel-core": "^6.11.4", "babel-loader": "^6.2.4", "babel-preset-es2015": "^6.9.0", "webpack": "^1.13.1" }, "dependencies": { "lodash": "^4.13.1" } }
この雛形ファイルに値を埋め込むにはthis.fs.copyTpl()
を利用します。
上記のindex.js
では次のように処理を書いています。
第1引数にテンプレートファイルのパスを、第2引数に出力先のファイルパスを、第3引数として設定ファイルに埋め込む変数の値をオブジェクトとして渡してあげます。
this.fs.copyTpl( this.templatePath('_package.json'), this.destinationPath('package.json'), { name: this.props.name, description: this.props.description, author: this.props.author } )
generator-chrome-extensionの動作確認
別ディレクトリに移動して、generator-chrome-extensionの動作確認をしてみます。
$ mkdir test-chrome-extension $ cd test-chrome-extension $ yo chrome-extension
プロンプトが立ち上がり必要な値を入力し終わると、ファイル・ディレクトリの生成が行われた後に、bower install && npm install
が実行され雛形が生成されます。
$ tree . ├── bower.json ├── bower_components (省略) ├── dist ├── js │ ├── background.js │ └── main.js ├── manifest.json ├── node_modules (省略) ├── package.json └── webpack.config.js