dackdive's blog

新米webエンジニアによる技術ブログ。JavaScript(React), Salesforce, Python など

[Salesforce]代理承認者機能の使い方

まとまってるドキュメントが見つからなかったのでメモ。


代理承認者とは

  • Salesforce の承認プロセス機能において、承認者の代わりに申請を承認/却下できる人を設定できる機能
  • ユーザに対して一人だけ代理承認者を設定しておくことができる
  • また承認プロセスの各承認ステップごとに代理承認者による承認を許可するかどうかが設定できる

承認プロセスそのものについては以下の Trailhead モジュールをやるといい。


設定手順

ユーザ設定より代理承認者を設定する

代理承認者を設定したいユーザのユーザ設定画面を開き、下の方の「承認者の設定」セクションに移動する。
「代理承認者」項目に代理承認者にしたいユーザを検索してセットする。

f:id:dackdive:20180317025929p:plain:w320

また、代理承認者自身のユーザ設定で、「承認申請メールを受信」項目を「自分が承認者である場合のみ」から「承認者または代理承認者である場合」に変更しておくとよい。理由は後述。

f:id:dackdive:20180317025925p:plain:w320


承認プロセス設定より、承認ステップで代理承認を許可する

今度は承認プロセスの設定画面を開き、任意の承認ステップの編集画面を開く。

f:id:dackdive:20180317031300p:plain

ステップ 3/3 で、一番下に「代理承認者もこの申請を承認可能にする」という項目があるのでチェックする。

f:id:dackdive:20180317031303p:plain


結果

自分が代理承認者になっている承認ステップに申請が回ってきたとき、承認者同様にメールが届く。
メールの件名には「(◯◯の代理承認者)」と書かれているよう。

f:id:dackdive:20180317032513p:plain


制限事項

自身が代理承認可能な申請は今のところ「未承認申請一覧」には表示されない。メール以外に確認する手段がないのでつらい。
これについてはずいぶん前から Idea に投稿されてるよう。

また、以下のヘルプ記事ではメール以外のワークアラウンドも紹介されてる(英語)。

Why can't a delegated approver see anything in the Items to approve list?

どうやら「レコードが現在承認プロセスの申請中かどうか」を表すチェックボックス項目をオブジェクトに追加し、それを条件にリストビューを作るという方法らしい。
チェックボックスの ON/OFF は承認プロセスの開始時や最終承認/却下時のアクションとして項目自動更新により自動的に制御できる。

が、これは別に「自身が代理承認になっているものリスト」ではないし、もっと言うと自分が承認者じゃないやつも含まれるのでは。。。

(2018/3/23追記)

と思ったら、標準レポートに「代理承認申請一覧」というのがあった。。。

f:id:dackdive:20180323234404p:plain

これで一覧表示できます。

f:id:dackdive:20180326143254p:plain

※ただし、標準フォルダは LEX では表示されないため、コピーする必要あり
(参考:レポートおよびダッシュボード: Lightning Experience で使用できない機能とその新機能


「代理承認者」に設定する以外に、他人の申請を承認/却下する方法

「代理承認者」はユーザにつき一人しか指定できない。もう少し柔軟に代理承認可能なユーザを増やすにはどうするか。

代理承認ではないが、申請を行うオブジェクトに対して「すべての編集」権限があれば任意の申請を承認/却下することができる。
(「すべてのデータの編集」権限もそう)

参考:承認の管理に関する考慮事項

管理者権限
次の権限のいずれかを持つユーザは承認管理者とみなされます。

  • 指定のオブジェクトに対するオブジェクトレベルでの「すべての編集」権限
  • 「すべてのデータの編集」ユーザ権限

承認管理者には次の権限があります。

  • 承認プロセスの一環としてではなく、未承認申請を承認または却下
  • 承認がロックされたレコードの編集


わかっていないこと

  • 承認者としてキューやグループを指定したときにどういう挙動になるのか

electron-react-boilerplateでCSSフレームワーク(Lightning Design System)をインストールするとエラー

Chatter Desktop という Electron アプリ を作っていて真っ先にハマったところのメモ。

Lightning Design System という CSS フレームワークを入れようとしたところ、以下のエラーとなった。

$ git clone --depth=1 https://github.com/chentsulin/electron-react-boilerplate.git your-project-name
$ cd your-project-name
$ yarn
$ yarn add @salesforce-ux/design-system
...
ERROR in dll renderer
Module not found: Error: Can't resolve '@salesforce-ux/design-system' in '/Users/yamazaki/workspace/electron/electron-react-boilerplate'
 @ dll renderer

ERROR in ./node_modules/bootstrap/dist/js/bootstrap.js
Module not found: Error: Can't resolve 'jquery' in '/Users/yamazaki/workspace/electron/electron-react-boilerplate/node_modules/bootstrap/dist/js'
 @ ./node_modules/bootstrap/dist/js/bootstrap.js 7:81-98
 @ dll renderer

ERROR in ./node_modules/bootstrap/dist/js/bootstrap.js
Module not found: Error: Can't resolve 'popper.js' in '/Users/yamazaki/workspace/electron/electron-react-boilerplate/node_modules/bootstrap/dist/js'
 @ ./node_modules/bootstrap/dist/js/bootstrap.js 7:100-120
 @ dll renderer
npm ERR! code ELIFECYCLE
npm ERR! errno 2
npm ERR! electron-react-boilerplate@0.13.2 build-dll: `cross-env NODE_ENV=development node --trace-warnings -r babel-register ./node_modules/webpack/bin/webpack --config webpack.config.renderer.dev.dll.js --colors`
npm ERR! Exit status 2
npm ERR!
npm ERR! Failed at the electron-react-boilerplate@0.13.2 build-dll script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/yamazaki/.npm/_logs/2018-03-04T21_19_46_858Z-debug.log
error Command failed with exit code 2.
info Visit https://yarnpkg.com/en/docs/cli/add for documentation about this command.

https://github.com/chentsulin/electron-react-boilerplate/blob/master/package.json#L23
どうやら postinstall スクリプトが走っており、この中で build-dll という DLL ファイルの生成処理をやろうとして失敗しているよう。

また build-dllwebpack.config.renderer.dev.dll.js を見て webpack によるビルドを行っているので、設定ファイルの中身を見る。そうすると

https://github.com/chentsulin/electron-react-boilerplate/blob/master/webpack.config.renderer.dev.dll.js#L175-L181

entry: {
  renderer: (
    Object
      .keys(dependencies || {})
      .filter(dependency => dependency !== 'font-awesome')
  )
},

ここで、元から入っていた font-awesome については明示的にビルド対象から外しているようだ。
なので手動で

entry: {
  renderer: (
    Object
      .keys(dependencies || {})
      .filter(dependency => {
        // also ignore installed CSS library
        return dependency !== 'font-awesome' && dependency !== '@salesforce-ux/design-system';
      })
  )
},

というふうにインストールする CSS フレームワークをビルド対象から除外してやると、ビルドに成功するようになった。

が、正しい手順なのかがよくわからず、Issue で質問してみることにした。


おまけ: webpack.config.renderer.dev.dll.js がやっていること

開発時のビルドパフォーマンス向上のために webpack.DLLPlugin というのを使っている。
DLLPlugin についてはきちんと理解したわけではないが、外部ライブラリなど毎回毎回ビルドする必要がないモジュールを DLL バンドルという形で別ファイルに切り出し、require() 時に読み込むらしい。
こちらの記事が非常に参考になった。

LDSとdesign-system-reactをBabel&webpackな環境に導入する

メモ。
ちょっと前から Lightning Design System(LDS)の React 実装が公式から出てます。

Lightning Design System for React

で、ようやく入れてみようとドキュメントを頼りにやってみたところ色々手こずったので、手順をまとめておきます。


はじめに

design-system-react の設定に関するドキュメントは、以下のように点在しています。

  1. Getting Started
  2. リポジトリREADME#Usage
  3. リポジトリdocs/webpack.md (Usage with Webpack)

1 が一番参考にしたドキュメント。webpack.config.js の設定例なども載っています。基本はここを見ながらやりました。
ここに書かれてる内容は private repo で管理してるらしい) 2 は 1 と被る部分もあり、ただ Icon の設定に関してはここにしか記載されてません。
また 1, 2 は design-system-react のインストール手順であり、これだけだと LDS はインストールされず、スタイルがあたりません。
LDS を webpack から使えるようにするための情報が 3 に載っています。

以下では、設定手順を大きく「1. design-system-react の設定」と「2. LDS の設定」に分けて記載します。


サンプルコード

Redux & Express でのアプリのひな形リポジトリに導入したときの PR です。

ディレクトリ構成

クライアント側のファイルは public というディレクトリに配置するような構成になっています。

- public
  - assets
    - lds --- LDS はここに展開
    - bundle.js --- ビルド後のファイル
  - components --- React & Redux の
  - containers
  - ...
  - index.js --- エントリーポイント
  - index.html
- package.json
- webpack.config.base.babel.js
- webpack.config.dev.babel.js
- webpack.config.prod.babel.js


1. design-system-react の設定

まずは design-system-react のインストールから設定までの手順。主に先ほどの 1. Getting Started を参考にします。

インストール

npm でインストールできます。

$ npm install @salesforce-ux/design-system @salesforce/design-system-react


webpack の設定

Getting Started のページに webpack.config.js の設定例があるので、それを参考に設定していきます。

 // webpack.config.babel.js (抜粋)
 export default {
   context: path.resolve(path.join(__dirname, 'public')),
   entry: [
     './index',
   ],
+  resolve: {
+    extensions: ['.js', '.jsx'],
+  },
   output: {
     filename: 'bundle.js',
     path: path.resolve(path.join(__dirname, 'public', 'assets')),
     publicPath: '/assets/',
   },
   module: {
     rules: [
       {
-        test: /\.js$/,
-        exclude: /node_modules/,
+        test: /\.jsx?$/,
+        include: [
+          path.resolve(path.join(__dirname, 'public')),
+          path.resolve(path.join(__dirname, 'node_modules/@salesforce/design-system-react')),
+        ],
         use: 'babel-loader',
       },
       {
         ...

(ファイル全体は こちら を参照)

ポイントとしては

  • design-system-react のファイルは .jsx なので、 .jsx もビルドできるように resolve.extensions および babel-loader を適用する正規表現を修正
  • 元々 node_modules 以下はすべて babe-loader の対象外としていたが、design-system-react は対象に含めるよう修正

です。

また、この記事を書いた時点ではドキュメントの方では

path.join(__dirname, 'node_modules/design-system-react')

というように @salesforce が入ってなかったんですが、入れるのが正しいです。
Issue で報告したのでそのうち直るはず。


Babel の設定

.babelrc を修正します。
これには @salesforce/babel-preset-design-system-react という preset を使えとドキュメントにはありますが、中身

https://github.com/salesforce/design-system-react/blob/master/preset/index.js

を見てみると

  • babel-preset-env
  • babel-preset-react
  • babel-plugin-transform-object-rest-spread
  • babel-plugin-transform-class-properties
  • babel-plugin-transform-export-extensions

を指定しているだけなので、既に設定されている .babelrc の内容に合わせて必要な preset/plugin を個別に追加するという対応でもいいのかもしれません。
(実際自分のリポジトリでも babel-plugin-transform-export-extensions 以外は使っていた)

今回は素直にこの preset を使うようにします。

$ npm install -D @salesforce/babel-preset-design-system-react
// .babelrc
{
  "presets": ["@salesforce/babel-preset-design-system-react"]
}


使う

このような形で import して使います。

// components/App.js
import React, { Component } from 'react';
import Button from '@salesforce/design-system-react/components/button';

export default class App extends Component {
  render() {
    return (
      <Button
        iconName="download"
        iconPosition="left"
        label="Neutral Icon"
      />
    );
  }
}


2. LDS の設定

さて、今度は LDS を読み込むための設定をします。
これは docs/webpack.md がある程度参考になります。


インストール
$ npm install @salesforce-ux/design-system style-loader css-loader file-loader

必要になる loader も一緒にインストールしときます。


webpack の設定
 // webpack.config.babel.js
 ...
 export default {
   ...
   module: {
     rules: [
       ...
+      {
+        test: /\.min\.css$/,
+        use: ['style-loader', 'css-loader'],
+      },
+      {
+        test: /\.(eot|svg|ttf|woff|woff2)$/,
+        loader: 'file-loader',
+        options: {
+          name: '[name].[ext]',
+          outputPath: 'lds/',
+        },
+      },
       ...


postinstall 時の処理

次に、npm install 後に LDS を静的リソース配信用のディレクトリ(ここでは public/assets/lds/)にコピーしておきます。
ドキュメントでは postinstall.js スクリプトを作ってシンボリックリンクを貼る処理をやっているようですが、単にコピーするだけなら package.json 内に記述しても十分だと思います。

 // package.json
 {
   "scripts": {
+    "postinstall": "rm -rf public/assets/lds && cp -r node_modules/@salesforce-ux/design-system/assets public/assets/lds",
   ...
 }


読み込み

アプリのエントリーポイントで

 // public/index.js
 import { render } from 'react-dom';
 import { AppContainer } from 'react-hot-loader';
 
+import '@salesforce-ux/design-system/assets/styles/salesforce-lightning-design-system.min.css';
+
 import configureStore from './store/configureStore';
 import App from './containers/App';
 ...

とすれば OK です。


3. Icon パスの設定

最後にもう一点だけ。Icon を使う場合、アプリのルートで <IconSettings> コンポーネントを使い、パスを正しく設定しておく必要があります。

README#icon-usageSLDS React | Icon Settings あたりに記載があります。

 // public/index.js
 import { AppContainer } from 'react-hot-loader';
 
 import '@salesforce-ux/design-system/assets/styles/salesforce-lightning-design-system.min.css';
+import IconSettings from '@salesforce/design-system-react/components/icon-settings';
 
 import configureStore from './store/configureStore';
 import App from './containers/App';
 
 import './styles/index.scss';
 
 const store = configureStore();
 
 const rootEl = document.getElementById('root');
+const LDS_ROOT = 'assets/lds';
 
 render(
   <AppContainer>
     <Provider store={store}>
-      <App />
+      <IconSettings
+        standardSprite={`${LDS_ROOT}/icons/standard-sprite/svg/symbols.svg`}
+        utilitySprite={`${LDS_ROOT}/icons/utility-sprite/svg/symbols.svg`}
+        actionSprite={`${LDS_ROOT}/icons/action-sprite/svg/symbols.svg`}
+        doctypeSprite={`${LDS_ROOT}/icons/doctype-sprite/svg/symbols.svg`}
+        customSprite={`${LDS_ROOT}/icons/custom-sprite/svg/symbols.svg`}
+      >
+        <App />
+      </IconSettings>
     </Provider>
   </AppContainer>,
   rootEl,
 );

ここに関してはよくわかってないことが 2 点あって、

1) <IconSettings> には iconPath を指定する方法と、xxxSprite というアイコンの種類ごとのパスを指定する方法とあるんですが、webpack を使ってると後者を推奨してるようです。

Individual sprites If you are using webpack it is advised to use the sprite properties {actionSprite, standardSprite...} to specify the individual sprite paths so that webpack can easily re-write the paths.

この PR で追加されたようで、そこでも webpack のためにということが書かれていますが詳しいことはよくわからず。

2) xxxSprite の指定のしかたとして、Example にあるように

import actionSprite from '@salesforce-ux/design-system/assets/icons/action-sprite/svg/symbols.svg';

のようにすればいいのかなと思ったんですが、なぜかうまくいかず。。。
結局 postinstall でコピーした方のパスを指定してうまくいったのでそうしています。


結果

f:id:dackdive:20180206041536p:plain

<Button> だけですが、無事に LDS のスタイルがあたった状態でコンポーネントが描画できていることが確認できました。アイコンも表示されています。


おわりに

書いてみるとなんてことないんですが、 @salesforce がちょいちょい抜けてたりとドキュメントの整備が追いついてないみたいで結構ハマりました。。。
とりあえず使えるところまでできてよかった。


トラブルシューティング

遭遇したエラー達。

ERROR in ./node_modules/@salesforce/design-system-react/components/button/index.jsx
Module parse failed: Unexpected token (228:3)
You may need an appropriate loader to handle this file type.
ERROR in ./public/components/App.js
Module not found: Error: Can't resolve '@salesforce/design-system-react/components/button' in '/Users/yamazaki/workspace/react/redux-express-template/public/components'

→ webpack の設定不備。 .jsx がビルド対象になっていない、 node_modules/@salesforce/design-system-react が include されていない、などなど。

/Users/yamazaki/workspace/react/redux-express-template/node_modules/webpack/lib/webpack.js:19
                throw new WebpackOptionsValidationError(webpackOptionsValidationErrors);
        ^
WebpackOptionsValidationError: Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
 - configuration.resolve.extensions[0] should not be empty.
   -> A non-empty string
    at webpack (/Users/yamazaki/workspace/react/redux-express-template/node_modules/webpack/lib/webpack.js:19:9)
    at Object.<anonymous> (/Users/yamazaki/workspace/react/redux-express-template/app.js:13:20)
    at Module._compile (module.js:643:30)
    at babelWatchLoader (/Users/yamazaki/workspace/react/redux-express-template/node_modules/babel-watch/runner.js:50:13)
    at Object.require.extensions.(anonymous function) [as .js] (/Users/yamazaki/workspace/react/redux-express-template/node_modules/babel-watch/runner.js:61:7)
    at Module.load (module.js:556:32)
    at tryModuleLoad (module.js:499:12)
    at Function.Module._load (module.js:491:3)
    at Function.Module.runMain (module.js:684:10)
    at process.on (/Users/yamazaki/workspace/react/redux-express-template/node_modules/babel-watch/runner.js:108:21)

→ webpack の resolve.exntensions に空文字 ['', '.js', '.jsx'] は webpack 2 系以降 NG になったぽい。使うなら'*'

第26回 Tokyo Atlassian ユーザーグループ に行ってきたメモ #augj

行ってきました。

途中参加かつ懇親会は都合がつかず、セッション2つ聞いて帰ってきました。

Confluenence/Jiraパフォーマンスチューニングポイント by 大中浩行

間に合わず。資料が公開されてたので貼っときます。

パフォーマンスと聞いてオンプレ版のことだろうと決めつけてたらやっぱりオンプレ版でした(弊社は Cloud 版)


Confluenceで組織を活性化させたかった話 by 南原 錦善

SES 主力の会社で Confluence Server を使って組織改善にチャレンジしたお話

  • 株式会社ヒューマンネットワーク
    • エンジニア 75 名、営業、管理部 20 名
    • SES の常駐業務が主力
  • 客先常駐なのでエンジニアはバラバラ
  • 定時後帰社、社内活動 -> 社内への働きに対して大きなパワーが必要。効率化することが重要な課題
  • 課題
    • 社内の活動の情報共有がしづらい (元desknets)
    • スキル情報を見る機会がない
    • 議事録、社内ルール、広報がワード、エクセル、PDF
    • やってる感が出ない(家で勉強してたとしても評価できないし、アピールの場がない)
  • 導入までの3つの壁
    1. 社内の反対
      • 変化に対する抵抗
      • 費用対効果の不明さによる懸念
      • 自腹で導入し、良さをアピール
    2. ユーザ管理
      • AD 連携ができるけどうまくいかない→諦め
    3. 使い方指導
  • 利用状況を Google Analytics で取得
  • DBから更新数、いいね数の取得
  • 運用のポイントというか意識したポイント
    1. 使用方法に制限をかけない
    2. 毎日みんなの投稿に目を通しリアクションする
    3. フォロワー(サクラ)を作る
  • 生きた情報は生きた組織を作る!


印象に残った話
  • 費用対効果を説明するの面倒だから 1000円/月・10人分のライセンスを自腹で購入
  • Paiza の問題のリンク集を作り、新人に問題を解かせた。また回答も Confluence に書かせた
    • Java のコードを見るとコメントしたくてたまらない人達が集まってきた
  • ポジティブな気持ちになれる偉人の名言を毎日投稿する人が出てきた

といったエピソードがありました。

弊社も Confluence に情報をまとめるのはだいぶ浸透してきたけど、開発というか業務にないことでも自由に発信するというのはできてないなー。


Making Software for the Software Makers "AtlassianはJIRAをどう使っているか" by Jason Wong

Jira Software プリシパルプロダクトマネージャーの Jason さんからの話。
Atlassian のチーム例 5 つを紹介。
Jira を徹底的に使いこなすための実践的 Tips というより、それぞれのチームで Jira をどう使っているかを通じて Atlassian のカルチャーみたいなものを感じることができて面白かったです。

  • 世界中どこを探してもまったく同じチームはない。だから Jira Software の使い方もチームによって異なる
  • アトラシアンの 5 つのチームの話
  • 世界12箇所、20+ Jira インスタンス、337 プロジェクト、468 カスタムワークフロー
1. 時間的に厳しいアジャイル
  • Identity CloudX チーム
  • Jira に登録しつつ物理カンバン

  • 見積り前提 -> NO!

    • 見積りより調査 早めにスパイクし始めよう!
    • QA 発表会
      • スプリントが終わったときにどんなソフトになっていてほしいか、スプリントの前に実施
  • 改善をし続ける社内文化を支えるために新しい習慣を作ります
    • アジャイルスラム(大勢の人の前に立って経験したことを話す)
      • 詩人会の由来から
    • ウォールボード
    • 仕事と楽しみのバランス
2. 大量の experiment を行うシステム
  • Atlassian 製品の実験的な取り組みを行うチーム?
  • 会社から大量のIdeaがくる。さばききれない
  • 自動化
    • optimizely, jira software, confluence をつなげるマイクロサービスMars
  • 情報を一つの場所にまとめるサービスやプロセスを作るのはとても大切
    • Jira + Confluence
      • Jira を仕事のステータスより、仕事の文脈や背景や結果を詳しく共有できる
3. 端から端まで、開発の見通し
  • Jira Software チーム(Jason さんが所属してるチーム)
  • デザイン・開発・マーケ・プロダクトなどさまざまなチームごとにプロジェクト
    • 使い方もさまざま
  • PM は様々な仕事をトラッキングするため Confluence のページでテーブル作った -> 情報がすぐ古くなる
  • -> クロスプロジェクトボードを作る!
  • 「ボードを歩く」Boardwalk
4.
  • SRE チーム
  • IMA というマイクロサービス作った
    • HOT チケットができると Hipchat にルームができる
    • Bluejeans も
    • StatusPage: https://ja.atlassian.com/software/statuspage
    • 各サービスへのリンクを Jira の課題に集約(自動的に記載される)
5. 開発情報のボード
  • Fusion Team (Jira Software と開発ツールの連携を作る)
  • ブランチの進行と Jira のステータスを重ね合わせると状況がよくわかる
  • development[pullrequests].all > 0
  • カードの色と組み合わせて視覚的に
印象に残った話

1 つめのチームに関しては、物理カンバンを使っていて、タスクのふせんをなぜか一本の道のようにつなげてボードにしていたチームの話。
道は途中で枝分かれしたり合流したりで、要所要所になぜかポケモンが。
またポケモンボール型のマグネットも用意されていて、タスク消化していってポケモンのところまで到達したらポケモンボール使ってポケモン GET!
→ちょっとした達成感のお祝いでみんなでコーヒー飲んだりする
みたいな話をされてました。

f:id:dackdive:20180306104701p:plain

また 2, 4 のチームにあるように、Atlassian では製品間をマイクロサービスでつなげて自動化を進めてるらしい。
StatusPage なんてサービスもやってたのか。

5 については、 JQL の development[xxx] というプロパティすら知らなかったんですが、やってみるとたしかにできました。
Bitbucket などと連携した状態で

development[pullrequests].open > 0

などとすると、「ひもづく PR でオープン状態のものがあるチケット」のような条件指定ができます。

f:id:dackdive:20180203013956p:plain

お話では、キャプチャのようにかんばんのカードの色の条件にこれを使っていて、Jira のステータスとソースコードの状況に乖離がないかを可視化してるとのことでした。

また、3 のチームの話に出てくる Boardwalk ってのがどういった目的で、どれくらいの頻度でやるのかいまいち理解できてなかったんですが
懇親会の冒頭にお話を伺うことができました。

  • 毎回のスプリント期間中に定期的に実施する。スプリントの真ん中あたりに設定してる
    • 前半はプランニング、後半はふりかえりがあるし
  • バックロググルーミングと似てるんだけど、「バックロググルーミングのような細かい話まではしないかな」とのこと
  • そのストーリーを「なぜやるか」というところを、デザイン・開発・マーケみんな集まったところで共有する
    • やる目的を共有し、全員が共感した状態で作らないとモチベーション上がらない

だいたいこんなような回答だったかと。
ググると Jason さんの記事が出てきますね。

また Jason さんからは他にも

  • かんばんはデジタル(Jira)で管理してるところもアナログ(物理)で管理してるところも、あるいは併用してるところもある。傾向として若者が多いところだと物理かんばんが多い
  • Face to Face のコミュニケーションってやっぱり大事。Jira や Confluence 上でもメンションつけてやり取りはたしかにできるけど。メンションつきで長文で重要な情報が頻繁にやり取りするようだと顔を突き合わせての対話が足りてないという兆しなんじゃないか

といった面白い話が聞けました。

総じて、対話によるコミュニケーションや、計画通りやるだけじゃなく仕事に楽しさを持たせるっていうのを大事にしてるんだなと感じました。

babel-preset-envの使い方(babel-preset-es2015からの移行)

はじめに

ES2015 の変換に babel-preset-es2015 を使っているプロジェクトで、npm install 時に

npm WARN deprecated babel-preset-es2015@6.24.1: 🙌  Thanks for using Babel: we recommend using babel-preset-env now: please read babeljs.io/env to update!

という警告が出ており、あーたしかに babel-preset-env を使った方がいいってどこかで聞いたなと思いつつ env の設定のしかたを調べられていなかったんですが、ようやく少し調べました。
そのときのメモ。

公式の

に加え、Qiita のこちらの記事も参考になりました。

注)この記事を書いた 2018/1/18 時点で Babel のバージョン 7 はベータ版だったので、6 系での設定です。
バージョン 7 での変更点は最後に書いてます。

最初にまとめ

  • babel-preset-es2015 から babel-preset-env にただ切り換えるだけであれば、babel-preset-xxx 部分を置き換えるだけで済む
  • babel-preset-env は何もオプションを指定しなければ、全部 ES5 の記法にトランスパイルする
  • が、モダンなブラウザでは Class など ES2015+ の構文に対応しているので、サポート対象ブラウザに応じて必要なところまでトランスパイルするのが望ましい
  • babel-preset-env では targets オプションで対象ブラウザを指定することが可能
// .babelrc(例)
{
  "presets": [
    ["env", {
      "targets": {
        "browsers": ["last 2 versions", "safari >= 7"]
      }
    }]
  ]
}

(2018/5/11追記)

上記の例の last 2 versions はあまりよくないらしい。という記事を読んだ。

last 2 versions - @jamiebuilds

(追記ここまで)


設定方法

babel-preset-env をインストール

babel-preset-es2015 をアンインストールして、かわりに babel-preset-env を入れます。

$ yarn remove babel-preset-es2015
$ yarn add -D babel-preset-env

.babelrc を修正

まずは単純に es2015 を env に置き換えます。

 {
-  "presets": ["react", ["es2015", { "modules": false }]],
+  "presets": ["react", ["env", { "modules": false }]],
   "plugins": [
     "transform-class-properties",
     "transform-object-rest-spread",
    "react-hot-loader/babel"
  ]
}

webpack で Tree Shaking をするための modules: false というオプションもそのままで大丈夫のようです。
https://babeljs.io/docs/plugins/preset-env/#modules

オプションで対象ブラウザを指定する

https://babeljs.io/docs/plugins/preset-env/#targets
targets というオプションで対象のブラウザを指定できます。
対象のブラウザを指定すると、そのブラウザで対応している構文についてはそのままでトランスパイルせず、未対応の構文のみトランスパイルするという挙動になるようです。

内部的には compat-table のデータを参照しているらしい。

targets の指定方法にはいくつか種類があって、

1) 対象ブラウザとバージョンを決め打ち

{
  "targets": {
    "chrome": 52
  }
}

2) targets.browsers を指定し、クエリを書く(内部的には browserslist を使っている)

"targets": {
  "browsers": ["last 2 versions", "safari 7"]
}

もしくはこれらを複数指定することができます。あとは node オプションで対象の Node のバージョンが指定できたり。
なお

Note, browsers’ results are overridden by explicit items from targets.

とあるので、 browsers の内容は個別に指定したものがあった場合上書きされます。


最終的にこうなった

というわけで、私は一旦こうしました。

// before
{
  "presets": ["react", ["es2015", { "modules": false }]],
  "plugins": [
    "transform-class-properties",
    "transform-object-rest-spread",
    "react-hot-loader/babel"
  ]
}
// after
{
  "presets": [
    "react",
    ["env", {
      "targets": {
        "browsers": ["last 2 versions"]
      },
      "modules": false
      }
    ]
  ],
  "plugins": [
    "transform-class-properties",
    "transform-object-rest-spread",
    "react-hot-loader/babel"
  ]
}

個人の適当なリポジトリで試しただけなので、対象ブラウザとかは深く考えてないです。

参考:

PR はこれ

Babel 7 での変更点

Babel 7 から babel-preset-env も Babel 本体のリポジトリに移動になったので、パッケージ名が @babel/preset-env に変わります。

参考:https://github.com/babel/babel/tree/master/packages/babel-preset-env

$ npm install @babel/preset-env --save-dev

targets の指定方法は変わってないぽいです。

IDDD本もくもく読書会メモ#5(第10章 集約)

メモが滞ってる。。。第10章「集約」のメモを。

過去メモ
教材

CodeZine の記事 も第9章から更新が止まってしまっていてつらい。

メモ

10.2 ルール:真の不変条件を、整合性の境界内にモデリングする

  • 不変条件:常に整合性を保っている必要のあるビジネスルールのこと
  • 不変条件について議論する際の整合性は、トランザクション整合性のことを指す
  • 集約はトランザクション整合性の境界

整合性の境界の論理的な意味は、「その内部にあるあらゆるものは、どんな操作をするにかかわらず、特定の不変条件のルールに従う」ということだ。

10.3 ルール:小さな集約を設計する

  • モデルの一部分をエンティティとしてモデリングしたくなったらどうするか
    • その部分自体が今後も変わり続けるものなのか、あるいは変更したくなったときに丸ごと置き換えれば済むのか考える
    • 丸ごと置き換えられるならエンティティではなく値オブジェクト
  • ユースケースを鵜呑みにするな

10.4 ルール:他の集約への参照には、その識別子を利用する

  • 集約の合成構造?
  • 集約から別の集約(へのルート)への参照を持つのはOK
  • 1つのトランザクションで参照する側とされる側の両方を更新してはならない
  • 集約そのものへのポインタではなく、一意な識別子へのポインタを保持する
    • Product ではなく ProductId (値オブジェクト)を持つ

10.5 ルール:境界の外部では結果整合性を用いる

  • ひとつの集約上でコマンドを実行するときに、他の集約のコマンドも実行するようなビジネスルールが求められるのなら、その場合は結果整合性を使う
  • 一方のインスタンスが変更されてから、もう一方のインスタンスが変更されるまでの遅延が、どの程度許容されるかをドメインエキスパートにたずねてみよう
  • 現実的な手段としては、トランザクションの最後にドメインイベントを発行する
  • 誰の役割かを考える

10.6 ルールに違反する理由

10.7 発見による知見の獲得

  • 例:バックログアイテム:タスク = 1 : n の関係にある
  • 一般的な利用シナリオを頭に浮かべながら試算する、という話が書かれている
  • バックログアイテムの状態とタスクの残作業の総計は結果整合性にすべきか?
    • -> タスクの数がどれだけあっても、バックログアイテムの状態が変わるのは、常に最後の見積もりになる
      • バックログアイテムの状態が変わらない限り version が変わらないので、結果整合性でなくロックしても問題ない
  • メモリの消費

10.8 実装

  • 集約のパーツは可能な限り、エンティティではなく値オブジェクトにする
public class Product extends ConcurrencySafeEntity {
    private Set<ProductBacklogItem> backlogItems;
    private String description;
    private String name;
    private ProductDiscussion ProductDiscussion; // VO
    private ProductId productId; // VO
    private TenantId tenantId; // VO
}

Q

  • 誰の役割かを考えてトランザクション整合性か結果整合性かを決める、というのは絶対なの?
    • -> あくまで指針の1つと捉えておくのが良い


資料

Nodeのバージョン管理をndenvにしたけどうまくバージョンが切り替わらなかったときのメモ

メモ。
これまでは Homebrew でインストールした Node を使っていたが、バージョンを上げたくて複数バージョン管理できるツールを取り入れることにした。
Node のバージョン管理ツールはちょっと調べた限り

あたりがあったが、元々 Python のバージョン管理に pyenv を使っていた過去もあり同じような使い勝手の ndenv にした。
またこの機会に anyenv もインストールし、ndenv は anyenv 経由でインストールすることにした。

n も一瞬触ってみたが、「プロジェクトごとに Node のバージョンを固定してバージョンを自動的に切り替える」をやる方法がわからず ndenv に乗り換えた。


インストール手順

こちらの記事が詳しい。


anyenv と ndenv のインストール

$ git clone https://github.com/riywo/anyenv ~/.anyenv

で anyenv をインストールした後、 .zshrc

export PATH="$HOME/.anyenv/bin:$PATH"
eval "$(anyenv init -)"

を追記しておく。今回のみシェルを再起動するため

$ exec $SHELL -l

を実行する。

最後に ndenv をインストールする。

$ anyenv install ndenv
$ exec $SHELL -l


ndenv で特定バージョンの Node をインストール

$ ndenv install -l
Available versions:
  v0.1.14
  v0.1.15
  v0.1.16
  ...

でインストールしたいバージョンを探し

$ ndenv install v8.9.3

のようにバージョンを指定してインストールする。

$ ndenv global v8.9.3
$ ndenv rehash
$ ndenv versions
  system
* v8.9.3 (set by /Users/yamazaki/.anyenv/envs/ndenv/version)


トラブルシューティング

$ ndenv versions
  system
* v8.9.3 (set by /Users/yamazaki/.anyenv/envs/ndenv/version)
$ node -v
v6.9.4

切り替わってない...?
(v6.9.4 は以前 Homebrew 経由でインストールしたバージョン)

$ which node
/usr/local/bin/node

Homebrew でインストールした Node が優先されているようだ。
似たような問題に遭遇している人がいた。

Homebrew をアップデートしたら ndenv の node が使えなくなった | WEBMAN

回避策として、記事に記載されている通り、Homebrew の Node をアンインストールした。

$ brew uninstall --ignore-dependencies node
$ exec $SHELL -l
$ which node
/Users/yamazaki/.anyenv/envs/ndenv/shims/node
$ ndenv versions
* v8.9.3 (set by /Users/yamazaki/.anyenv/envs/ndenv/version)

which node のパスが変わっているので無事にアンインストールできたっぽい。
また ndenv versions したときに system が表示されなくなった。


npm にまだ問題があった

$ which npm
/usr/local/bin/npm

npm コマンドが残っていた...

あたりを参考に

$ npm uninstall -g npm
$ rm -rf /usr/local/lib/node_modules
$ brew prune

を実行してきれいになった。本来は Node より先に npm をアンインストールすべきだったらしい。

$ which npm
/Users/yamazaki/.anyenv/envs/ndenv/shims/npm

npm のパスが変わったのでこれでおそらく大丈夫。

# v6.9.4 は ndenv install 済みとして
$ ndenv local v6.9.4
$ node -v
v6.9.5
$ npm -v
3.10.10

$ ndenv local v8.9.3
v8.9.3
$ npm -v
5.5.1