型のプロパティを拡張する。
型で条件付きで拡張すれば良い。
const MyEmpty = Symbol("MyEmpty"); type Empty<T> = { [P in keyof T]:P extends "hoge" ? T[P] | typeof MyEmpty : T[P] } type ExRoomInfo = Empty<RoomInfo>
サブモジュールがクローンされない。
以下を参照した。
gitでクローンと同時にサブモジュールを初期化、アップデートする – IsaB
cloneしてから
git submodule update --init --recursive
で良いようだ、 それかそもそも
--recursive
をつけてcloneしておく。
jsconfig.json
Visual Studio Codeはjsconfig.jsonのあるファイルをルートにしてくれる。 JSDoc形式で書かれた型情報を認識
jsonconfig.jsonの設定は以下を参照。
VS CodeでJavaScriptアプリを作成する上で知っていると便利(?)なこと (2/3):Visual Studio CodeでWebアプリ開発を始めよう - @IT
iOS関連
manifestは読み込めるが、アイコンは無視されるのでメタタグで定義する必要がある(apple-touch-icon.pngというファイル名で根っこにおいておくとヘッダーに記述しなくて良いというのは本当だろうか。)。 htmlの根っこにおく。読み込まれないかは、safariのインスペクタで確認。ちなみにインスペクタは実機をmacにつなげて無いとみえない‥。 iOS13から強制終了できるようになった。 ファビコン用のものを定義しておくと、(icon)、共有シートに反映される。
アイコンは例えば
<link rel="apple-touch-icon" sizes="192x192" href="./logo.png" />
のような感じで。
manifestが読み込まれているかはchromeのインスペクタのApplicationタグやコンソールのエラーも参考になった。
あとサービスワーカーを入れないとうまくうごかなかったと記憶している。
Parcell
以下を参照した。
インストール
npm install --save-dev parcel-bundler
使い方
npx parcel index.html
とするだけで依存関係をたどってdistディレクトリに吐き出される。
webサーバ(ポートは自動)が起動し、 Hot Module Replacementに対応しているのであとはファイルを更新するたびに更新が反映される。
オプションは-pでポート指定、––openでブラウザも起動、watchはwebサーバは起動せず更新のみ反映、jsのみも可 特にTypeScriptは.tsを指定しても、htmlに.tsを直接指定して入れ込んでも可能。 プロダクション版を作るにはbuildをつける。 --out-dirや-dで出力先は変更可能
compositionAPI ストアのプロバイドとインジェクション
より明確にストアの書き方がわかったので書いておく。
キーを何か用意
const StoreSymbol = Symbol()
親のstoreをもっているものがprovideする。
// sotreを持っている側がprovideする。 export function provideStore(store) { provide(StoreSymbol, store) }
子はインジェクトで取り出す。
export function useStore() { const store = inject(StoreSymbol) if (!store) { // throw error, no store provided } return store }
ストアと言っているものは単なるオブジェクト(をreactive関数によって包んだもの)
しかし、これは便利な反面、皮を被ったシングルトンともいえなくない‥。
compositionAPIの初歩
ここの説明がそもそもわかりやすかった。
vue-composition-api-rfc.netlify.app
そこに書いてあるコードを借りてくると、こんな感じでuse関数(useは実際は何でも良い)を書いて、
function useCreateFolder (openFolder) { // originally data properties const showNewFolder = ref(false) const newFolderName = ref('') // originally computed property const newFolderValid = computed(() => isValidMultiName(newFolderName.value)) // originally a method async function createFolder () { if (!newFolderValid.value) return const result = await mutate({ mutation: FOLDER_CREATE, variables: { name: newFolderName.value } }) openFolder(result.data.folderCreate.path) newFolderName.value = '' showNewFolder.value = false } return { showNewFolder, newFolderName, newFolderValid, createFolder } }
そういう関数達を用意して
export default { setup() { // ... } } function useCurrentFolderData(networkState) { // ... } function useFolderNavigation({ networkState, currentFolderData }) { // ... } function useFavoriteFolder(currentFolderData) { // ... } function useHiddenFolders() { // ... } function useCreateFolder(openFolder) { // ... }
setup関数でこれらをcompositして使う。
export default { setup () { // Network const { networkState } = useNetworkState() // Folder const { folders, currentFolderData } = useCurrentFolderData(networkState) const folderNavigation = useFolderNavigation({ networkState, currentFolderData }) const { favoriteFolders, toggleFavorite } = useFavoriteFolders(currentFolderData) const { showHiddenFolders } = useHiddenFolders() const createFolder = useCreateFolder(folderNavigation.openFolder) // Current working directory resetCwdOnLeave() const { updateOnCwdChanged } = useCwdUtils() // Utils const { slicePath } = usePathUtils() return { networkState, folders, currentFolderData, folderNavigation, favoriteFolders, toggleFavorite, showHiddenFolders, createFolder, updateOnCwdChanged, slicePath } } }
refは値のリアクティブ化で、reactiveはオブジェクトの場合と思っておくことにする。
パッケージの公開
以下を参考にした。 qiita.com
まず、npmのユーザーを登録しておく。 npm | build amazing things
で npm addUserでユーザを紐付けておく。
.npmignore を用意して、公開に不要なもの(tsファイルとか)を指定しておく。
package.jsonのバージョン(version)を指定。 "private"は公開したくないものが公開されないようにfalseにしているが、これをtrueに。
テストファイルを見せたくないのでsrcからテストコードをtestフォルダに分けて package.jsonでのコマンドを
"build": "tsc src/index.ts --outDir ./dist --declaration true", "test": "tsc test/test.ts;node ./test/test.js"
のような感じにして出力先をわけてみた。declarationオプションは型情報*.d.tsを作るのに必須。
あとはnpm publishで公開できる。
公開したら自分のプロフィールのパッケージのところに出てくる。 これでプロジェクトでnpm installしたりできるようになっている。
公開したくないものを公開しないように注意。
ABC propsでオブジェクトを指定する。
type AlertCompletedBlock = (index: number) => void; interface Alert { display: number; completedBlock: AlertCompletedBlock | null; title: string; desc: string; buttonTitles: string[]; } const alertInit:Alert = { display:0, title:"", desc:"", completedBlock:null, buttonTitles:["OK"] }
として
interface Props { alert:Alert } export default defineComponent({ name:"Alert2", props:{ alert:{type:Object, require:true, 'default':() => alertInit} },
のようにObjectとしてdefault値を関数にして渡してやる必要があった‥。