- 投稿日:2019-05-24T20:53:28+09:00
Puppeteer をヘッドフルにしてあげた
Puppeteer君、きみはよくがんばった。褒美に画面をあたえよう。
ということで、スクレイピングやE2Eテストなど裏方で活躍している Headless Chrome Node API の Puppeteer に特に理由もなく Web フロントエンドを実装しました。
動かしてみよう
デモサイト(重すぎるのであまりおすすめではありません)
https://boiyaa-headful-puppeteer.appspot.comまたは、
https://github.com/boiyaa/headful-puppeteer
をクローンして、$ npm i $ npm run devして、 http://localhost:8080 にアクセス。
ブラウザの中のブラウザ風UIの中のアドレスバーに入力されている URL の画面が表示されますが、HTMLではなく、 Pupeteer で叩いて取得したスナップショット画像を表示しています。
このアドレスバーに例えば GitHub の URL を入力すれば GitHub のスナップショット画像に切り替わります。
また、画像ですが、画像内のマウスクリック座標を渡して Pupeteer が代わりにリンクをクリックして遷移するように仕上げてみました。
クリックを受け取れる機能を利用してちょっと試してみます。
アドレスバーの左に、この Headful Puppeteer に遷移するホームボタンを用意しました。
これを押すと、Puppeteer で Headful Puppeteer を開いてその中の Puppeteer が Puppeteer のWebサイトにアクセスしている状態になります。
その画像の中のホームボタンを押す、を繰り返しただけ増殖します。
ん〜実にヘッドフル。
Chrome を意気揚々と操っている Puppeteer 自身もまた何者かに操られている、という社会派アートができました。
以上です。
やったこと
画面の実装
import React, { useState, useEffect } from "react"; import axios from "axios"; type ReactFC<P> = React.FC<P> & { getInitialProps?: (context: { req: { query: { url: string } } }) => Promise<P> }; interface Props { initialUrl: string; } type Url = string | undefined; type Position = { x: number; y: number; } | null; const Index: ReactFC<Props> = ({ initialUrl }) => { const [mouseOffset, setMouseOffset] = useState<Position>(null); const [inputValue, setInputValue] = useState<Url>( initialUrl ? initialUrl : "https://developers.google.com/web/tools/puppeteer/" ); const [query, setQuery] = useState<{ url: Url; position: Position; }>({ url: inputValue, position: mouseOffset }); const [imgSrc, setImgSrc] = useState<string | null>(null); useEffect(() => { if (!query.url) { return; } // (2) 入力されたURL、画面サイズを渡す // (8) 現在のURL、画面サイズ、クリックした座標を渡す const url = query.url; const browserWindow = document.getElementById("window"); const width = browserWindow ? browserWindow.clientWidth.toString() : ""; const height = browserWindow ? browserWindow.clientHeight.toString() : ""; const params = query.position ? new URLSearchParams({ url, width, height, "position[x]": query.position.x.toString(), "position[y]": query.position.y.toString() }) : new URLSearchParams({ url: query.url, width, height }); const browser = `/api/browse?${params.toString()}`; axios.get(browser).then(response => { // (6) (12) ウィンドウにスナップショットを表示 setImgSrc(response.data.screenshot); setInputValue(response.data.url); history.pushState(null, "", `?url=${encodeURIComponent(url)}`); }); }, [query]); return ( <> <section> <h1>Headful Puppeteer</h1> <div id="container"> <div id="address-bar"> <button onClick={() => { setQuery({ url: "http://localhost:8080/", position: null }); }} > ? </button> {/* (1) アドレスバーにURLを入力 */} <input type="text" value={inputValue} onChange={event => setInputValue(event.target.value)} onKeyDown={event => (event.keyCode === 13 ? setQuery({ url: inputValue, position: null }) : null)} /> </div> {/* (7) スナップショット上のリンクをクリック */} <div id="window" onMouseMove={event => setMouseOffset({ x: event.nativeEvent.offsetX, y: event.nativeEvent.offsetY })} onClick={() => setQuery({ url: inputValue, position: mouseOffset })} > {imgSrc ? <img src={`data:image/png;base64,${imgSrc}`} /> : ""} </div> </div> </section> </> ); }; Index.getInitialProps = async (context: { req: { query: { url: string } } }) => ({ initialUrl: context.req.query.url }); export default Index;APIの実装
Express のハンドラの中で Puppeteer を動かしています。
参考: Page クラスのドキュメントimport { Request, Response } from "express"; import puppeteer from "puppeteer"; const dev = process.env.NODE_ENV !== "production"; export default async (req: Request, res: Response) => { console.log(req.query); const browser = await puppeteer.launch({ args: ["--no-sandbox"] }); const page = await browser.newPage(); await page.setViewport({ width: parseInt(req.query.width, 10), height: parseInt(req.query.height, 10) }); // (3) Puppeteerでアクセス await page.goto(req.query.url, { waitUntil: dev ? "networkidle2" : "networkidle0" }); if (req.query.hasOwnProperty("position")) { // (9) Puppeteerでアクセスし、指定座標でマウスクリックし、画面遷移する await Promise.all([ page.mouse.click(parseInt(req.query.position.x, 10), parseInt(req.query.position.y, 10)), page.waitForNavigation({ waitUntil: dev ? "networkidle2" : "networkidle0" }) ]); } // (4) (10) スナップショット取得 const screenshot = await page.screenshot({ encoding: "base64" }); const url = page.url(); await browser.close(); // (5) (11) スナップショットとURL状態を返す res.json({ screenshot, url }); };おすすめのデプロイ先
リポジトリの方に設定ファイル入れていますが、 Google App Engine がおすすめです。
同じ Google 製ということもあるし、「Puppeteer でのヘッドレス Chrome の使用」と公式ドキュメントで説明もありますのでサクッと動かす環境作れます。
まとめ
React Hooks コンポーネントのテストめんどそう
- 投稿日:2019-05-24T16:51:02+09:00
GatsbyのStaticQueryをどこで使うか
Gatsybyでのサイト構築で得た個人的見解を記します。
StaticQueryとは
コンポーネントにGraphQL経由でデータを渡す機能です。
これにより、今までページ生成用ファイルからしかGraphQLを呼び出せなかったものが、各コンポーネントからもGraphQLを呼び出すことができるようになりました。
公式→https://www.gatsbyjs.org/docs/static-query/
GatsbyとGraphQLの仕様
Gatsbyはデータ管理にGraphQLを用いています。
このGraphQLを呼び出すことができるのは、ページ生成用のファイル内からのみ可能です。
具体的には、pageディレクトリにあるファイルと、gatsby-node.jsでページ生成を設定したファイルのみになります。
仕様の問題点
通常Reactでは、親コンポーネントから子コンポーネントへデータを流す構造にします。
Gatsbyでも同様に、親から子へデータを流すことができます。しかし、Gatsbyはページ生成用ファイルからしかGraphQLを使えないため、不自然な設計になることがあります。
それは、GraphQL経由で共有部分にデータを渡すときです。
例として、ヘッダー部分のカテゴリーリストについて考えます。画像はw3school.comのヘッダー部分です。
図のようにヘッダー内のメニューバーへカテゴリーリストを渡したい時、通常Reactではヘッダーコンポーネントを親としてデータを取得させます。そのデータを、子であるメニューバーコンポーネントに渡す構造にするはずです(たぶん)。しかし、Gatsbyではこれができません。
GatsbyがgraphQLからデータを取得できるのは、ページ生成を行うファイルからのみです。ルートページ、ブログ記事ページ、カテゴリー別ページ...それぞれでGraphQLからカテゴリーリストを取得し、それをヘッダー/メニューバーコンポーネントまで流す必要があります。二度手間ですね。
もちろんこれでも動きますし、静的サイトジェネレーターなので、本番環境でパフォーマンスの低下があるわけでもありません。せいぜい、生成にほんの少し時間がかかるだけです。
しかし、きれいなコードを目指すなら、ヘッダーコンポーネントに直接データを渡したいはずです。
そんなときに役立つのがStaticQueryです。
StaticQueryの効果
StaticQueryを使えば、GraphQLからヘッダーコンポーネントに直接データを渡せます。
すると、各ページ生成用ファイルからヘッダー/メニューバーコンポーネントに関するデータ処理が消え、非常にわかりやすい構造が出来上がります。このようにStaticQueryを使うと、データ処理が通常のReactの設計へより近づきます。
まとめ
以上より、共有するコンポーネントにデータを渡したいときは、StaticQueryを積極的に使うべきだと考えます。
- 投稿日:2019-05-24T14:55:42+09:00
React.unstable_ConcurrentModeは廃止について
はじめに
去年の11月にReact 16.x Roadmapが公開されて、次はConcurrent Modeの登場を待っている状態です。
少し前になりますが、これに関連して変更があったようです。React.unstable_ConcurrentMode
Concurrent Modeを試すには二通りの方法がありました。上記の記事から抜粋します。
// Two ways to opt in: // 1. Part of an app (not final API) <React.unstable_ConcurrentMode> <Something /> </React.unstable_ConcurrentMode> // 2. Whole app (not final API) ReactDOM.unstable_createRoot(domNode).render(<App />);この前者の方法が廃止されたとのことです。
詳しくは、 https://github.com/facebook/react/pull/15532 を参照してください。部分的にConcurrent Modeを適用すると難しいケースがある上に、利用シーンも分からないということのようです。
今後は後者の
createRoot
を使うことになります。おわりに
自分のテストコードで複数の場所で使っているので、近いうちに修正しておかなければと思いました。
- 投稿日:2019-05-24T14:55:42+09:00
React.unstable_ConcurrentModeは廃止されたようです
はじめに
去年の11月にReact 16.x Roadmapが公開されて、次はConcurrent Modeの登場を待っている状態です。
少し前になりますが、これに関連して変更があったようです。React.unstable_ConcurrentMode
Concurrent Modeを試すには二通りの方法がありました。上記の記事から抜粋します。
// Two ways to opt in: // 1. Part of an app (not final API) <React.unstable_ConcurrentMode> <Something /> </React.unstable_ConcurrentMode> // 2. Whole app (not final API) ReactDOM.unstable_createRoot(domNode).render(<App />);この前者の方法が廃止されたとのことです。
詳しくは、 https://github.com/facebook/react/pull/15532 を参照してください。部分的にConcurrent Modeを適用すると難しいケースがある上に、利用シーンも分からないということのようです。
今後は後者の
createRoot
を使うことになります。おわりに
自分のテストコードで複数の場所で使っているので、近いうちに修正しておかなければと思いました。
- 投稿日:2019-05-24T14:55:42+09:00
React.unstable_ConcurrentModeの廃止について
はじめに
去年の11月にReact 16.x Roadmapが公開されて、次はConcurrent Modeの登場を待っている状態です。
少し前になりますが、これに関連して変更があったようです。React.unstable_ConcurrentMode
Concurrent Modeを試すには二通りの方法がありました。上記の記事から抜粋します。
// Two ways to opt in: // 1. Part of an app (not final API) <React.unstable_ConcurrentMode> <Something /> </React.unstable_ConcurrentMode> // 2. Whole app (not final API) ReactDOM.unstable_createRoot(domNode).render(<App />);この前者の方法が廃止されたとのことです。
詳しくは、 https://github.com/facebook/react/pull/15532 を参照してください。部分的にConcurrent Modeを適用すると難しいケースがある上に、利用シーンも分からないということのようです。
今後は後者の
createRoot
を使うことになります。おわりに
自分のテストコードで複数の場所で使っているので、近いうちに修正しておかなければと思いました。
- 投稿日:2019-05-24T13:05:25+09:00
『React』をかじりたい
よく聞くけど『React』ってなに?
っていう、忘れっぽい自分のための備忘メモです。
概要を知って、環境構築して、やってみる、までの間に参考にしたものをまとめています。これ読んだ
- Reactの概要を知りたい
【参考記事】Reactを使うとなぜjQueryが要らなくなるのか
JavaScriptとHTML(?)が悪魔合体しているのが基本作法
Reactは 仮想DOMと呼ばれる「DOMの設計図」 をベースに処理
機能的に関連するタグと動作を、名前付きでまとめて短く記述できるReactの記述方法
- Reactの環境構築が知りたい
- reactとreact-domのインストール
- Webpackのインストール
Webpackって?
JSファイルをまとめる高機能なモジュールバンドラー。まとめることでウェブページのHTTPリクエストの数を減らしたり、高度なウェブアプリケーションの開発に役立つ (ここから引用)- Babelのインストール
Babelって?
次世代のJavaScriptの標準機能を、ブラウザのサポートを待たずに使えるようにするNode.js製のツールです。次世代の標準機能を使って書かれたコードを、それらの機能をサポートしていないブラウザでも動くコードに変換(トランスパイル)します。(ここから引用)- ブラウザリロードの実装
- index.htmlにコード追加
【参考記事2】正真正銘のReactだけの不純物なしでReact入門
感想
javascriptでDOM操作をごりごり書いてた時代は終わってたんだなぁ。
初心者でも使うのには抵抗ない感じ。環境構築さえしてしまえば。ほんとは
1. 読む
2. Qiitaにまとめる
3. 環境作ってミニマムでやってみる
4. GITにあげる
までやりたい。
以上、Qiitaをうまいこと使っていきたいと思った初投稿でした。
- 投稿日:2019-05-24T11:10:17+09:00
Reactで実践!Schematics
自己紹介
よろしくお願いします!
はじめに
Angular CLIで利用されているSchematics を使って、いつもの作業をいい感じに効率化できたので紹介させていただきます。
Angular CLIはこんな感じのやつです!使ったことある人は多いのではないでしょうか?
$ ng g component my-hero installing component create src/app/my-hero/my-hero.component.css create src/app/my-hero/my-hero.component.html create src/app/my-hero/my-hero.component.spec.ts create src/app/my-hero/my-hero.component.ts update src/app/app.module.tsAngularユーザーでなくてもSchematicsは使えるのでいつもの作業をスキャッフォルディグっちゃいましょう!
Schematicsって?
README.mdには下記のように書いてあります。
モダンウェブのスキャッフォルドライブラリです。
ファイルの作成、既存のファイルのリファクタリングや移動などができます。
とのこと。そして説明には同様のライブラリとの違いとして下記を挙げています。
- まさしく記述的
- すべてがコミットされる準備ができるまで、実際のファイルシステムを変更しない
- Schematicsでは副作用はありません
ところであのおじさん元気かなー
できることはyeomanおじさんと似てますが、Schematicsには「お、いけてる」と思う点がたくさんありました。
実際に作ったものを紹介しながら良さも伝えていきたいと思います。
いつもの作業...
私が欲しかったものは
src/components/Header/ ├── Header.jsx ├── Header.stories.js ├── Header.test.js └── index.jsこんな感じのコンポーネントのワンセットを
コマンドでサクッと
- 作りたいコンポーネント名
- パス
を下記のように指定したら生成してくれて、
$ npm run gen -- --name=Header --path=src/componentsあわよくば実行可能なストーリーブックとスナップショットテストが欲しい。
できる!
https://github.com/hand-dot/component-gen
npmで公開していますが、現状ほぼ自分のために作ったので悪しからず...
思った以上に簡単だった...!
初めて触ったんですが、自分のやりたいことのレベルならnpmに公開して別プロジェクトで使うまで2,3時間くらいで作れたので良かった。
もし同じようなことがやりたい人がいたら...と思い、やったことを下記で簡単に説明していきます。
セットアップ
- schematicsをインストールして
- 空のschematics cli「my-schematics」を作って
- 移動します
$ npm install -g @angular-devkit/schematics-cli $ schematics blank my-schematics $ cd my-schematics複数のSchematicを使いたい場合や、実装をみてみたい場合は
$ schematics schematic --name=my-schematicsでセットアップするといいかも。丁寧にコメントしてあってわかりやすいです。
srcの中のファイルはこんな感じ
src/ ├── collection.json <-Schematicsの定義ファイル └── my-schematics ├── index.ts └── index_spec.tsビルドして実行
$ npm run build $ schematics .:my-schematicsテストもついてる
$ npm run test
一番簡単なファイルの作成
Hello world!という内容のhiというファイルを作ってみましょう。
import { Rule, SchematicContext, Tree } from "@angular-devkit/schematics"; export function mySchematics(_options: any): Rule { return (tree: Tree, _context: SchematicContext) => { tree.create("/hi", "Hello world!"); return tree; }; }Treeは変更のためのステージング領域。Treeにあんなことやこんなことをして返却して変更をリクエストする。
時間の関係上、機能は紹介しませんが
などを参考にしていただければと思います。(APIもシンプルなので良きです。)
Schematicsのここが好き!
Dry Run!
例えばさっきの一番簡単なファイルの作成を実行すると実際にファイルは作成されないが、下記のようなフィードバックがある。$ schematics .:my-schematics CREATE /hi (12 bytes)
--dry-run=false
のオプションを渡すと本当にファイル作ります。テストも同様でsetUpやtearDownを書かなくていいため、ファイルを消して再実行!みたいな手間がない。そして、下記のように
npm run build -- -wでwatchしながら実装すればサクサク試せるので楽しかった。
Schematicsのここで困った...
$ schematics .:my-schematics
実行時の.:
これなに?ってなってシカトしてたらnpmパッケージにした後に他プロジェクトで実行できなくて少し迷った。Helpにはサフィックスでセミコロンをつけろとのこと。
schematics [CollectionName:]SchematicName [options, ...]
.:
の場合は同階層のpackage.jsonのschematicsプロパティからcollection.jsonを見つけて指定されたSchematicNameを実行する。
そして例としてあげた「my-schematics」をnpmで公開して別プロジェクトでnpm installした場合の実行は
$ schematics my-schematics:my-schematics
となる。
READMEにも CollectionにNPMパッケージを使用します。との記載があるが、
最初はCollectionName? SchematicName? え? となるので困った。ちなみに実行時にCollectionNameに
.:
を使うとデフォルトがDry Runになる。
まとめ
- 定型作業をサクッと効率化できる。
- え?yeoman!?(プークスクス)ってならない。
- え? Don't repeat yourself ですよ?(キャーカクイイ)ってなるかもしれない。
- AngularのいいところがAngular以外で使えて嬉しい。
- Schematicsの開発自体が結構楽しい。(ここ重要)
おわり
参考にさせていただきました!
- 投稿日:2019-05-24T11:10:17+09:00
【開発を効率化しよう】Reactで実践!Schematics
schematicsを使っていつもの作業を効率化しよう!
Reactのコンポーネント、テスト、ストーリーブックの作成をスキャッフォルドしてみた!
自己紹介
よろしくお願いします!
はじめに
Angular CLIで利用されているSchematics を使って、いつもの作業をいい感じに効率化できたので紹介させていただきます。
Angular CLIはこんな感じのやつです!使ったことある人は多いのではないでしょうか?
$ ng g component my-hero installing component create src/app/my-hero/my-hero.component.css create src/app/my-hero/my-hero.component.html create src/app/my-hero/my-hero.component.spec.ts create src/app/my-hero/my-hero.component.ts update src/app/app.module.tsAngularユーザーでなくてもSchematicsは使えるのでいつもの作業をスキャッフォルディグっちゃいましょう!
Schematicsって?
README.mdには下記のように書いてあります。
モダンウェブのスキャッフォルドライブラリです。
ファイルの作成、既存のファイルのリファクタリングや移動などができます。
とのこと。そして説明には同様のライブラリとの違いとして下記を挙げています。
- まさしく記述的
- すべてがコミットされる準備ができるまで、実際のファイルシステムを変更しない
- Schematicsでは副作用はありません
ところであのおじさん元気かなー
できることはyeomanおじさんと似てますが、Schematicsには「お、いけてる」と思う点がたくさんありました。
実際に作ったものを紹介しながら良さも伝えていきたいと思います。
いつもの作業...
私が欲しかったものは
src/components/Header/ ├── Header.jsx ├── Header.stories.js ├── Header.test.js └── index.jsこんな感じのコンポーネントのワンセットを
コマンドでサクッと
- 作りたいコンポーネント名
- パス
を下記のように指定したら生成してくれて、
$ npm run gen -- --name=Header --path=src/componentsあわよくば実行可能なストーリーブックとスナップショットテストが欲しい。
できる!
https://github.com/hand-dot/component-gen
npmで公開していますが、現状ほぼ自分のために作ったので悪しからず...
思った以上に簡単だった...!
初めて触ったんですが、自分のやりたいことのレベルならnpmに公開して別プロジェクトで使うまで2,3時間くらいで作れたので良かった。
もし同じようなことがやりたい人がいたら...と思い、やったことを下記で簡単に説明していきます。
セットアップ
- schematicsをインストールして
- 空のschematics cli「my-schematics」を作って
- 移動します
$ npm install -g @angular-devkit/schematics-cli $ schematics blank my-schematics $ cd my-schematics複数のSchematicを使いたい場合や、実装をみてみたい場合は
$ schematics schematic --name=my-schematicsでセットアップするといいかも。丁寧にコメントしてあってわかりやすいです。
srcの中のファイルはこんな感じ
src/ ├── collection.json <-Schematicsの定義ファイル └── my-schematics ├── index.ts └── index_spec.tsビルドして実行
$ npm run build $ schematics .:my-schematicsテストもついてる
$ npm run test
一番簡単なファイルの作成
Hello world!という内容のhiというファイルを作ってみましょう。
import { Rule, SchematicContext, Tree } from "@angular-devkit/schematics"; export function mySchematics(_options: any): Rule { return (tree: Tree, _context: SchematicContext) => { tree.create("/hi", "Hello world!"); return tree; }; }Treeは変更のためのステージング領域。Treeにあんなことやこんなことをして返却して変更をリクエストする。
時間の関係上、機能は紹介しませんが←2019/05/25追記: 次のセクションにて解説します。などを参考にしていただければと思います。(APIもシンプルなので良きです。)
今回作成したSchematicsの簡単な解説
やりたいことはReactのテンプレートを用意し、ファイル名や一部の文字を置き換え、任意の場所にコピーするだけなので単純です。
公式のREADME.mdのTemplatingを参考にテンプレートを呼び出す例として下記の処理を見てみましょう。
files/__name@dasherize__.tsexport class <%= classify(name) %> { }index.tsimport { strings } from '@angular-devkit/core'; import { Rule, SchematicContext, SchematicsException, Tree, apply, mergeWith, template, url, } from '@angular-devkit/schematics'; import { Schema as ClassOptions } from './schema'; export default function (options: ClassOptions): Rule { return (tree: Tree, context: SchematicContext) => { if (!options.name) { throw new SchematicsException('Option (name) is required.'); } const templateSource = apply( url('./files'), [ template({ ...strings, ...options, }), ] ); return mergeWith(templateSource); }; }なんとなく予想つきますが、テンプレートのプレースホルダを埋めます。
template
関数を見てみると渡しているのは...options
と...strings
です。
options
に関してはテンプレート内<%= classify(name) %>
とファイル名の__name@dasherize__
をname
で渡した何かしらの文字列に置き換えます。
strings
は使用されているdasherize
とclassify
関数をテンプレート内とファイル名に提供しています。(ファイル名に関数を適応する場合は@
をつける)なので
options.name
にfooBar
を渡して実行した場合、実行したディレクトリに下記のようなファイルが作成されます。foo-bar.tsexport class FooBar { }これを理解しておくと私がやったことはなんとなく想像ができるのではないでしょうか?
src/ ├── collection.json └── component-gen ├── files │ └── react │ ├── __name@classify__.jsx │ ├── __name@classify__.stories.js │ ├── __name@classify__.test.js │ └── index.js └── react ├── index.d.ts ├── index.ts ├── index_spec.d.ts └── index_spec.tsソースコードは(こちら)[https://github.com/hand-dot/component-gen]でご覧いただけます。
Schematicsのここが好き!
Dry Run!
例えばさっきの一番簡単なファイルの作成を実行すると実際にファイルは作成されないが、下記のようなフィードバックがある。$ schematics .:my-schematics CREATE /hi (12 bytes)
--dry-run=false
のオプションを渡すと本当にファイル作ります。テストも同様でsetUpやtearDownを書かなくていいため、ファイルを消して再実行!みたいな手間がない。そして、下記のように
npm run build -- -wでwatchしながら実装すればサクサク試せるので楽しかった。
Schematicsのここで困った...
$ schematics .:my-schematics
実行時の.:
これなに?ってなってシカトしてたらnpmパッケージにした後に他プロジェクトで実行できなくて少し迷った。Helpにはサフィックスでセミコロンをつけろとのこと。
schematics [CollectionName:]SchematicName [options, ...]
.:
の場合は同階層のpackage.jsonのschematicsプロパティからcollection.jsonを見つけて指定されたSchematicNameを実行する。
そして例としてあげた「my-schematics」をnpmで公開して別プロジェクトでnpm installした場合の実行は
$ schematics my-schematics:my-schematics
となる。
READMEにも CollectionにNPMパッケージを使用します。との記載があるが、
最初はCollectionName? SchematicName? え? となるので困った。ちなみに実行時にCollectionNameに
.:
を使うとデフォルトがDry Runになる。
まとめ
- 定型作業をサクッと効率化できる。
- え?yeoman!?(プークスクス)ってならない。
- え? Don't repeat yourself ですよ?(キャーカクイイ)ってなるかもしれない。
- AngularのいいところがAngular以外で使えて嬉しい。
- Schematicsの開発自体が結構楽しい。(ここ重要)
- SchematicNameは複数定義できるので自分のネームスペースでnpmに公開おいて、プロジェクトに合わせて使ったり、今回はコンポーネント版でしたがRedux版やVue版も作りたいと思った。
- チーム開発でもかなり強力に使えると思った。
おわり
参考にさせていただきました!