- 投稿日:2020-11-17T22:30:46+09:00
NextJSのapiでサーバー側からリダイレクトをさせたい時
page/api
配下で処理を書いてそれをfetch
した時に、処理内容に応じてクライアント側でリダイレクト処理をさせたい時res.redirect('/')
と書いてもstatus: 307
が帰ってくるだけでクライアント側はリダイレクトされません。- クライアント側のリダイレクトをさせたい時はクライアント側でrouter処理を書きましょう。
src/api/*export deafult (req, res) => { res.status(307) }src/pages/*import Router from 'next/router' () => { if(code == 307){ Router.push('/') } }node弱いのでもっといいやり方あったら教えてください。。。
- 投稿日:2020-11-17T19:14:44+09:00
湯婆婆言語作ってみた
湯婆婆言語作ってみた
Qiitaで湯婆婆のセリフをいかに短く実装するかブームらしいので自作言語を作って
実装した話です
ソースコードはここにのってます
https://github.com/riya81/yubaうぷ主の環境
- macOS Big Sur 11.0.1
- Node 12.16.3
手順
1. 自作言語の構文を考える
2. トランスパイル先の言語を決める
3. ファイルを読みこむ
4. トランスパイラを作る
5. トランスパイラをビルドする手順は僕の他の記事に詳しく書かれているので省きます
この記事のソースコードを少し変えただけです
https://qiita.com/riya81/items/b1d5261205d13e4740cbコマンド
y "名前";これだけで湯婆婆を実装できます
この機能しかないですまとめ
まとめることなんかほぼ無いうっすい記事ですが以上
湯婆婆言語を作った話でした
- 投稿日:2020-11-17T17:17:26+09:00
コピペで簡単!爆速でtailwindcssをNode.jsに導入する方法について
はじめに
皆さんはどのCSSフレームワークを使われていますか?
有名どころは、Twitter社が作ったBootStrapでしょうか。
Bootstrapの大きな欠点は、どこかで見たようなサイトに仕上がり、
デザインにオリジナリティが出すことが難しくなります。そんな中でおすすめしたいのが、今回取り上げるTailwindです。
この記事では、Node.jsでtailwindcssを導入する方法をご紹介いたします。
今回使用するモジュール
今回使用したモジュールは以下の通りです。
今回採用したテンプレートエンジンはejsとなります。
また、ルーティング処理等はすべてexpressを用いています。package.json"autoprefixer": "^10.0.1", "ejs": "^3.1.5", "express": "^4.17.1", "postcss": "^8.1.6", "postcss-cli": "^8.2.0", "tailwindcss": "^1.9.6"[STEP1]プロジェクトを作成し、そのディレクトリに移動しましょう
ターミナルmkdir nodejs-tailwindcss cd nodejs-tailwindcss
mkdir
でファイルを作成します。
cd
でディレクトリを移動します。[STEP2]初期化処理を行う
ターミナルnpm initこのコードを実行して以下のファイルが作成できればOKです。
package.json{ "name": "nodejs-tailwindcss", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", }, "author": "", "license": "ISC", }[STEP3]JavaScriptのファイルを作成する
ターミナルtouch index.js簡単ですね。
ただindex.jsファイルを作成するだけです。[STEP4]必要なモジュールをインストールする
ターミナルnpm install express ejs --saveこの後、tailwindcssなどのモジュールもインストールしますが、
わかりやすさに重きをおくため、先にexpressとejsをインストールします。こちらを実行することで、package.jsonが以下のようになればOKです。
package.json{ "name": "nodejs-tailwindcss", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", }, "author": "", "license": "ISC", "dependencies": { "ejs": "^3.1.5", "express": "^4.17.1", } }[STEP5]expressでルーティング処理等を記述する
STEP3で作成したindex.jsに以下のコードを記述します。
index.js//モジュールを読み込む const express = require('express'); const ejs = require('ejs'); //読み込んだexpressモジュールを実体化してインスタンスにする const app = express(); //テンプレートエンジンとしてejsを用いる(今回はejsを使いません) app.set('view engine', 'ejs'); //ルーティング処理 app.get('/', (req, res) => { res.send("expressを導入しました"); }); //サーバーを立ち上げる app.listen(3000, () => { console.log('http://localhost:3000'); });[STEP6]tailwindcssなど必要なモジュールをインストールする
ようやく本題の
tailwindcss
をここでインストールします。
ついでにpostcss
,autoprefixer
もインストールします。この2つは解説します。
PostCSS
とは、Node.js製の「CSSツールを作るためのフレームワーク」です。
Autoprefixer
はベンダープリフィックスを自動で付与するPostCSS製のツールです。tailwindcssはPostCSSのプラグインであるため、
最新のCSSをブラウザが理解できるものに変換するツールが必要となります。ということで、コマンドラインからPostCSSを扱える,
postcss-cli
を合わせた4つをインストールしましょう。ターミナルnpm install tailwindcss postcss autoprefixer postcss-cli --save[STEP7]tailwindcssを使うために必要なファイルを作成する
これが最後のステップです。
何個かファイルを作成しないといけないのでまずはやるべきことを下記に記載します。
tailwind.config.js
の作成postcss.config.js
の作成とファイルへの記述- CSSを格納するフォルダ・ファイルを作成
package.json
にCSSをビルドする記述を追加tailwind.config.jsの作成
ターミナルnpx tailwindcss initこのファイルは特にいじる必要はありません。
カスタマイズをする時にでも記載しましょう。
詳しくはこちらをご確認ください。postcss.config.jsの作成とファイルへの記述
ターミナルtouch postcss.config.jsこちらを実行すると、postcss.config.jsが作成されます。
こちらのファイルに以下の記述を追加してください。postcss.config.jsmodule.exports = { plugins: [require('tailwindcss'), require('autoprefixer')], };CSSを格納するフォルダ・ファイルを作成
ターミナルmkdir public mkdir public/styles touch public/styles/tailwind.css touch public/styles/style.css上から順に、
①public
フォルダを作成
②publicフォルダ内にstyles
フォルダを作成
③stylesフォルダ内にstyle.css
ファイルを作成
④stylesフォルダ内にtailwind.css
ファイルを作成④のtailwind.css内には以下の記述を追加してください。
tailwind.css@tailwind base; @tailwind components; @tailwind utilities;
package.json
にCSSをビルドする記述を追加
scripts
に新たに記載を追加します。package.json{ "scripts": { "css": "postcss public/styles/tailwind.css -o public/styles/style.css" }, }以下がpackage.jsonファイルの全体像です。
package.json{ "name": "nodejs-tailwindcss", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "css": "postcss public/styles/tailwind.css -o public/styles/style.css" }, "author": "", "license": "ISC", "dependencies": { "autoprefixer": "^10.0.1", "ejs": "^3.1.5", "express": "^4.17.1", "postcss": "^8.1.6", "postcss-cli": "^8.2.0", "tailwindcss": "^1.9.6" } }それでは最後にビルドをしましょう!
ターミナルnpm run cssこれでtailwind.cssの導入が完了です。
public/styles/style.css
にCSSが追加されています。
- 投稿日:2020-11-17T10:25:37+09:00
webpack v5がリリースされた現状まとめ
プロダクションで使うのはまだ早い(11月時点
webpack v5のリリースは行われましたが、まだバグが多くありwebpackで使用するloaderやpluginは対応が全然追いついていません。
webpack v5系のIssues を眺めると多くの問題があることがわかります。
プライベートでwebpack v5にアップデートを試みたところ全部壊れました。大変危険です、webpack v5 を使用するのは 数ヶ月ほど待ったほうが良いと思います。
周辺ツールの現状
webpackを使用するにあたって特に重要な webpack-dev-server と webpack-cli の現状は以下のとおりです。
webpack-dev-server
webpack-dev-server は webpack v5対応がまだリリースされてないので、動かないケースが何点かあります。
webpack-cli
webpack v5 対応のためv4のリリースはされていますが、上記でも書いている通りwebpack-dev-serverと組み合わせるとバグります。
webpack-cli v4からwebpack-dev-server の起動をwebpack serveコマンドに統合するようになっています。
変更内容
主に下記のような変更があります。
- 永続的なキャッシング
- TypeScriptの対応で
@types/webpack
が不要になり、import { WebpackOptionsNormalized } from 'webpack';
で型を import できるようになった。(ファイル名を webpack.config.ts にする必要がある- Tree Shaking の最適化が入りバンドルサイズ縮小に期待できる
- CommonJs の Tree Shaking 対応
- css の chunk が可能になった( MiniCssExtractPlugin 使用時にできる)
破壊的変更
特に大きな破壊的変更を2つ取り上げます。
Node.js の polyfill を自動で挿入しなくなった
今まではwebpackを使用すればNode.js のコードをクライアントサイドで使用し、自動でpolyfillを挿入してくれていました。
今後 webpackはwebで動作するコードに焦点を当てていくため、Node.jsのpolyfill がバンドルに含まれ、結果的にバンドルサイズがデカくなくることを望まないようになり、
自動で polyfill を挿入しなくなりました。polyfill を挿入したい場合は webpack/node-libs-browser を参照して、自前で挿入する必要があります。
また、クライアントサイドで Node.js に依存したパッケージを使用している場合は、パッケージの対応を待つか、フロントエンド互換のあるパッケージに変更する必要があります。global, __filename, __dirnameもwebpackのデフォルト設定でfalseに変更されたので、使用したい場合は明示的に変更する必要があります。
デフォルトランタイムが一部 ES2015 になった
webpackの生成するコードが一部 ES2015 になったので、明示的に es5 への対応が必要となりました。
browserslistnのサポートが含まれたので、browserslistの設定またはwebpack の設定を変える、2つの選択肢があります。
- webpack の設定
webpack.conf.js
module.exports = { target: ['web','es5'] };
- browserslist の設定
.browserslistrc
last 1 version ie >= 11
- package.json
"browserslist": [ "last 1 version", "> 1%", "ie >= 11" ]参考文献
- 投稿日:2020-11-17T01:42:07+09:00
子供用の学習アプリケーションを作る(2) アニメーション編
はじめに
以前作成したアプリの続きをしていきます。
参考: 子供用の学習アプリケーションを作る(1)今回は、コンテンツの選択画面にアニメーションを導入し、選択後の詳細画面を作成したので、その実装について記事にしていこうと思います。
動作
まずは、動作を見ていただければと思います。
実装
構成
構成は以下のようになっています。
❯ pwd /Users/yoshitaka.koitabashi/Desktop/iLearn/src/components ~/Desktop/iLearn/src/components ❯ tree . . ├── alsContent.tsx ├── contentsSelect.tsx ├── falcon9Content.tsx ├── header.tsx └── spaceContent.tsx 0 directories, 5 files今回の実装の説明に使用するのは、こちらです。
・contentsSelect.tsx
コンテンツを選択する画面Home画面からの遷移時に、各コンテンツがふんわり浮かび上がるアニメーションを作成しました。
参考 react-native: Animated
こちらの実装なのですが、単純で、Animatedというライブラリと副作用fookであるuseEffectを利用したパターンになります。contentsSelect.tsximport 'react-native-gesture-handler'; import React, { useRef, useEffect } from 'react'; import { SafeAreaView, ScrollView, StyleSheet, Animated, TouchableOpacity, } from 'react-native'; import { Card, Title } from 'react-native-paper'; import { createStackNavigator } from '@react-navigation/stack'; import AppHeader from './header'; import spaceContent from './spaceContent'; import alsContents from './alsContent'; import falcon9Contents from './falcon9Content'; const contents = ({ navigation }) => { const fadeSpace = useRef(new Animated.Value(0)).current; const fadeAls = useRef(new Animated.Value(0)).current; const fadeFalcon9 = useRef(new Animated.Value(0)).current; const spaceContentFadeIn = () => { Animated.timing(fadeSpace, { toValue: 1, duration: 500, useNativeDriver: true, }).start(); }; const alsContentsFadeIn = () => { Animated.timing(fadeAls, { toValue: 1, duration: 2000, useNativeDriver: true, }).start(); }; const falcon9ContentsFadeIn = () => { Animated.timing(fadeFalcon9, { toValue: 1, duration: 3000, useNativeDriver: true, }).start(); }; useEffect(() => { spaceContentFadeIn(); alsContentsFadeIn(); falcon9ContentsFadeIn(); }); return ( <SafeAreaView style={styles.container}> <ScrollView contentContainerStyle={styles.contentContainer} > <TouchableOpacity onPress={() => { navigation.navigate('Home'); }} > <AppHeader /> </TouchableOpacity> <Animated.View style={[{ opacity: fadeSpace }]}> <Card onPress={() => navigation.navigate('宇宙って?')} style={styles.cardPadding} > <Card.Content> <Title style={styles.cardTitle}>宇宙って?</Title> <Card.Cover source={require('../../public/img/alien.png')} style={styles.cardImg} /> </Card.Content> </Card> </Animated.View> <Animated.View style={[{ opacity: fadeAls }]}> <Card onPress={() => navigation.navigate('ALSって知ってる?')} style={styles.cardPadding} > <Card.Content> <Title style={styles.cardTitle}>ALSって知ってる?</Title> <Card.Cover source={require('../../public/img/health.png')} style={styles.cardImg} /> </Card.Content> </Card> </Animated.View> <Animated.View style={[{ opacity: fadeFalcon9 }]}> <Card onPress={() => navigation.navigate('Falcon9がすごい')} style={styles.cardPadding} > <Card.Content> <Title style={styles.cardTitle}>Falcon 9がすごい</Title> <Card.Cover source={require('../../public/img/startup_isometric.png')} style={styles.cardImg} /> </Card.Content> </Card> </Animated.View> </ScrollView> </SafeAreaView> ); }; const Stack = createStackNavigator(); const contentsSelect = () => ( <Stack.Navigator> <Stack.Screen name="知識の森" component={contents} /> <Stack.Screen name="宇宙って?" component={spaceContent} /> <Stack.Screen name="ALSって知ってる?" component={alsContents} /> <Stack.Screen name="Falcon9がすごい" component={falcon9Contents} /> </Stack.Navigator> ); const styles = StyleSheet.create({ container: { flex: 1, }, cardImg: { height: 300, }, cardPadding: { top: 60, marginBottom: 20, borderRadius: 5, marginLeft: 20, marginRight: 20, }, cardTitle: { fontWeight: 'bold', }, contentContainer: { paddingBottom: 50, }, }); export default contentsSelect;・spaceContent.tsx
宇宙についてのコンテンツの詳細画面詳細画面で少し面白い箇所が、下記です。
何をしているかというと、Home画面に戻す動作をしているのですが、dispatch(StackActions.popToTop())をしないと、navigationのHistoryが消されず想定外の動作をしてしまいます。navigation.navigate('Home'); navigation.dispatch(StackActions.popToTop());spaceContent.tsximport * as React from 'react'; import { ScrollView, StyleSheet, View, Image, TouchableOpacity, } from 'react-native'; import { Card, Paragraph, Chip, Avatar, Title, } from 'react-native-paper'; import { StackActions } from '@react-navigation/native'; import { Text } from 'react-native-elements'; import AppHeader from './header'; const spaceContent = ({ navigation }) => ( <View style={styles.container}> <ScrollView contentContainerStyle={styles.contentContainer} > <TouchableOpacity onPress={() => { navigation.navigate('Home'); navigation.dispatch(StackActions.popToTop()); }} > <AppHeader /> </TouchableOpacity> <Card style={styles.cardPadding} > <Card.Content> <Title style={styles.cardTitle}>宇宙ってなんだろう??</Title> <Card.Cover source={require('../../public/img/alien.png')} /> </Card.Content> </Card> <Card style={styles.cardPadding} > <Card.Content> <Paragraph style={styles.nextCardMessage} > Topics </Paragraph> <View style={styles.row}> <Chip style={styles.chip}> <Text style={styles.chipText}>宇宙開発</Text> </Chip> <Chip style={styles.chip}> <Text style={styles.chipText}>Jaxa</Text> </Chip> <Chip style={styles.chip}> <Text style={styles.chipText}>ISS</Text> </Chip> </View> </Card.Content> </Card> <Card style={styles.cardPadding} > <Card.Content> <Paragraph style={styles.nextCardMessage} > 作者 </Paragraph> <View style={styles.row}> <Avatar.Image size={70} source={require('../../public/img/space-travel.png')} /> <Text style={styles.avatarMessage}> Koitabashi Yoshitaka </Text> </View> </Card.Content> </Card> <Card style={styles.cardPadding} > <Card.Content> <Paragraph style={styles.nextCardMessage} > 物語 </Paragraph> <Text h3 style={styles.storyTitle}> はじめに </Text> <Text style={styles.storyBody}> 宇宙の誕生は、約138億年前のビッグバンから始まります。 </Text> <Image source={require('../../public/img/moon2.png')} style={{ width: 300, height: 200 }} /> <Text h4 style={styles.storyTitle}> ビックバンって、何〜? </Text> <Text style={styles.storyBody}> 人間のまばたきよりも短い時間の中で起こった超・高エネルギーの爆発ビックバンです。 ビッグバンにより、小さな物質同士が結合し合い、星の素となるチリやガスが生まれました。 {'\n'} さらに、それらの物質がくっつき合い、恒星や惑星といった星々が生まれたのです。 {'\n'} </Text> <Image source={require('../../public/img/moon1.png')} style={{ width: 300, height: 200 }} /> <Text style={styles.storyBody}> 誕生以来、宇宙は膨張を続けており、その膨張は加速し続けているといわれています。 {'\n'} そのため、宇宙の大きさは現在の科学でも解明できていません。 </Text> </Card.Content> </Card> </ScrollView> </View> ); const styles = StyleSheet.create({ container: { flex: 1, }, backButton: { paddingTop: 10, paddingBottom: 10, }, cardPadding: { textAlign: 'center', top: 60, marginBottom: 20, borderRadius: 5, marginLeft: 20, marginRight: 20, }, cardTitle: { marginBottom: 15, fontSize: 20, fontWeight: 'bold', }, cardMessage: { marginTop: 15, fontSize: 20, fontWeight: 'bold', }, nextCardMessage: { marginBottom: 20, fontSize: 20, fontWeight: 'bold', }, row: { flexDirection: 'row', flexWrap: 'wrap', paddingHorizontal: 12, }, chip: { backgroundColor: '#2096F3', margin: 2, }, chipText: { color: '#ffffff', }, avatarMessage: { marginLeft: 30, marginTop: 20, fontWeight: 'bold', textAlign: 'left', }, storyTitle: { marginTop: 20, marginBottom: 20, fontWeight: 'bold', }, storyBody: { marginTop: 20, fontWeight: 'bold', }, contentContainer: { paddingBottom: 60, }, }); export default spaceContent;おわり
・ 説明が雑になってきているので、だんだん追記していきます。w
・ 現在は、各コンテンツの内容をハードコーディングしているのですが、いずれ専用のAPIを作成するつもりなので、そこはとりあえず置いておきます。
・ あとは、Qittaのようにmarkdownで誰でも編集できるようにしていきたいと思ってます。参考文献