Skip to content

Commit

Permalink
feat: support inline task (#93)
Browse files Browse the repository at this point in the history
  • Loading branch information
ktsn committed Jun 7, 2019
1 parent 4840eae commit 680f2d9
Show file tree
Hide file tree
Showing 6 changed files with 130 additions and 61 deletions.
48 changes: 24 additions & 24 deletions docs/guide/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,31 @@

Houl config file can be `.json` or `.js` that exports config object. It specifies the project source/destination directory, the way how it transforms sources and so on. Available options are following:

Key | Description
-------------- | --------------------------------------------------------
input | Path to source directory
output | Path to destination directory
exclude | Glob pattern(s) of files that will be ignored from input
taskFile | Path to task file that is described in the later section
preset | Preset package name or an object that specify a preset
preset.name | Preset package name
preset.options | Preset options
rules | Specify how to transform source files
dev | Dev server related options (See [Dev options](#dev-options) for details)
| Key | Description |
| -------------- | ------------------------------------------------------------------------ |
| input | Path to source directory |
| output | Path to destination directory |
| exclude | Glob pattern(s) of files that will be ignored from input |
| taskFile | Path to task file that is described in the later section |
| preset | Preset package name or an object that specify a preset |
| preset.name | Preset package name |
| preset.options | Preset options |
| rules | Specify how to transform source files |
| dev | Dev server related options (See [Dev options](#dev-options) for details) |

## Rules

You can specify the way how to transform the source files by _rules_. The `rules` field in config file should be an object and its keys indicate target extensions for transformation. For example, if you want to transform `.js` files, you should add `js` field in `rules` object.

Each field in `rules` object can be an object or a string. If string is specified, it will be treated as `task`.
Each field in `rules` object can be an object, a string or a function. If string or function is specified, it will be treated as `task`.

Key | Description
--------- | -----------------------------------------------------------------------------------------------------------
task | Task name that will apply transformations
outputExt | Extension of output files. If omitted, it is same as input files' extensions.
exclude | Glob pattern(s) of files that will not be applied the rule
progeny | Specify [progeny configs](https://github.com/es128/progeny#configuration) for the corresponding file format
options | Options for the corresponding task that is passed to the 2nd argument of the task
| Key | Description |
| --------- | ----------------------------------------------------------------------------------------------------------- |
| task | Task name or inline task that will apply transformations |
| outputExt | Extension of output files. If omitted, it is same as input files' extensions. |
| exclude | Glob pattern(s) of files that will not be applied the rule |
| progeny | Specify [progeny configs](https://github.com/es128/progeny#configuration) for the corresponding file format |
| options | Options for the corresponding task that is passed to the 2nd argument of the task |

## Preset

Expand Down Expand Up @@ -134,11 +134,11 @@ module.exports = {

You can provide dev server related options via `dev` field. The `dev` field has an object which can include the following properties.

Key | Description
-------- | ---
proxy | Proxy configurations which is compatible with [`node-http-proxy` options](https://github.com/nodejitsu/node-http-proxy#options).
port | Port number of the dev server as same as the `--port` cli option.
basePath | Base path of the dev server as same as the `--base-path` cli option.
| Key | Description |
| -------- | -------------------------------------------------------------------------------------------------------------------------------- |
| proxy | Proxy configurations which is compatible with [`node-http-proxy` options](https://github.com/nodejitsu/node-http-proxy#options). |
| port | Port number of the dev server as same as the `--port` cli option. |
| basePath | Base path of the dev server as same as the `--base-path` cli option. |

The below is an example of `proxy` configuration:

Expand Down
33 changes: 29 additions & 4 deletions docs/guide/task.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,43 @@ const babel = require('gulp-babel')
const sass = require('gulp-sass')

exports.scripts = stream => {
return stream
.pipe(babel())
return stream.pipe(babel())
}

exports.styles = (stream, options) => {
return stream
.pipe(sass(options.sass))
return stream.pipe(sass(options.sass))
}
```

Note that the exported name is used on config file (e.g. If you write `exports.scripts`, you can refer it as `"scripts"` task in the config file).

## Inline Task

You can also write task function in config file directory. `task` option in rule objects can receive task function:

```javascript
const babel = require('gulp-babel')
const sass = require('gulp-sass')

module.exports = options => {
return {
rules: {
js: {
task: stream => {
return stream.pipe(babel())
}
},
scss: {
task: stream => {
return stream.pipe(sass(options.sass))
},
outputExt: 'css'
}
}
}
}
```

## Task Helpers

If you want to execute environment specific transformation, you can use `dev` and `prod` helpers:
Expand Down
50 changes: 25 additions & 25 deletions docs/ja/guide/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,31 @@

Houl の設定ファイルには `.json` もしくは、オブジェクトをエクスポートする `.js` ファイルを使うことができます。設定ファイルにはプロジェクトのソースコードが入ったディレクトリ、出力先ディレクトリ、ソースコードをどのように変換するか、などを設定することができます。利用可能なオプションは以下のとおりです。

キー | 説明
-------------- | --------------------------------------------------------
input | ソースコードの入っているディレクトリ
output | 出力先ディレクトリ
exclude | input 内で無視するファイルの glob パターン (文字列または配列)
taskFile | タスクファイルのパス (タスクファイルについては次の節で説明します)
preset | プリセットのパッケージ名、もしくは、プリセットを指定するオブジェクト
preset.name | プリセットのパッケージ名
preset.options | プリセットのオプション
rules | ソースコードをどのように変換するかを指定
dev | 開発サーバー関連のオプション (詳細は [Dev options](#dev-options))
| キー | 説明 |
| -------------- | -------------------------------------------------------------------- |
| input | ソースコードの入っているディレクトリ |
| output | 出力先ディレクトリ |
| exclude | input 内で無視するファイルの glob パターン (文字列または配列) |
| taskFile | タスクファイルのパス (タスクファイルについては次の節で説明します) |
| preset | プリセットのパッケージ名、もしくは、プリセットを指定するオブジェクト |
| preset.name | プリセットのパッケージ名 |
| preset.options | プリセットのオプション |
| rules | ソースコードをどのように変換するかを指定 |
| dev | 開発サーバー関連のオプション (詳細は [Dev options](#dev-options)) |

## ルール

_ルール_ によってソースコードをどのように変換するかを指定することができます。設定ファイルの `rules` はキーが変換するソースコードの拡張子と対応するオブジェクトです。例えば、`.js` ファイルを変換したいとき、`rules` オブジェクトに `js` プロパティを追加します。

`rules` オブジェクトのそれぞれの値はオブジェクト、または、文字列になります。文字列が指定されたときは `task` として扱われます。
`rules` オブジェクトのそれぞれの値はオブジェクト、文字列、または、関数になります。文字列、関数が指定されたときは `task` として扱われます。

キー | 説明
--------- | -----------------------------------------------------------------------------------------------------------
task | 変換として適用されるタスク
outputExt | 出力ファイルの拡張子。省略されたときは入力ファイルの拡張子と同じになる。
exclude | このルールを適用しないファイルの glob パターンの文字列、もしくは、その配列
progeny | ファイル形式に対応する [progeny の設定](https://github.com/es128/progeny#configuration)
options | タスクのオプション (タスク関数の第2引数に渡されます)
| キー | 説明 |
| --------- | --------------------------------------------------------------------------------------- |
| task | 変換として適用されるタスク名、または、インラインタスク |
| outputExt | 出力ファイルの拡張子。省略されたときは入力ファイルの拡張子と同じになる。 |
| exclude | このルールを適用しないファイルの glob パターンの文字列、もしくは、その配列 |
| progeny | ファイル形式に対応する [progeny の設定](https://github.com/es128/progeny#configuration) |
| options | タスクのオプション (タスク関数の第 2 引数に渡されます) |

## プリセット

Expand Down Expand Up @@ -112,7 +112,7 @@ module.exports = function(options) {
}
```

プリセットをより柔軟に変更したいときは、`preset.modifyConfig` オプションを使えます。`modifyConfig` には第1引数に生のプリセットの設定オブジェクトが渡される関数を指定します。プリセットの設定をその関数内で変更したり、任意で新しい設定オブジェクトを返すことができます。
プリセットをより柔軟に変更したいときは、`preset.modifyConfig` オプションを使えます。`modifyConfig` には第 1 引数に生のプリセットの設定オブジェクトが渡される関数を指定します。プリセットの設定をその関数内で変更したり、任意で新しい設定オブジェクトを返すことができます。

```js
module.exports = {
Expand All @@ -134,11 +134,11 @@ module.exports = {

`dev` フィールドには開発サーバー関連のオプションを渡せます。`dev` フィールドは次のようなプロパティを含むオブジェクトを期待します。

キー | 説明
-------- | ---
proxy | [`node-http-proxy` のオプション](https://github.com/nodejitsu/node-http-proxy#options) 互換のプロキシ設定。
port | 開発サーバーのポート番号。`--port` CLI オプションと同じ。
basePath | 開発サーバーのベースとなるパス。`--base-path` CLI オプションと同じ。
| キー | 説明 |
| -------- | ----------------------------------------------------------------------------------------------------------- |
| proxy | [`node-http-proxy` のオプション](https://github.com/nodejitsu/node-http-proxy#options) 互換のプロキシ設定。 |
| port | 開発サーバーのポート番号。`--port` CLI オプションと同じ。 |
| basePath | 開発サーバーのベースとなるパス。`--base-path` CLI オプションと同じ。 |

下記は `proxy` 設定の例です。

Expand Down
35 changes: 30 additions & 5 deletions docs/ja/guide/task.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,50 @@

タスクファイルにはソースコードが Houl によってどのように変換されるかを定義します。特筆すべき点は、タスクファイルは任意の [Gulp](http://gulpjs.com/) プラグインと互換性を持っているという点です。これは Houl で潤沢な Gulp のエコシステムを活用することができることを意味します。

タスクファイルはいくつかの関数をエクスポートする `.js` ファイルです。エクポートされる関数はソースコードが送られるストリームを受け取るので、それをパイプして変換を行ったストリームを返す必要があります。第2引数には設定ファイルの各ルールに指定されたオプションの値が渡されます。任意の Gulp プラグインを使ってストリームをパイプできます。
タスクファイルはいくつかの関数をエクスポートする `.js` ファイルです。エクポートされる関数はソースコードが送られるストリームを受け取るので、それをパイプして変換を行ったストリームを返す必要があります。第 2 引数には設定ファイルの各ルールに指定されたオプションの値が渡されます。任意の Gulp プラグインを使ってストリームをパイプできます。

```javascript
const babel = require('gulp-babel')
const sass = require('gulp-sass')

exports.scripts = stream => {
return stream
.pipe(babel())
return stream.pipe(babel())
}

exports.styles = (stream, options) => {
return stream
.pipe(sass(options.sass))
return stream.pipe(sass(options.sass))
}
```

エクスポートする名前は設定ファイル内で使われます (例えば、`exports.scripts` と書いたら、設定ファイル内では `"scripts"` タスクとして使用することができます)。

## インラインタスク

タスクの関数を設定ファイル内に直接書くこともできます。ルールオブジェクト内の `task` オプションはタスク関数も受け取れます:

```javascript
const babel = require('gulp-babel')
const sass = require('gulp-sass')

module.exports = options => {
return {
rules: {
js: {
task: stream => {
return stream.pipe(babel())
}
},
scss: {
task: stream => {
return stream.pipe(sass(options.sass))
},
outputExt: 'css'
}
}
}
}
```

## タスクヘルパー

環境特有の変換を行いたいときは `dev``prod` ヘルパーを使えます。
Expand Down
12 changes: 9 additions & 3 deletions lib/models/rule.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,15 @@ const emptyRule = new class EmptyRule {

class Rule {
constructor(rule, inputExt) {
this.taskName = typeof rule === 'string' ? rule : rule.task

this.task = null
const rawTask =
typeof rule === 'string' || typeof rule === 'function' ? rule : rule.task
if (typeof rawTask === 'function') {
this.taskName = '<inline task>'
this.task = rawTask
} else {
this.taskName = rawTask
this.task = null
}

this.inputExt = inputExt
this.outputExt = rule.outputExt || this.inputExt
Expand Down
13 changes: 13 additions & 0 deletions test/specs/models/rule.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,19 @@ describe('Rule model', () => {
}).toThrowError(/Task "foo" is not defined/)
})

it('accepts inline task', () => {
const r = Rule.create(
{
task: () => 'pass'
},
'js',
{}
)

expect(r.taskName).toBe('<inline task>')
expect(r.task()).toBe('pass')
})

describe('Empty rule', () => {
const empty = Rule.empty

Expand Down

0 comments on commit 680f2d9

Please sign in to comment.