ExpressでテンプレートエンジンPugを利用してみる
今回はExpressでpugを使ってみようと思います。
まずプロジェクトディレクトリを作成してください。
mkdir express_practice
その後、npm init -y
package.jsonが作成されます。
その後expressをインストールします。
npm i -D express
今回はpugを使用するので
npm i -D pug
view
フォルダにindex.pugファイルを用意します。
html head title!= title body h1!= message
プロジェクトフォルダ配下にapp.jsファイルを追加します。
const express = require('express'); const app = express(); app.set('view engine', 'pug'); const recordLog = function (req, res, next) { console.log('localhost:3000にアクセスしました'); next(); }; app.use(recordLog); app.get('/', function (req, res) { res.render('index', { title: 'Hello', message: 'Express'}); }); app.listen(3000);
res.render('index', { title: 'Hey', message: 'Hello there!'});
↑ではindex.pugで設定した変数に値がそれぞれ入ります。
その後、node app.js
と実行後、ブラウザでlocalhost:3000
にアクセスしてみてください。
このように表示されればOKです!
簡単ではありますが以上になります。
今後はmysqlを使ってデータのやりとりをしてみようと思います。
ReactのFragmentsって便利
今回はReactの開発において今後積極的に使っていこうと思ったものを紹介したいと思います!
タイトルにも書いてある通り、Fragmentsです。
言葉で説明するよりも下記のコードを見た方が理解し易いです。
import * as React from "react"; class Columns extends React.Component { render() { return ( <div> <td>データ1</td> <td>データ2</td> </div> ); } }
ここで<td>
タグのリストをレンダリングしたいのに余計なノードをDOMに追加しなけばいけません。階層が余計に深くなったりルートの要素に余分なスタイルを当てなければいけない時などが出てくる可能性があります。
もやもやしますよね・・・
React v16 からはこの忌まわしき問題から解放されます!!
新たにFragmentを読み込みます。
このように書くことで上記の問題を回避することができるのです!簡単ですね!
import React, { Fragment } from 'react' class Columns extends React.Component { render() { return ( <React.Fragment> <td>データ1</td> <td>データ2</td> </React.Fragment> ); } }
レンダリングされた結果がこちらになります。
<td>データ1</td> <td>データ2</td>
また別の記述の仕方があります。
import React, { Fragment } from 'react' class Columns extends React.Component { render() { return ( <> <td>データ1</td> <td>データ2</td> </> ); } }
こちらの書き方はまだサポート他のツールでサポートされていないようなので<React.Fragment>
を使用することが推奨されています。
簡単ではありますが、是非活用してみてください!
ES2015でポップアップのテンプレートを作ってみた!
今回はJavaScriptで簡単なポップアップのテンプレートを作ってみたのでサンプルコードを載せておきます。
<!DOCTYPE html> <html lang='ja'> <head> <meta charset='UTF-8'> <meta name='viewport' content='width=device-width, initial-scale=1.0'> <meta http-equiv='X-UA-Compatible' content='ie=edge'> <title>ポップアップのサンプル</title> <link rel='stylesheet' href='css/style.css'> <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.26.0/babel.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/6.26.0/polyfill.min.js"></script> </head> <body> <button class="popupButton" id="js-clickEl">クリックする要素</button> <div class='popup' id="js-popup"> <div class='popup_content'> <p class='popup_content_closeButton' id="js-popupCloseButton">X</p> <div class='popup_content_description'>何か文言が入ります</div> <div> </div> <script src="js/Popup.js"></script> </body> </html>
.popupButton { border: none; background: #323232; color: #fff; padding: 20px; border-radius: 33px; cursor: pointer; } .popup { width: 100%; height: 100%; position: fixed; top: 0; left: 0; background: rgba(5,5,5,0.8); opacity: 0; transition:all .3s; transform: scale(0); } .popup.is-active { transform: scale(1); opacity: 1; } .popup_content { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: #fff; width: 400px; height: 360px; padding: 30px; } .popup_content_closeButton { cursor: pointer; text-align: right; } .popup_content_description { margin-top: 30px; }
class PopUp { constructor(clickEl, popupEl, closeEl){ this.clickEl = document.getElementById(clickEl) this.popupEl = document.getElementById(popupEl) this.closeEl = document.getElementById(closeEl) } setEventListener(){ this.clickEl.addEventListener("click", this.displayPopup.bind(this)); this.closeEl.addEventListener("click", this.closePopup.bind(this)); } displayPopup(){ this.popupEl.classList.add("is-active") } closePopup(){ this.popupEl.classList.remove("is-active") } } const simplePopup = new PopUp('js-clickEl', "js-popup", "js-popupCloseButton"); simplePopup.setEventListener();
このPopupクラス
を使って初期化した後の引数に対象となる要素のIDを入れればデザインの違うポップアップにも対応できます!
是非使ってみてください!
React+TypeScript+Webpackで環境構築
今回はReact+TypeScript+webpackの環境構築をしていきたいと思います。公式のドキュメントを参考になぞってみました。是非、一読してみてください。
前提としてnode
とnpm
はインストール済みで進めていきます。
作業ディレクトリを作成してください。
以下のディレクトリ構成で進めていきます。
proj/ ├─ dist/ └─ src/ └─ components/
ここでは、まだdist
フォルダを作成しなくても良いです。
後述しますが、webpackが自動で作ってくれます。
プロジェクトディレクトリ直下でnpm init -y
と実行してください。
そうするとpackage.jsonが生成されます。
webpackのインストール
まずグローバルにwebpackがインストールされているか確認してください。 まだインストールがされていなければ
npm i -g webpack
と実行してwebpackがインストールされていることを確認してください。
Reactのインストール
reactとreact-domをインストールしましょう。
npm i -D react react-dom @types/react @types/react-dom
ここで@typesという接頭辞が出てきて何ぞや?と思われた方もいると思います。この@typesというのはreact
とreact-dom
の型定義ファイルになります。
どんな型定義ファイルがあるかはこちらから確認ができます。
react単体で型定義をする場合は、PropTypesなどを作成すると思いますが、TypeScript 2から型定義ファイルの管理をnpmで行えるようになりました。
TypeScriptのインストール
npm install --save-dev typescript awesome-typescript-loader source-map-loader
この中のパッケージのawesome-typescript-loader
とsource-map-loader
はwebpackと一緒に使うときに必要になります。
awesome-typescript-loaderはwebpackがTypeScriptのスタンダードな設定ファイルであるtsconfig.jsonを使ってtypescriptのファイルをコンパイルしてくれます。
source-map-loaderはその名の通り、ソースマップを生成してくれます。
tsconfig.jsonの設定
tsconfig.jsonファイルをプロジェクトディレクトリ直下に作成し、以下のように設定してください。
{ "compilerOptions": { "outDir": "./dist/", "sourceMap": true, "noImplicitAny": true, "module": "commonjs", "target": "es5", "jsx": "react" }, "include": [ "./src/**/*" ] }
outDir
- 出力先のディレクトリの設定
sourceMap
- ソースマップの有無。
noImplicitAny
- 厳密に型を決めるときなど、暗黙のanyの型はエラーとすることができます。
module
- moduleコードの生成方法
target
- トランスパイルする先の、ECMAScript の ターゲット・バージョンになります.。
詳細を知りたい方はこちらで確認してください。
Let's Write Code
実際にReactを使ってTypeScriptを書いていきましょう。
まず、Hello.tsxというファイルをsrc/components
直下に配置してください。
import * as React from "react"; export interface HelloProps { compiler: string; framework: string; } export const Hello = (props: HelloProps) => <h1>Hello from {props.compiler} and {props.framework}!</h1>;
こちらはステートレスコンポーネントで記述しています。 文字通り、何か状態を保持ている状態ではなく、描画するためだけのコンポーネントになります。
クラス構文を使って記述すると以下のようになります。
import * as React from "react"; export interface HelloProps { compiler: string; framework: string; } // 'HelloProps' describes the shape of props. // State is never set so we use the '{}' type. export class Hello extends React.Component<HelloProps, {}> { render() { return <h1>Hello from {this.props.compiler} and {this.props.framework}!</h1>; } }
コードの中にこのような記述があります。
React.Component<HelloProps, {}>
ComponentはReact.Component<P, S>
を extends したクラスを作成します。
P
は props の型、 S
は state の型となります。
次にindex.tsxをsrc直下に追加します。
import * as React from "react"; import * as ReactDOM from "react-dom"; import { Hello } from "./components/Hello"; ReactDOM.render( <Hello compiler="TypeScript" framework="React" />, document.getElementById("example") );
ここでは単純にindex.tsxにHello.tsxをインポートしてReact.DOMのrederメソッドでレンダリングしています。
次にHello.tsxの内容を表示させるためにindex.htmlファイルを作成します。
プロジェクトフォルダ直下にindex.htmlを作成してください。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>Hello React!</title> </head> <body> <div id="example"></div> <!-- Dependencies --> <script src="./node_modules/react/umd/react.development.js"></script> <script src="./node_modules/react-dom/umd/react-dom.development.js"></script> <!-- Main --> <script src="./dist/bundle.js"></script> </body> </html>
webpackの設定ファイルを作成
プロジェクトディレクトリの直下にwebpack.config.jsファイルを作成してください。
module.exports = { entry: "./src/index.tsx", output: { filename: "bundle.js", path: __dirname + "/dist" }, // Enable sourcemaps for debugging webpack's output. devtool: "source-map", resolve: { // Add '.ts' and '.tsx' as resolvable extensions. extensions: [".ts", ".tsx", ".js", ".json"] }, module: { rules: [ // All files with a '.ts' or '.tsx' extension will be handled by 'awesome-typescript-loader'. { test: /\.tsx?$/, loader: "awesome-typescript-loader" }, // All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'. { enforce: "pre", test: /\.js$/, loader: "source-map-loader" } ] }, // When importing a module whose path matches one of the following, just // assume a corresponding global variable exists and use that instead. // This is important because it allows us to avoid bundling all of our // dependencies, which allows browsers to cache those libraries between builds. externals: { "react": "React", "react-dom": "ReactDOM" }, };
上記のexternals
とあると思いますが、React.jsのプロジェクトでは、webpackによるビルド時のデフォルト挙動がReact.jsライブラリ自体もビルドするため、時間がかかります。
そこでexternals指定してReact.jsをビルドから除外する手順が有効となります。
webapack
コマンドを実行してください。
このように表示されていればOKです!
今度はローカルサーバーを立てながら実際に簡単なTodoアプリを作成していきたいと思います。
デザイナーでも楽々フロントエンドの環境構築「PINGY CLI」
最近、「環境構築とかしたくないー」などと嘆くデザイナーさんがいらっしゃったので、何か手軽にフロントエンドの環境を構築できる方法はないかなーと思っていました。そこで良いツールを見つけました!!
その名もPingyです。
gulpやGruntなどは学習コストが掛かります。
Pingyの場合は、複雑なビルドのフローなどには向きませんが、設定ファイルなどもシンプルで初心者に優しく簡単に環境構築ができます!
では、早速環境構築をしていきましょう!
nodeが入っていることは前提としていますのでまだNodeをインストールしていない方は下記の記事を参考にしてください。(尚nodeのバージョンは6以上をサポートしています)
Macユーザーはこちら
1 インストール
npm i -g @pingy/cli
作業ディレクトリを作成
mkdir pingy_practice
作業ディレクトリへ移動
cd pingy_practice
2 初期設定
作業ディレクトリへ移動したのち、下記のコマンドを実行します。
pingy init
そうすると選択形式でいろいろと聞かれますので順に答えていきましょう!
HTMLの設定
先ずはhtmlのテンプレートエンジンはどうするのかを問われているので今回はPug
を選択
CSSの設定
次にcssのメタ言語を問われているのでSass(.scss)
を選択。
(ここでは詳しく説明しませんが、.scssと.sassは記述方法がことなるので注意してください)
JavaScriptの設定
ここではBabel
を選択。Babelは新しいJavaScriptの記述が可能になり、ブラウザが解釈できるように旧来のJavaScriptにトランスパイルしてくれます。
すべての設定が終わったのであとはこれらのパッケージをインストールするのでY
を選択しましょう。
その後、pingy dev
と入力してローカルサーバーを立てます。
そうするとこのようにタブが開き、このような画面になると思います。
これで開発できる状態になりました!! 簡単ですね!!!
試しにscss
ファイルにbodyにblue
とスタイルを変更してみてください。
ブラウザをリロードしていないにも関わらず、スタイルの変更がされました!
scss
だけでなく、pug
やjs
もリアルタイムに変更されるので試してみてください。
ビルド
pingy.json
があるファイルと同じ階層の場所でpingy export
とコマンドを実行してください。
dist
フォルダができたと思います。ビルドも簡単ですね!
pingy.json
ファイルを少し覗いてみましょう。
画像にも書いてありますが
- exportDir:ビルドした時のディレクトリ名を設定
- minify:圧縮するかしないか
- compaile:コンパイルの有無(基本はtrue)
- exclusions:ビルドしないディレクトリ等
- port:ポート番号の設定
複雑なディレクトリ構成で開発をしないのであれば、Pingyが重宝すると思います。あまり開発環境構築を好まないデザイナーさんなどにも使いやすいのではないでしょうか?
その時々の状況に合わせて是非使ってみてください!!
webpack4の基礎
ついに webapck4.0.0がリリースされましたね!
変更点としてよく言われているのが設定ファイルが不要ということです。
この記事では主要な変更点に絞って実際に手を動かしながらwebpack4の特徴を掴んでいくことを目的とします。
では早速、開発用のディレクトリを作成します。
mkdir webpack4_practice
npm init -y
package.jsonファイルが作られます。
ではではwebpack4.0.0をインストールしましょう!
npm i -D webpack
webpack
みたいにコマンドを実行している場合はcliを入れる必要があります。webpack-cli
をインストールしましょう。
npm i webpack-cli -D
インストールができたらpackage.jsonを開き、以下の記述を追加します。
"scripts": { "build": "webpack" }
その後以下のコマンドを実行してください!
npm run build
このようなエラー文がでると思います。
ERROR in Entry module not found: Error: Can't resolve './src' in '~/webpack4_practice'
これはどういうことかというとwebpack4が自動的に./src以下にエントリーポイントを探しにいってくれるのです。
以前のバージョンではwebpack.config.jsファイルの中でエントリーポイントと出力先を記述する必要があったと思います。
const path = require('path'); module.exports = { entry: { 'index': [ path.resolve(__dirname, 'src/index.js') ] }, output: { filename: '[name].js', path: path.resolve(__dirname, 'public'), publicPath: '/', }, };
ではでは実際にファイルを作成してビルドするところまでやってみましょう。
./src/index.js
とファイルを作成します。
console.log("This is the entry file")
その後先ほどpackage.jsonに記述したようにnpm run build
と実行してみてください。
新しく./dist/main.js
とファイルができていると思います。
しつこいようですがまだ設定ファイルは記述していません。
記事の頭でも言及しましたが、webpack4での新たな機能のひとつとして
設定ファイルを必要としない
と言われています。
もう少し詳しく見ていきます。
まずはじめにwebpackではProduction
用とDevelopment
用で2ファイル用意するのが典型的な例でした。
これは大きなプロジェクトになればなるほど必要になってきます。
ですがwebpack4ではどうでしょうか?
webpack4では
- productionモード
- developmentモード
というものがあります。 実際に手を動かして見ていきましょう。
package.jsonを編集します。
"scripts": { "dev": "webpack --mode development", "build": "webpack --mode production" }
npm run dev
と実行後、./dist/main.js
を見てみてください。minifyされていないことが確認できると思います。
その後npm run build
と実行し、./dist/main.js
を見てみてください。minifiedされていることが確認できるかと思います。
とても簡単な例ですが、webpack4ではこのようにそれぞれ1行のコマンドでDevelopment用とProduction用とで処理を変えることができます。とっても簡単ですね♪
次にBabelを使用してES6 → ES5
のトランスパイルをしていきたいと思います。
babel-loaderがwebpackのがES6からES5にトランスパイルするためのloaderなので以下のパッケージをインストールします。
- babel-core
- babel-loader
- babel-preset-env
以下のコマンドを実行します。
npm i babel-core babel-loader babel-preset-env -D
その後、 .babelrcをプロジェクトフォルダ直下に作成し、以下を記述します。
{ "presets": [ "env" ] }
ここで疑問に思うかもしれません。 設定ファイルが不要というのがwebpack4の大きな変更点として言われているにのに、結局設定ファイルが必要になるんだなーと。
最小限の構成で開発をするのであれば、今までで紹介した
- エントリーポイント、ビルド先がデフォルトで決まっている
- Production、Developmentモードがコマンド一つで切り替え可能
上記のことから設定ファイルが必要がないということが言えるのではないのでしょうか? 自分独自の開発環境を構築しようとなった時には、設定ファイルが必要になってくると思います。(実際に触ったばかりなのでまだ確定できませんが。。。)
このことを踏まえてwebpack.config.js
ファイルをプロジェクトフォルダ直下に作成します。
module.exports = { module: { rules: [ { test: /\.js$/, exclude: /node_modules/, use: { loader: "babel-loader" } } ] } };
ここで見て欲しいのが、エントリーポイントを記述していない点です。
その後、./src/index.js
をES6で記述します。
const data = [1, 2, 3]; const getArrData = () => console.log(...data); console.log(getArrData)
npm run build
と実行してみください。
正しくES6 → ES5
にトランスパイルされたかと思います。
最小限の構成ですとこのように設定ファイルなしで開発していくことができます。
次回はReact+webpack4での開発環境を紹介できればと思います。