クロコめも2。

ただのめもー

そろそろイラレを卒業したいと

特に絵を描くわけじゃないんだけどね!

Sketch使い方メモ

ベクターツールを使う

ベクター編集モードに切り替える

  • insert -> Vectorを選ぶ。ショートカットは「v」
  • 既存のパスをダブルクリック
  • 編集を終える -> 右にあるfinish Editingボタンを押す。もしくは「a」ボタン押したりすると解除される

ポイントの編集

  • 追加:ベクター編集モードの時にポイント追加したいパスをクリック
  • 削除:削除したいポイント選択中にdeleteボタン

ポイントから出てる足の編集

  • 片方だけ編集-> commandボタンを押しながら編集
  • リセット-> ポイントをダブルクリック

パスを閉じる、開ける

  • 右にある「Open Path」「Close Path」ボタンを押す。(選択中のパスがどういう状態かでボタン名が切り替わる)

文字をパスにして編集

  • 挿入した文字を選択して右クリック「convert to outlines」を選んでアウトライン化
  • アウトライン化した文字をダブルクリックでベクター編集モードに->編集可能

typescriptでvueのプロジェクトを作るときに

素敵。最高。 qiita.com

よくわからない点

  • watchの書き方どうなるんだろ?
  • vuexとか組み込むのはやっぱつらいのかな?つか普通にmvc的にしてコールバック登録する形でいいか
  • data()の中にあるやつをもう一回宣言する必要があるのなんとかならないかな?
  • tsd非推奨でtypings?使えって言われたけど、まだちゃんと調べてないからよくわからない

あと感じたこととして、

intellijでは動作遅くてやってられない。

試しにvisual studio code使ってみたら軽すぎて鼻水でた。

typescript使うならこっちかなー。

プロジェクトの雛形2016年2月版!

前回雛形との違い

  • index.template.html.
  • Split files vendor.js app.js and app.css.
  • To compress the source using the UglifyJs.
  • Use bourbon and bourbon-neat.

setup directory and node_modules

mkdir -p {build,test/{unit,e2e},src/{components,views/app,filters,directives,assets/{js,style,images,html}}}
npm init -y
npm i -g webpack webpack-dev-server mocha babel-core babel-loader power-assert node-sass
npm i -S vue vuex
npm i -D babel-core babel-loader webpack style-loader css-loader node-sass sass-loader html-loader mocha mocha-loader babel-plugin-add-module-exports babel-plugin-transform-runtime babel-polyfill babel-preset-es2015 babel-preset-stage-2 babel-runtime file-loader url-loader espower-babel power-assert lodash
npm i -D extract-text-webpack-plugin html-webpack-plugin@2
npm i -D node-bourbon node-neat

Please run with the "sudo" If the permission error has occurred

.babelrc

{
  "presets": ["es2015", "stage-2"]
}

webpack.config.js

var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');

var contentBase = __dirname + '/build';
var cssLoader = ExtractTextPlugin.extract('style', 'css?sourceMap!sass')

var htmlWebpackPlugin = new HtmlWebpackPlugin({
    filename: 'index.html',
    template: 'src/assets/html/index.template.html'
});

var pkg = require('./package.json');
var vendor = Object.keys(pkg.dependencies);

var options = {
    entry: {
        app: ["./src/assets/js/app.js", "./src/assets/style/app.scss"],
        vendor: vendor,
    },
    output: {
        path: contentBase + '/',
        filename: "js/[name].js",
        contentBase: contentBase + '/build'
    },
    resolve: {
        alias: {
            vue: "vue/dist/vue",
            lodash: "lodash"
        },
        modulesDirectories: ['node_modules', 'src/', 'src/assets/js/', 'src/assets/style/', 'src/views/', 'src/directives/', 'src/filters/', 'src/components/'],
        // require()するときに拡張子を省略可能にします
        extensions: ['', '.webpack.js', '.web.js', '.js']
    },
    devServer: {
        contentBase: "./build",
    },
    module: {
        preloaders: [],
        loaders: [
            {
                test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
                loader: "url-loader?limit=10000&minetype=application/font-woff"
            },
            {
                test: /\.png$/,
                loader: "url-loader?limit=100000"
            },
            {
                test: /\.jpg$/,
                loader: "file-loader"
            },
            {
                test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
                loader: "file-loader"
            },
            {
                test: /\.scss$/,
                loader: cssLoader
            },
            {
                test: /\.html$/,
                loader: "html"
            },
            {
                test: /\.js(x?)$/,
                loader: 'babel-loader?sourceMaps=true'
            }
        ]
    },
    plugins: [
        htmlWebpackPlugin,
        new ExtractTextPlugin('./css/app.css', {disable: false}),
        new webpack.optimize.CommonsChunkPlugin('vendor', 'js/vendor.js')
    ]
};

if (process.env.NODE_ENV === 'production') {
    var defplugin = new webpack.DefinePlugin({
        'process.env': {
            NODE_ENV: '"production"'
        }
    });
    var minplugin = new webpack.optimize.UglifyJsPlugin({
        compress: {
            warnings: false
        }
    });
    options.plugins.push(defplugin);
    options.plugins.push(minplugin);
    options.plugins.push(new webpack.optimize.OccurenceOrderPlugin());
}

module.exports = options;

package.json (scripts property)

  "scripts": {
    "hot": "webpack-dev-server -d --inline",
    "build": "NODE_ENV=production webpack --progress --hide-modules",
    "test": "mocha --compilers js:espower-babel/guess test/unit",
    "e2e": "mocha --compilers js:espower-babel/guess test/e2e"
  },

src/assets/html/index.template.html

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>テンプレート</title>
</head>
<body>
<app>ここにAPPが入ります</app>
</body>
</html>

src/assets/js/app.js

import Vue from 'vue';
import App from '../../views/app'

require('../style/app.scss');

new Vue({
    el:'body',
    components: {App}
});

src/assets/style/app.scss

@import "~bourbon";
@import "~bourbon-neat";

body {
  @include outer-container();
  background-color: #000000;
  color: yellow;
  .header {
    @include span-columns(3);
    background-color: #999999;
  }
  .navigator {
    @include span-columns(5);
    background-color: #333333;
  }
  .footer {
    @include span-columns(12);
    background-color: #666666;
  }
}

src/views/app/index.js

export default {
    template: require("./template.html")
}

src/views/app/template.html

<div class="header">ヘッダー</div>
<div class="navigator">ナビゲーター</div>
<div class="contents">コンテンツ</div>
<div class="footer">フッター</div>

vuejsにてコンポーネントのdataの中に_で始まる値を定義してはいけない

タイトルで本エントリはほぼ終了

たとえばこういうこと

sample-component/index.js

export default {
    template: require('./template.html'),
    data() {
        return {
            _aaa: 100,
            bbb: 200

        }
    },
    computed: {
        data1 () {
            return this._aaa;
        },
        data2 () {
            return this.bbb;
        }
    }
}

sample-component/template.html

<div>
    <h1>サンプルコンポーネント</h1>
    <div>data1:{{data1}}</div>
    <div>data2:{{data2}}</div>
</div>

これ画面でみるとdata2は200と表示されますが、data1は何も表示されません。

なぜかは知りません。

内部的なことは暇があったらちゃんと調べますが、とりあえず

vuexのソースを見てて理解できないとこ。その1

src/util.js

/**
* Deep clone an object. Faster than JSON.parse(JSON.stringify()).
*
* @param {*} obj
* @return {*}
*/

export function deepClone (obj) {
    if (Array.isArray(obj)) {
        return obj.map(deepClone)
    } else if (obj && typeof obj === 'object') {
        var cloned = {}
        var keys = Object.keys(obj)
        for (var i = 0, l = keys.length; i < l; i++) {
            var key = keys[i]
            cloned[key] = deepClone(obj[key])
        }
        return cloned
    } else {
        return obj
    }
}

for文の中にある「l」はなんの意味があるんやろうか?

    for (var i = 0; i < keys.length; i++) {

じゃあだめなんやろか?

パフォーマンスの問題かと思って50万回ぐらい実行したタイムを比較したら特に違いが見られなかったんだよねぇー

んで、書式的にもlが理解できない。

var でもない。let をつけたらコンパイルエラー。

何これ?

vuejsプロジェクト雛形を楽に作りたい

2日経つと前に何作ってたか忘れてまた最初からやりたくなる病。
そのために作り始めを早めるメモ

主に組み込むものとバージョン

  • node(v5.4.0)
  • npm(3.5.3)
  • vue(^1.0.14)
  • vuex(^0.2.0)
  • es6
  • mocha(2.3.4)
  • power-assert(1.2.0)

手順概要

  1. ディレクトリ用意
  2. いろいろインストール
  3. 環境に必要なもの用意
  4. 小さいvuexサンプル
  5. 最小テスト

手順詳細

ディレクトリ用意

# ディレクトリ作成
mkdir プロジェクトのフォルダ
cd プロジェクトのフォルダ
mkdir -p {build,test/{unit,e2e},src/{components,views/app,filters,directives,assets/{js,style,images}}}

いろいろインストール

npm init --y
npm i -g webpack webpack-dev-server mocha babel-core babel-loader power-assert
npm i -S vue vuex
npm i -D babel-core babel-loader webpack style-loader css-loader sass-loader html-loader mocha mocha-loader babel-plugin-add-module-exports babel-plugin-transform-runtime babel-polyfill babel-preset-es2015 babel-preset-stage-2 babel-runtime file-loader url-loader espower-babel power-assert

環境に必要なもの用意

.babelrc

{
  "presets": ["es2015", "stage-2"]
}

webpack.config.js

module.exports = {
    entry: {
        app: "./src/assets/js/app.js"
    },
    output: {
        path: './build/js',
        publicPath: '/js/',
        filename: "[name].js"
    },
    resolve: {
        alias: {
            vue: "vue/dist/vue"
        },
        modulesDirectories: ['node_modules', 'src/', 'src/assets/js/**', 'src/assets/style/**', 'src/views/**', 'src/directives/**', 'src/filters/**', 'src/components/**'],
 // require()するときに拡張子を省略可能にします
 extensions: ['', '.webpack.js', '.web.js', '.js']
 },
 devServer: {
            contentBase: "./build",
        },
 module: {
            preloaders: [],
            loaders: [
                {
                    test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
                    loader: "url-loader?limit=10000&minetype=application/font-woff"
                },
                {
                    test: /\.png$/,
                    loader: "url-loader?limit=100000"
                },
                {
                    test: /\.jpg$/,
                    loader: "file-loader"
                },
                {
                    test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
                    loader: "file-loader"
                },
                {
                    test: /\.scss$/,
                    loader: "style!css!sass"
                },
                {
                    test: /\.html$/,
                    loader: "html"
                },
                {
                    test: /\.js(x?)$/,
                    loader: 'babel-loader?sourceMaps=true'
                }
            ]
        }
 };

package.jsonのscriptsの中身を書き換え

  "scripts": {
    "hot": "webpack-dev-server -d --inline",
    "test": "mocha --compilers js:espower-babel/guess test/unit",
    "e2e": "mocha --compilers js:espower-babel/guess test/e2e"
  },

上から、
npm run hotデバッグ用のサーバ起動するためのもの
npm testでtest/unit配下に格納したテストを実行するもの
npm run e2eでe2eテストに格納したテストが動くはず(今回はやらない)

小さいvuexサンプル

前段その1サーバ起動確認

build/index.html

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>sample</title>
</head>
<body>
    <div id="app">this is app</div>
    <script type="text/javascript" src="js/app.js" charset="utf-8"></script>
</body>
</html>

src/assets/js/app.js

console.log('hoge');

ここでコンソール上でnpm run hotを実行して下記URLで"this is app"、デバッグコンソールに"hoge"と表示されればここまでOK

http://localhost:8080/

前段その2小さいvueコンポーネント

build/index.html書き換え

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>sample</title>
</head>
<body>
<app></app>
<script type="text/javascript" src="js/app.js" charset="utf-8"></script>
</body>
</html>

src/assets/js/app.js書き換え

import Vue from 'vue'
import App from '../../views/app'

new Vue({
    el: 'body',
    components: { App }
});

src/views/app/index.js

export default {
    template: require('./template.html')
}

src/views/app/template.html

<div>this is app view</div>

http://localhost:8080/にthis is app viewと表示されていればOK

小さいvuexサンプル(vuexさん公式のcounterサンプルを丸パクリします)

src/views/app/index.js書き換え

import Counter from '../../components/counter'

export default {
    template: require('./template.html'),
    components: {
        "counter": Counter
    }
}

src/views/app/template.html書き換え

<counter></counter>

src/components/counter/index.js

import store from '../../assets/js/store'

export default {
    template: require('./template.html'),
    computed: {
        count () {
            return store.state.count
        }
    },
    methods: store.actions
}

src/components/counter/template.html

<div>
    Clicked: {{ count }} times
    <button @click="increment">+</button>
    <button @click="decrement">-</button>
    <button @click="incrementIfOdd">Increment if odd</button>
    <button @click="incrementAsync">Increment async</button>
</div>

src/assets/js/store/index.js

 import Vue from 'vue'
 import Vuex from 'vuex'

 Vue.use(Vuex);

 // mutation types
 // optional if you don't like constants.
 const INCREMENT = 'INCREMENT';
 const DECREMENT = 'DECREMENT';

 // root state object.
 // each Vuex instance is just a single state tree.
 const state = {
     count: 0
 };

 // actions are what components will be able to
 // call as store.actions.xxx
 // note these are not the final functions the
 // components will be calling.
 const actions = {

     // for simple actions that just dispatches a single mutation,
     // we can just provide the mutation type.
     increment: INCREMENT,
     decrement: DECREMENT,

     // for a normal action function, it always recieves the store
     // instance as the first argument, from which we can get the
     // dispatch function and the state object. Any additional
     // arguments will follow the store argument.
     incrementIfOdd: ({ dispatch, state }) => {
         if ((state.count + 1) % 2 === 0) {
             dispatch(INCREMENT)
         }
     },

     // Same thing for async actions.
     incrementAsync: ({ dispatch }) => {
         setTimeout(() => {
             dispatch(INCREMENT)
         }, 1000)
     }
 };

 // mutations are operations that actually mutates the state.
 // each mutation handler gets the entire state tree as the
 // first argument, followed by additional payload arguments.
 // mutations must be synchronous and can be recorded by middlewares
 // for debugging purposes.
 const mutations = {
     [INCREMENT] (state) {
         state.count++
     },
     [DECREMENT] (state) {
         state.count--
     }
 };

 // A Vuex instance is created by combining the state, the actions,
 // and the mutations. Because the actions and mutations are just
 // functions that do not depend on the instance itself, they can
 // be easily tested or even hot-reloaded (see counter-hot example).
 // 
 // You can also provide middlewares, which is just an array of
 // objects containing some hooks to be called at initialization
 // and after each mutation.
 export default new Vuex.Store({
     state,
     actions,
     mutations
 })

http://localhost:8080/にカウンターが表示されていればOK

最小テスト

test/unit/store-test.js

 import assert from 'power-assert';

 import store from '../../src/assets/js/store'

 describe('storeのテスト', () => {

     it('mutationsのincrement処理を実行するとstateのcountが増える', () => {
         let before = store.state.count;
         store.actions.increment();
         let after = store.state.count;
         assert(before < after);
     });

     it('mutationsのdecrement処理を実行するとstateのcountが減る', () => {
         let before = store.state.count;
         store.actions.decrement();
         let after = store.state.count;
         assert(before > after);
     });

 });

npm testで実行して結果が表示されればOK

assert(before === after)などに書き換えてエラーを出してみるのもよいかも

es6のファイル名問題。

es6でクラスを直接export defaultする場合、ファイル名はクラスと同じ名前にしておくべきか?

言い換えると「大文字で始まるファイル名にすべきか?」


今までのjsの文化ではファイル名は全て小文字始まりである。

理由はhtmlの世界は大文字小文字の区別がないからファイル名も小文字で統一しておく。
あとは「みやすさ」?


しかし昨今のjsはwebpackの利用が前提だったりで、その制約いる?みたいな状態でもある。

airbnbのes6コーディング規約では大文字始まりのキャメルケースらしい。


つか、そうしたい。

しかし、昔ながらのじゃばすくりぷたーさんが大文字始まりのファイル名は拒絶反応を起こしちゃう。


うーむ。