yarn と parcel と riot を使って簡単な webサイトを作ってみた

yarn と parcel で roitを使ってみました。
yarnについてはこちらの記事を、parcelについてはこっちを診てもらうとすぐに理解できます。

ささっとやったことをメモしておこうと思います。

※参考
https://qiita.com/soarflat/items/3e43368b2d767c730781

yarnを導入

僕の場合、npmをndenvを使ってましたので、npmでインストールしました

$ npm install --global yarn


node のバージョンにより、warningができますが、気持ち悪いので、v8.0.0にしました。

warning You are using Node "7.9.0" which is not supported and may encounter bugs or unexpected behavior. Yarn supports the following semver range: "^4.8.0 || ^5.7.0 || ^6.2.2 || >=8.0.0"


インストールしたらpathを通します。

$ vim ~/.bash_profile など


export PATH="$HOME/.yarn/bin:$PATH"



読み込んだら、

yarn -v
yarn init

で、バージョンを確認し、initします。

parcelを入れる

$ yarn add parcel-bundler 

実行すると、yarn.lockファイルと、npmと同じように、node_moduleが作成されます。
yarnのコマンドはここに乗ってます
https://qiita.com/morrr/items/558bf64cd619ebdacd3d
ありがとうございます。


riot やbabelを入れる

参考
https://qiita.com/jude/items/704c6d8603f0f5057b7e

yarn add riot
yarn add --dev babel-preset-es2015-riot

dir構成

- root
  - node_module
  - public(defaultだとdist)
  - src
    - images
    - javascript
      - module
      - tags
        - layouts
          - Top.tag
        - App.tag
      - app.js
    - stylesheet
      - styles.scss
    - index.html

html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>title</title>
</head>
<body>
  <App></App>
  <script src="app.js"></script>
</body>
</html>


app.js

import '../stylesheets/main.scss'

import riot from 'riot'
import './tags' // riotによりprecompileされたファイルを指定しとく

riot.mount('*')


App.tag

<App>
  <Top />
  <script>
    import riot from 'riot'
  </script>
</App>


Top.tag

<Top>
  <p>{ text }</p>
  <script>
    this.text = "トップ"
  </script>
</Top>


scssをcssに

yarn add node-sass --dev


ここまででビルドしてみる

riot src/javascripts/tags src/tags.js

parcel src/index.html -d public


確認

public以下にfileが作成されており、

http://localhost:1234/

でブラウザで確認する

まとめ

結構簡単にできたかと思います。そこまで大掛かりなプロジェクトでない場合は、parcelがいいかもしれません。


nodejs aws-sdkでs3 ファイルアップロード とcloudfront create invalidation

nodejs で aws s3 にアップロードする方法です。
webpackを使ってたので、npmでs3-plugin-webpackを使ってdeployを試みましたが、設定ファイルのこのプラグインの設定を入れるとbuildが終わらず、まったくアップロードできなかった(materializeを使ってますが、そこのコンパイルで全く進まなくなる)ので、aws-sdkを使って自作でスクリプトを作成しました。

前提

  • aws s3の設定がされていること
  • cloudfrontを使う前提で distributionの設定がされていること
  • iamの設定(s3 の使用するバケットへのputの許可、cloudfrontアクセスの許可を持っている)がされていること

s3へのアップロード

sdkを入れます

インストール

$ npm install aws-sdk --save or --savve-dev



keyなど設定をべた書きしたくないのでdotenvを使いました

$ npm install dotenv --save-dev



s3にファイルを上げる時、content-typeがないと、ちゃんとファイルを認識してくれないので、mimetypeを読んで、指定してアップするため

$npm install mime-type --save-dev



.envファイルを作り、AWS_ACCESS_KEY_IDなどの設定を書く

AWS_ACCESS_KEY_ID = xxxxxxxxxxxxxxxxxx
AWS_SECRET_ACCESS_KEY = xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
CLOUDFRONT_DISTRIBUTION_ID = xxxxxxxxxxxxxxxx
CLOUDFRONT_DISTRIBUTION_ID_WWW = xxxxxxxxxxxxxxxx
AWS_REGION = xxxxxxxx
AWS_BUCKET_NAME = xxxxxxxxxxxxxx



読み込み

require('dotenv').config();
var AWS = require('aws-sdk');
var fs = require('fs');
var mime = require('mime-types')



Aws ロード

AWS.config.update({
  accessKeyId: process.env.AWS_ACCESS_KEY_ID, 
  secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, 
  region: process.env.AWS_REGION
});



public配下(状況によって変えて下さい)をバケット直下に配布する

var dir = "./public"
var s3 = new AWS.S3();
fs.readdir(dir, function(err, files){
    if (err) throw err;
    files.filter(function(file){
        var params = {
            Bucket: process.env.AWS_BUCKET_NAME,
            Key: file,
            Body: fs.readFileSync(dir + file),
            ContentType: mime.lookup(file)   
        };
        s3.putObject(params, function(err, data) {
            if (err) console.log(err, err.stack);
            else     console.log(data);
        });
    });
});
  1. fs を使い、localのpublic dir以下のファイルを取得します。
  2. parasのBucketはバケット名、keyは配布されるときのファイル名、bodyがファイルの中身(fs.readFileSyncを使った)、contentTypeはmime-typeで取得したtypeを指定
  3. pubObjectで上げる
    AWS-SDK s3 リファレンス

    cloudfrontにcreate invalidationする(cacheを消す)

僕の場合は、www用(リダイレクト)、wwwなし用(それぞれhttps対応)があるため、一応両方のdistributionに対して、createInvalidationしています。

var cloudfront = new AWS.CloudFront({apiVersion: '2017-03-25'});
var timestamp = new Date();
var string_timestamp = String(timestamp.getTime());

var invalidate_items = ['/*'];
var item_count = invalidate_items.length;
var invalidations = invalidate_items.map(encodeURI)

var distributionIds = [process.env.CLOUDFRONT_DISTRIBUTION_ID, process.env.CLOUDFRONT_DISTRIBUTION_ID_WWW];

distributionIds.forEach( function( distributionId ) {
  var params = {
      DistributionId: distributionId,
      InvalidationBatch: {
          CallerReference: string_timestamp,
          Paths: {
            Quantity: invalidations.length,
            Items: invalidations
          }
      }
  };

  cloudfront.createInvalidation(params, function(err, data) {
      if (err) console.log(err, err.stack);
      else     console.log(data);
  });
});



最初どんなにやってもエラーが出てしまい、うまく行かなかったのですが、invalidate itemに対して、encodeURI したところ、うまくいきました。
CallerReferenceは、timestamp、PathのQuantityは、itemの数、Itemsは、消す対応のitemになります。
AWS-SDK cloudfront リファレンス

全体のソースコード

s3-upload.js

require('dotenv').config();
var AWS = require('aws-sdk');
var fs = require('fs');
var mime = require('mime-types')

AWS.config.update({
  accessKeyId: process.env.AWS_ACCESS_KEY_ID, 
  secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, 
  region: process.env.AWS_REGION
});


var dir = "./public"
var s3 = new AWS.S3();
fs.readdir(dir, function(err, files){
    if (err) throw err;
    files.filter(function(file){
        var params = {
            Bucket: process.env.AWS_BUCKET_NAME,
            Key: file,
            Body: fs.readFileSync(dir + file),
            ContentType: mime.lookup(file)   
        };
        s3.putObject(params, function(err, data) {
            if (err) console.log(err, err.stack);
            else     console.log(data);
        });
    });
});


var cloudfront = new AWS.CloudFront({apiVersion: '2017-03-25'});
var timestamp = new Date();
var string_timestamp = String(timestamp.getTime());

var invalidate_items = ['/*'];
var item_count = invalidate_items.length;
var invalidations = invalidate_items.map(encodeURI)

var distributionIds = [process.env.CLOUDFRONT_DISTRIBUTION_ID, process.env.CLOUDFRONT_DISTRIBUTION_ID_WWW];

distributionIds.forEach( function( distributionId ) {
  var params = {
      DistributionId: distributionId,
      InvalidationBatch: {
          CallerReference: string_timestamp,
          Paths: {
            Quantity: invalidations.length,
            Items: invalidations
          }
      }
  };
  cloudfront.createInvalidation(params, function(err, data) {
      if (err) console.log(err, err.stack);
      else     console.log(data);
  });
});


実行

$ node s3-upload.js(上記を保存したファイル名)

これを、webpackを使ってるなら、packeages.jsonのscript部分に設定すれば、npm runコマンドでbuild後に実行するようにすればOKです。

まとめ

今後は、buildされたファイルをバージョン管理し、rollback的なものもできたらいいと思います。


AWS cloudfront から s3 への Origin Access Identityを使ったアクセス

S3で静的サイトを公開するのですが、その際、直接S3へのアクセスを許可したくないので、特定のディストリビューションでのCloudfront経由のみから「Origin Access Identity」を使い特定アクセスを許可するよう設定を進めていました。

S3の設定で、

  • 静的ウェブサイトホスティング」 = OFF
  • アクセス権限やパケットポリシーなし = Privete

とし、Cloudfrontの設定を下記の記事を参考に設定しました。
https://dev.classmethod.jp/cloud/aws/cloudfront-s3-origin-access-identity/
※大変参考になりました。ありがとうございます。

ただ、設定を完了し、いざ試す際に想定どおり動きませんでした。
S3直アクセスは、403でアクセスできないのはわかるのですが、
Cloudfrontで生成されるURLにアクセスすると、s3のURLへリダイレクトされてしまい、S3に直でアクセスしているのと同じ挙動になってしまいました。

色々と調べてたら、

時間が立てばリダイレクトしなくなる
https://forums.aws.amazon.com/thread.jspa?threadID=216814

ということでした笑。

cloudfrontのディストリビューションは「deployed」になってるのに、その後も時間が少しかかるみたいですね。
落ち着いて待ちましょう。

一応、s3の設定内容の整理です。

静的ウェブサイトホスティング

これは、そのままの意味で、webとして、ホスティングする際に必ずONにする必要があります。
cloudfront経由のみのアクセスを可能にする場合OFFにします。

Amazon S3 での静的ウェブサイトのホスティング

アクセス権限やパケットポリシーについて

アクセス権限は、あくまで、そのパケット自体や、各ファイルに設定するアクセスの権限です。
パケット全体のアクセスをパブリックにせず、特定のファイルのみ、パブリックにすることも可能です。

Cloudfront経由のみのパブリック・アクセスにしたい場合は、パブリックにしない
デスク


Webpackでi18n国際化(locale)のシンプルな方法

webサイトを作成するにあたり、もう言語対応は外せなくなってきました。

webpackで言語対応をする際、色々と迷います。

まずはどういう形でlocale対応をしたいのかで、方法が大きく異なると思います。

今回僕は、英語版と、日本語版をそれぞれコンパイルし、静的ファイルを言語ごとに分ける対応をしてみました。

React等を使用される場合は、storeにtextを保持し、動的に言語を切り替える方法などもありますが、
なんとなくstoreにtextデータがたくさん貯まるのは重くなる気がしてなりません。

だったら使うFrameworkに左右されることなく、静的なファイルを言語毎に履き、別ページとして対応したほうがわかりやすし、シンプルだなーと思い、今回はこの方法を採用しました。

といっても、i18n webpack等で調べるとほんとにいろんなnpmが出てきます。

どれ使う?

  • i18n-webpack-plugin
    はい、検索すると一番上位に出てきました。wepack-pluginというくらいなんで、一番一般的?なんですかね?

とてもわかりやすそうでしたので、今回はこれを使いました。

環境

  • node v7.9.0
  • webpack 3.8.0
  • babel 6.26
  • babel-preset-es2015 6.2.4.1

導入方法

まずは、インストール

npm install --save-dev i18n-webpack-plugin

webpack.config.jsを編集

import I18nPlugin = from "i18n-webpack-plugin";
var languages = {
  "en": null,
  "ja": require("./src/locale/ja.json") // dir構造によって変えて下さい。
};


export default Object.keys(languages).map(function(language) {
  ....
  entry: {
      app: './app.js',
  },
  output: {
      path: path.join(__dirname, './public'),
      filename: '[name].' + language + '.js'
  },
  plugins: [
    new I18nPlugin(
      languages[language]
    )
  ]
  ....
  ....
}
  • まずはimportします
  • 必要な言語を定義し、default(辞書データがない場合はキー名が出力されるので、key名は大体英語だと思うのでenはnullを)
  • exportする際に、language毎にループさせる
  • filenameに言語名を入れる
  • pluginsに追加

この場合、app.en.js と、app.ja.js ファイルが作成される

辞書ファイルを用意

json形式で下記のように用意します。
src/locale/ja.json

{
  "Hello World": "こんにちは"
}

たぶんnestできなそうですが、試してません。

app中での使い方

console.log(__("Hello World"));

この場合、日本語のjaの場合、「こんにちは」と出力され、enの場合は、辞書ファイルを用意してないですが、default設定がenになりますので、key名がそのまま出力される形になります。

以上、これで言語対応ができました!


iOS9 以下 Safariでjavascriptがちゃんと動かない時にチェックしたい項目

PCとスマフォ両方に対応したWebサイトを作る際、PCやiOS10以上、Androidだと問題ないのに、iOS9以下だと正常にJavascriptが動かないことがあります。
意外と知られてないですが、Javascriptのmethodの書き方や、細かな部分でiOS9以下のSafariではちゃんと動かない場合があります。
そんな時下記の項目をチェックしてみて下さい。僕はこれで数時間ハマりました。

Date関数

文字列型(String)からDate型に変換する際、文字列のフォーマットに注意する

new Date("yyyy-mm-dd")

普通に問題なさそうなのですが、iOS9のSafariだと、「invalid date」が帰ってきてしまいます。

new Date("yyyy/mm/dd")

-には対応しておらず、/でなくては行けません。

methodの初期値

Methodの定義にて、引数の初期値を設定しておきたい場合がありますが、これはiOS9のSafariだとNGです。

function methodA(param = array())

こういう初期値の設定のあるmethodを定義するとエラーになりますので、避けましょう。

iframe使用時、子から親の取得

子から親の要素を操作したい時、

window.parent.document

と指定すると直近の親が取得できますが、iOSのSafariだとちゃんと動かないときがありました。

window.top.document

を使うと取れました。これはもともと一番上の親を取得しますが、あしからず。

clickイベント

クリックイベントを発火させるためには、クリックできる要素でなくてはなりません。

a, bottom

などの要素に対してclickイベントを発火させましょう。他のブラウザの場合はdivやspan等なんでも発火しますがしてくれません。
でもどうしても、divなどでイベントを発火させたいときは、

css で下記を定義する

.element {
  cursor:pointer;
}

もしくは、clickイベントの定義に

$("#element").click(function(){
  .....
}).css('cursor','pointer');

と追加する

それでもだめな場合は、

$("大本要素").on("click touchstart", "要素指定", function(){
    .........
}).css('cursor','pointer');

とすると、聞くようになりました。

他にも見つけたら追加していきます。

なおiOS10以降は上記の問題は解消されてるっぽいです。


DB テーブル定義 を Markdown や HTML で作成する方法

データベースのテーブル定義書をつくるのは面倒ですので、既存のDBから、簡単に作りたいということで、

  1. マークダウン作成(スクリプトからDBにアクセスして取得)
  2. マークダウンを表示できない人のために、HTMLへ

で、作成する方法です。

わざわざGUIソフト等を入れて作るが面倒だと思い、とりあえずmarkdownで出力できないかどうか調べてたら、スクリプトを書いてくれてる方がたくさんいらっしゃったので、拝借し、ちょっと修正し、使わせていただきました。ありがとうございます。

Markdownで出力する

下記の方のコードを使わせていただきました。PHPです。
僕はローカルにanyenvでphpを入れてますが、バージョン等でエラーが出るかもしれないので、シンタックスエラーが出たら都度修正して下さい。
MySQLのテーブル定義をマークダウン(Qiita用)で出力する
テーブル指定部分、僕のPHPバージョン的に、「[]」が使えない古いバージョンをよく使っているので(業務上)、少し改良しました。

37G: $table_names = explode(",", $argv[2]);

※第一引数に、「データベース名」、第二引数に「テーブル名」をカンマ区切りで。すべてのテーブルを指定する場合は「ALL」を指定します。

MarkdownからHTML出力

brewで「pandoc」を入れます。

brew install pandoc

HTMLに出力するのですが、CSSを適応したいと思います。今回は「github」のものを使います。
https://gist.github.com/andyferra/2554919

pandoc -c github.css input.md -o output.html

するとHTMLが作成されるので、他の人に渡すにも良いですね。

必要に応じてカラムの説明等は、HTMLを修正して、コメント欄に記述してあげれば完璧です。

まとめ

わざわざGUI等のソフトを入れずに、簡単に素早く、誰にでも閲覧できるような形でテーブル定義が作成できました。


Webpack + Riot + Materializeで、Webサイト環境を作った話

RiotとWebPackを使う目的

うーちゃん家のWebサイトは、現状、サーバー上のRailsで動いてますが、そんだけのために、Webサーバーを使ってるのがもったいなく感じてきたので、webpackを使いstaticな静的ファイルを生成してWebサーバーを使うのをやめようということで、モダンなjsで代表的なのはReactですが、(Angularはどうだろう)、今回はちゃちゃっと済ましたいので、Riotを使ってみることにしました。

環境作り

  • webpackでプレコンパイルして、staticな形で出力する
  • riot は.tagファイルで記述し読む
  • materializeを全体的に使いたい
  • 自作スタイルシートはsassで記述したいけど、js中でmoduleで読むのは面倒なので、cssファイルを出力し、タグ中で普通に使いたい
  • 画像はHTTPリクエストを最大限に減らすため、base64でコンパイルする

バージョンについて

  • webpack 3.8.0
  • riot 3.7.3


必要なパッケージを入れる

node 初期化

$ npm init

node が入ってない場合はbrewか何かで入れて下さい。

Webpack

$ npm install --save-dev webpack

Babel を入れる

$ npm install --save-dev babel-core babel-loader

ec2015

$ npm install --save-dev babel-preset-es2015 babel-preset-es2015-riot

webpack のためのローダー

$ npm install --save-dev riotjs-loader

Riot.js を入れる

$ npm install --save riot

Materialize とsassに必要なもの

$ npm install --save materialize-css
$ npm install --save-dev sass-loader css-loader file-loader url-loader materialize-loader

jquery materializeは、jqueryを使ってるため

$ npm install --save jquery


Webpackの設定ファイル

webpack.config.babel.js

import path from 'path';
import webpack from 'webpack';
import ExtractTextPlugin from 'extract-text-webpack-plugin';

export default [
    {
        context: path.join(__dirname, './source/javascripts'),
        entry: {
            app: './app.js'
        },
        output: {
            path: path.join(__dirname, './public'),
            filename: '[name].js'
        },
        module: {
            rules: [
                {
                    test: /\.tag$/,
                    exclude: /node_modules/,
                    enforce: "pre",
                    loader: 'riotjs-loader'
                },
                {
                    test: /\.js[x]?$|\.tag$/,
                    exclude: /node_modules/,
                    loader: 'babel-loader',
                },
                {
                    test: /\.(png|jpe?g|gif|svg|woff2?|eot|ttf|otf)(\?.*)?$/,
                    loader: 'url-loader',
                },
            ],
        },
        resolve: {
            extensions: ['*', '.js', '.tag']
        },
        plugins: [
            new webpack.ProvidePlugin({
                riot: 'riot'
            })
        ]
    },
    {
        context: path.join(__dirname, './source/stylesheets'),
        entry: {
            app: './style.sass'
        },
        output: {
            path: path.join(__dirname, './public'),
            filename: '[name].css'
        },
        module: {
            rules: [
                {
                    test: /\.sass$/,
                    exclude: /node_modules/,
                    use: ExtractTextPlugin.extract({
                        fallback: "style-loader",
                        use: [
                            {
                                loader: "css-loader",
                                options: {
                                    url: false,
                                    minimize: true
                                }
                            },
                            "sass-loader"
                        ]
                    })
                },
                {
                    test: /\.(png|jpe?g|gif|svg|woff2?|eot|ttf|otf)(\?.*)?$/,
                    loader: 'url-loader',
                },
            ]
        },
        plugins: [
            new ExtractTextPlugin({
                filename: '[name].css'
            })
        ]
    }
]

※ entry や output部分のファイル名やパスは、必要に応じて変更して下さい。

  • jsの方は、riot-loaderと、babelのloaderを指定してます。
  • cssは、sassをコンパイルして、cssを履きその内容をタグの中でつかえるようにしました。moduleで読む方法もあるけど、毎回js中でimportするのが面倒なので、この方法をとりました。
  • 画像はjsからもcssからも、base64で読むようにurl-loaderをそれぞれで指定してます。そのためpublic以下にわざわざ画像を出力しません。

.babelrc

{
    "presets": [ "es2015", "es2015-riot", "stage-3" ]
}

これで環境ができました。

あとは、riotとmaterializeを使って書いていきます。


Materialize

設定

webpack.config.babel.js に下記を追加します。

context: path.join(__dirname, './source/javascripts'),
entry: {
    app: './app.js'
},
.
.
.
ここから
  {
      test: /\.scss$/,
      loader: ExtractTextPlugin.extract('style-loader', 'css-loader?-url&minimize&sourceMap!sass-loader')
  },
  {
      test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, 
      loader: 'url-loader?limit=10000&mimetype=application/font-woff' 
  },
  {
      test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
      loader: 'file-loader'
  }
ここまで
  • scssをプレコンパイル対象に追加したのは、materializeの色をカスタマイズするために、下記で設定するscssファイルが必要だったからです。
  • woffとttfなどは、materializeで仕様しているフォントファイル等が必要なためです。
  • file-loaderにより、public以下に出力されます。
  • url-loaderはmaterializeのcssファイル中から、fontを読めるようにするためです。
設定ファイルを用意

source/config ディレクトリを作成し

materialize.config.jsを作成

module.exports = {
    styles: {
        'materialize': true,
    }
};

materialize.config.scssを作成

$primary-color: color("blue-grey", "lighten-2");
$primary-color-light: lighten($primary-color, 15%);
$primary-color-dark: darken($primary-color, 15%);

※好きな色を指定する(色をカスタマイズしたいときのみ)

materialize.config.cssを作成

読み込み

app.jsでrequireする

require('materialize-loader!../config/materialize.config.js');
require('materialize-css');

これでmaterializeが適応されました

  • materialize-loaderはcssしかロードしてくれないような感じでしたので、jsも適応したいので、materialize-css を直接記述してます。

Material icon

npm install --save-dev material-design-icons


Riot

試しにカウントアップ・ダウンのサンプルをやってみます
source/tags ディレクトリを作詞し、
count.tagを作成

<count>
    <p>カウント: { count }</p>
    <button onclick={ add }>+</button>
    <button onclick={ minus }>-</button>
    <script>
        this.count = 0;
        add() {
            this.count += 1;
        }
        minus() {
            this.count -= 1;
        }
    </script>
</count>
  • scriptタグ中のthis.xxxと定義すると、htmlタグ中で、{xxx}の形で変数を扱えます。
  • methodについても、script中で定義したmethodは{xxxx}で扱えます。
    わかりやすいですね。

source/javascripts/app.jsを編集

import count from '../tags/count'

riot.mount('count')

mountし、描画される

複数の.tagを読み込む際、何行もimportするのを回避する

source/tags/index.jsを用意

import count from './count'
import navigation from './navigation'

※もっといい方法あれば教えてください。

source/tags/navigation.tagsを適当に用意する

そうすると、app.jsでは

import {count, navigation} from '../tags'

こう書くことができ、一気にたくさんimportできます

これで整いました

まとめ

webpackでの、画像の取扱や、cssのloaderがたくさんあるので、少し戸惑いましたが、理解できてスッキリしました。
riotは視覚的に非常にわかりやすく、モダンにjsを書きたいけど、reactまでやるのはちょっとって方にはいいかもしれません。


「会社辞めたい」って 文句があるなら行動しよう!って話

会社 辞めたい

最近、Googleの検索で、「会社」と入力すると「辞めたい」と、サジェストでかなり上位に候補が出てきます。

しかも下の「関連ワード」は、

会社 辞めたいに関連する検索キーワード

会社辞めたい病

仕事辞める方法

仕事 辞めたい 人間関係

仕事辞めたい うつ

会社 辞めたい 40代

仕事 辞めたい 甘え

仕事辞めたい 転職

仕事辞めたい 新卒

会社 辞めたい 理由

仕事 辞めたい 理由

辞めたいって思ってる人が多いんですね。

だったら、辞めればいいのにって思うんです。

辞めたい理由は?

大体の人が、

  • 「○○○」がムカつく
  • つまんない
  • 会社のやり方が気に食わない
  • 辛い

じゃー辞めれば」って思います。

けど、わかります…..

僕もこう思ってる時、ありました。

僕は4回転職した

僕は、エンジニアですが、4回転職しました。

  • Yahoo! japan 入社 2年半 で 退職
    → ここで生涯ずっと付き合い続けるであろう、たくさんの友人と出会ったけど、仕事は、ともて大きな組織の中の一員であることに、違和感を感じ、自分の力をもっと試したいと感じた。

  • サーフレジェンド 入社 3年弱 で 退職
    → この頃は、職場も湘南で、満員電車に乗ることもなく、家から自転車で通勤し、サーフィンもやり放題で最高だった。気象系の研究開発も楽しかった。けど、まったりゆっくりしすぎてしまったので、刺激が欲しくなった。

  • Winoo 入社 5年ほどやって、田舎で在宅ワーカーに
    → ここはYの先輩だった人が開業した会社で、声かけてもらって入社。小さなベンチャーなので、お金周りや、営業、もちろん開発も、ろもろやらせてもらい、かなり今の自分にも活かされている経験をさせてもらった。社長(経営者)とものすごく距離が近いので、会社の経営の大変さや、面白さみたいなのがダイレクトに感じられた。特に不満もなかったけど、父の田舎の海の近くで、「宿をならないか」というお話を父からもらったので、相当迷い、とっても残念だったが、昔からいつか海の近くに住むと決めていた僕は、早かれ遅かれ、と思い、辞めることを決意したが、社長に話したところ、在宅ワーカーとしてやらせてくれることになった。

  • 白浜ゲストハウス うーちゃん家 開業
    会社の仕事と、両立。急な話だったので、ゲストハウスをやる知識、経営する知識なんて全く無かった中、始めたので最初は本当に苦労した。

個人事業 会社経営ってサラリーマンより全然大変だよ

そうです。会社を経営するってとっても大変です。僕は自分でやってみてわかりました。
雇われているときは、会社への愚痴や不満たらたらでしたけど、
大きな会社を経営してる人ってホントすごいなーって今は思ってますし、何より今は感謝してます。

自分で経営するって、自分の努力やセンスがそのままダイレクトに返ってきます。僕はまともな休みなんて年に数回だし、休んでいたって、仕事のことを忘れたことなんてありません。旅行してても、忘れませんよ。
事業をしてる経営者なんて、みんなそんなもんです。

なので、もし会社に不満がある方は、経営者の方が今までどれだけの苦労をして、やってきたか、そういう会社の歴史とか調べたり理解することで、もしかしたら気持ちが変わるかもしれません。まずは自分の会社の経営者に感謝しましょう。
いかんせん、サラリーマンは、決まった給料、ボーナスがもらえる、保険も年金も会社が半分払ってくれていて、まして、土日や祝日は会社のことを忘れ、休める。ぶっちゃけ会社さまさまです。

会社の文句や愚痴を言うなら、まずは行動しよう!

まずは行動しましょう

  • 会社への嫌なイメージを払拭するために、社長のことをよく知る
  • 入社当初の自分の会社への思いを再確認する
  • それでも会社への思いが変わらなかったら、転職や独立を考える
  • そのために必要なことを調べ行動する

まとめ

意見はいいと思うんです。意見ですから。
でも、愚痴を言うのはだと僕は思ってます。

もちろん、疲れてたり、その時の自分のコンディションで、イライラしたりするのは、人間ですからありますよね。
(僕だってよく言ってました。)

ただ、もしそこの組織の中の一員であるならば、文句は控え、そこの組織に従うべきだし、もし、従えないなら、やめて自分でやるか、従えるところに移動するべきだと思います。

従えず、行動もできないのに、文句だけ言うのは、ただのわがままだと思うんです。

「文句、従えない ー> 行動する」
「行動できない ー> 従う」

ご意見や文句 あったらお気軽にお願いします。


簡単! 秋なす と 万願寺とうがらし 簡単おつまみ

なすとししとうの簡単おつまみ

材料

  • 秋なす
  • 万願寺とうがらし
  • (フレッシュな)生姜
  • 鰹節

調味料

  • 味の素
  • 塩胡椒
  • 醤油(お好みで)
  • オリーブオイル or グレープシードなど

手順

  1. なすと、万願寺とうがらしを洗う
  2. なすを好みの食べやすい大きさに長細くカット
  3. フライパンに、オリーブオイルを結構多めに入れて温める
  4. なすと、万願寺とうがらし(そのまま)を入れる
  5. 味の素と塩コショウで味付け
  6. 日が通ったら、皿に盛り、生姜の細切りしたものと鰹節と醤油をかけて完成

ポイント

なすはオイルを吸うととてもジューシーになり、本当に美味しくなります。サラダ油だとコテコテになるので、オリーブオイルを使いましょう。
それと炒めすぎないように気をつけましょう。


脱サラして 元エンジニアがゲストハウスを開業した話。

キャプチャです

僕は、元サラリーマンでしたが、今から4年ほど前から、東京を離れ田舎に退き、ゲストハウスをやっています。

早かれ遅かれ、いつかは、海のすぐ近くに住むことを決めていましたが、三十路ちょうどで、脱サラして田舎でゲストハウスを開業するとは想像もしてませんでした。

なので、もともと開業したいと思って、その目標に向かって頑張ってきた人たちと比べると僕は、本当になんの知識もないまま、開業することになったと思います。

そんな僕が、4年やった現時点で思ったことや、これまでやってきたことを書いておこうと思います。

移住のきっかけ

父の生まれ故郷にて、もともと父の友人がやっていたコテージ型の宿を、安く買う話になったのがきっかけです。

なんでゲストハウス

ぶっちゃけなんとなくです。ペンションでも民宿でも良かったのです。ただ、今風だから?ゲストハウスにしたんです。
なので、ゲストハウスへのこだわりは当初そこまでなかったのが事実です。
でも、ゲストハウスにしてよかったと、いまはとても思っています。

開業

開業するのに、よく必要な手続き等を丁寧に載せてくれているサイトがあります。とても参考になりました。

  • 個人事業主の届け
  • 青色申告の届け
  • 保健所チェック
  • 消防チェック
  • etc…

他にもたくさんあった気がしますが、ここでは割愛します。検索すると結構色々出ててきます。

あと、僕は会計ソフトのfreeeを使っていますが、これを使うと、必要な書類を自動で作ってくれるみたいです。

また、開業するにあたり、色々とお金がかかりました。

  • 土地や建物の売買
  • 不動産取得税(これがあとから来てビビった。でも古くない建物なら免除されることが多いです)
  • 固定資産税(これは持ち家の人なら払ってる)
    あと何よりも、僕の物件の場合、とても古かったので、色々と修繕費がかかりました。
    よく、Youtubeで直し方ややり方を動画で見て、必要な工具を揃えて、材料を買いにいって、やれることは自分でやりました。
    なるべく自分でできることは自分でやることが大事だし、それが楽しさ何だと思います。

集客

ゲストハウスって結構予約サイトの載せず電話のみの予約でやってるところが多い気がしますが、僕はIT系エンジニアだったので、たくさんITの恩恵をうけて、集客してます。
予約サイト使わずにやってるのってすごいなーって思います。

僕の思う理想のゲストハウス

僕は沖縄が好きで、よくゲストハウスに泊まってました。ゲストハウスに来る人は、旅人やスタッフ、その地の人との交流を求めてくる人もいれば、ただただ、観光にお金を使いたいから宿はケチりたい人、人それぞれのスタイルがあるわけです。

僕は、沖縄のゲストハウスにあるような、激しい「ゆんたく」は、醍醐味だと思うし、とっても楽しいと思います。
ただ、ゆっくり休みたいという人にはつらいかもしれません(僕もそんな経験がある)。

だから、プライベートの空間はしっかり確保でき、他の人と交流したい人は交流できて、したくない人はしなくても気まずい思いを一切しなくてもよい、そんなゲストハウスが、僕にとっては理想かと思ってます。

ファミリー同士だって、カップル同士だって、交流したければすればいいし、したくないならしなくてもいい。そんなスタイルでやってます。

現状の課題

  • オフシーズンの集客
    僕のゲストハウスは、海のすぐ近くなので、どうしても夏にお客さんが集中します。夏以外のほうが、人も少ないし、ゆっくりできていいと思うんですが、やっぱりみんな海水浴に来るんです。海水浴以外なにもないので、そこは課題です。

  • 共有スペース
    僕のゲストハウスには、共有スペースが外にしかありません(屋根は一応ある)。その為、春〜秋は問題無いですけど、冬は寒くてそこにいられませんね。室内にも共有スペースを用意したいと思ってます。

  • キッチン
    現状、お客さんが使えるちゃんとしたキッチンがありません。用意したいとは思ってます。

  • 外国人
    外国人が最近やっと増えてきましたが、僕はいかんせん、英語がそんなに得意ではありません(日々勉強中)。なのでもっと話ができたらなーとは思ってます。それと集客ですが、海外向けのサイトをもっと使おうと思ってます。外国人に流行れば、日本人にも流行るわけで。

まとめ

サラリーマンとは違い、自分の店、宿を守れるのは自分だけです。すべてを自分で判断し、自分で行い、すべての責任も自分に降りかかります。
ただ、自由だし、自分の努力がそのまま自分に帰ってきます。色んな人とも出会えて、それが財産になるんだと、思います。

まだまだ自分の納得の行く形になるまでは、程遠いですが、日々少しずつやっていこうと思います。

ご意見やご指摘などあればお気軽に