Markdownエディタを作成します.JTTUBアクションによる配備をもつJSとタイプスクリプト
何を学ぶ
プロジェクトソースコード:
アシュワーム / 対応するスクリプトの編集
反応の使用によるMarkdownエディタ。JTTUBアクションワークフローを使用して連続展開と組み合わせるJSとTypesScript
プロジェクトデモ:Ashwamegh /反応TypeScriptのマークダウンエディタ
プロジェクトの設定から始めましょう
1 .プロジェクトを設定します。JSとタイプスクリプト
私たちはすべてのタイプスクリプトの機能を知って、どのようにあなたの愚かなミスの日を保存することができます.そして、反応と結合されるならば、彼らはどんなアプリケーションにでも力を与えるすばらしい組合せになります.
私は使用されます
create-react-app
以来、それはボックスから入力スクリプトをサポートします.ルートディレクトリに移動し、プロジェクトを作成し、このコマンドを実行します.npx create-react-app markdown-editor --template typescript
この--template typescript
フラグはあなたのためのすべてのハードワークを行い、反応を設定します.JSプロジェクト.後で、ブートストラップされたコードの一部を削除してアプリケーションを作成する必要があります.
参考のために、この初期のコミットをチェックして、何が削除されたかを確認できます.
https://github.com/ashwamegh/react-typescript-markdown-editor/commit/7cc379ec0d01f3f1a07396ff2ac6c170785df57b
あなたが最初の手順を完了した後、最終的に我々のマルクダウンエディタを作成するに移動します.2 . Markdownエディタの作成
コードに飛び込む前に、プロジェクトのフォルダ構造を見てみましょう.
├── README.md
├── package.json
├── public
| ├── favicon.ico
| ├── index.html
| ├── logo192.png
| ├── logo512.png
| ├── manifest.json
| └── robots.txt
├── src
| ├── App.test.tsx
| ├── App.tsx
| ├── components
| | ├── Editor.tsx
| | ├── Footer.tsx
| | ├── Header.tsx
| | ├── Main.tsx
| | ├── Preview.tsx
| | └── shared
| | └── index.tsx
| ├── index.css
| ├── index.tsx
| ├── react-app-env.d.ts
| ├── serviceWorker.ts
| ├── setupTests.ts
| └── userDarkMode.js
├── tsconfig.json
└── yarn.lock
私は使用されますemotion
コンポーネントとスタイルの作成react-icons
プロジェクトで使用するアイコン.だからインストールする必要があるでしょうemotion
and react-icons
このコマンドを実行します.npm i -S @emotion/core @emotion/styled react-icons
または使用している場合yarn
私のようにyarn add @emotion/core @emotion/styled react-icons
まず最初に、我々はshared
コンポーネントフォルダを作成するコンポーネントを再利用されます.
/* src/components/shared/index.tsx */
import React from 'react'
import styled from '@emotion/styled'
export const ColumnFlex = styled.div`
display: flex;
flex-direction: column;
`
export const RowFlex = styled.div`
display: flex;
flex-direction: row;
`
In this file, we have declared two styled components for
flex-column
andflex-row
styleddivs
which we'll be using later.
To know more aboutstyled-components
withemotion
library, head on to this link.
3反応フックを使用してカスタムテーマフックを作成する
我々は、我々は光から暗い色まで私たちのテーマを切り替えることができます使用して、基本的なテーマ機能を実装するために私たちのカスタムフックを作成するために反応フックを使用します.
/* useDarMode.js */
import { useEffect, useState } from 'react'
export default () => {
const [theme, setTheme] = useState('light')
const toggleTheme = () => {
if (theme === 'dark') {
setTheme('light')
} else {
setTheme('dark')
}
}
useEffect(() => {
const localTheme = localStorage.getItem('theme')
if (localTheme) {
setTheme(localTheme)
}
}, [])
return {
theme,
toggleTheme,
}
}
In our hooks file, we are setting the initial state of the theme to be
light
usinguseState
hook. And usinguseEffect
to check whether any theme item exists in our browser's local storage, and if there is one, pick the theme from there and set it for our application.
以来、私たちは私たちの共有コンポーネントとカスタムをテーマに、私たちのアプリのコンポーネントに飛び込みましょうフックの反応を定義している.
だから、私は5つのコンポーネントに我々のアプリの構造を分割している:ヘッダー、メイン(エディタ&プレビューコンポーネントとアプリケーションのメインセクションが含まれています)とフッターコンポーネント.
エディタのためのコード
IIプレビュー//マークダウンコードをHTMLにプレビューするコードが含まれています
/* src/components/Header.tsx */
import React from 'react'
import { FiSun } from 'react-icons/fi'
import { FaMoon } from 'react-icons/fa'
// this comment tells babel to convert jsx to calls to a function called jsx instead of React.createElement
/** @jsx jsx */
import { css, jsx } from '@emotion/core'
// Prop check in typescript
interface Props {
toggleTheme: () => void,
theme: string
}
const Header: React.FC<Props> = ({ theme, toggleTheme }) => {
return (
<header
css={theme === 'dark' ?
css`
display: flex;
flex-direction: row;
justify-content: space-between;
background-color: #f89541;
padding: 24px 32px;
font-size: 16px;
`:css`
display: flex;
flex-direction: row;
justify-content: space-between;
background-color: #f8f541;
padding: 24px 32px;
box-shadow: 0px -2px 8px #000;
font-size: 16px;
`}>
<div className="header-title">
Markdown Editor
</div>
<div css={
css`
cursor: pointer;
`}
onClick={toggleTheme}
>
{
theme === 'dark'?
<FaMoon />:
<FiSun />
}
</div>
</header>
)
}
export default Header;
In this component, we are using TypeScript for prop checks and you may wonder, why we're mentioning
React.FC
here. Its just that, by typing our component as an FC (FunctionComponent), the React TypeScripts types allow us to handle children and defaultProps correctly.
我々のコンポーネントを使用してスタイリングのために
css
文字列形式のプロップemotion
ライブラリについては、ドキュメントに従うことにより、これについての詳細を学ぶことができますhere ヘッダーコンポーネントを作成した後、フッターコンポーネントを作成し、メインコンポーネントに移動します.
フッターコンポーネントのコードを見ましょう
import React from 'react'
// this comment tells babel to convert jsx to calls to a function called jsx instead of React.createElement
/** @jsx jsx */
import { css, jsx } from '@emotion/core'
const Footer: React.FC = () => {
return (
<footer>
<div
className="footer-description"
css={
css`
padding: 16px 0px;
overflow: hidden;
position: absolute;
width: 100%;
text-align: center;
bottom: 0px;
color: #f89541;
background: #000;
`
}>
<span>{`</>`}</span><span> with <a href="https://reactjs.org" target="_blank">React.js</a> & <a href="https://www.typescriptlang.org/" target="_blank">TypeScript</a></span>
</div>
</footer>
)
}
export default Footer;
Footerコンポーネントは、通常のクレジットをレンダリングする単純なコードが含まれます./* src/components/Main.tsx */
import React, { useState } from 'react'
// this comment tells babel to convert jsx to calls to a function called jsx instead of React.createElement
/** @jsx jsx */
import { css, jsx } from '@emotion/core'
import { RowFlex } from './shared'
import Editor from './Editor';
import Preview from './Preview';
interface Props {
theme: string
}
const Main: React.FC<Props> = ({ theme }) => {
const [markdownContent, setMarkdownContent] = useState<string>(`
# H1
## H2
### H3
#### H4
##### H5
__bold__
**bold**
_italic_
`);
return (
<RowFlex
css={css`
padding: 32px;
padding-top: 0px;
height: calc(100vh - 170px);
`}>
<Editor theme={theme} markdownContent={markdownContent} setMarkdownContent={setMarkdownContent}/>
<Preview theme={theme} markdownContent={markdownContent}/>
</RowFlex>
)
}
export default Main;
以来、コードのいくつかは、あなたが今あなた自身を理解できる前のコンポーネントからあなたに精通しているように見えます.それ以外は、我々は使用しているuseState
フックのマークダウンコンテンツとハンドラを保持する状態を作成するsetMarkdownContent
コードで.We need to pass these down to our
Editor
andPreview
components, so that, they can provide the user the way to edit and preview their markdown content. We have also set an initial state for content with some basic markdown text.
エディタコンポーネントのコードを参照してください.
/* src/components/Editor.tsx */
import React, { ChangeEvent } from 'react'
import PropTypes from 'prop-types';
// this comment tells babel to convert jsx to calls to a function called jsx instead of React.createElement
/** @jsx jsx */
import { css, jsx } from '@emotion/core'
import { ColumnFlex } from './shared'
interface Props {
markdownContent: string;
setMarkdownContent: (value: string) => void,
theme: string
}
const Editor: React.FC<Props> = ({ markdownContent, setMarkdownContent, theme }) => {
return (
<ColumnFlex
id="editor"
css={css`
flex: 1;
padding: 16px;
`}>
<h2>
Editor
</h2>
<textarea
onChange={(e: ChangeEvent<HTMLTextAreaElement>) => setMarkdownContent(e.target.value)}
css={theme === 'dark'?
css`
height: 100%;
border-radius: 4px;
border: none;
box-shadow: 0 -2px 10px rgba(0, 0, 0, 1);
background: #000;
color: #fff;
font-size: 100%;
line-height: inherit;
padding: 8px 16px;
resize: none;
overflow: auto;
&:focus {
outline: none;
}
`
: css`
height: 100%;
border-radius: 4px;
border: none;
box-shadow: 2px 2px 10px #999;
font-size: 100%;
line-height: inherit;
padding: 8px 16px;
resize: none;
overflow: auto;
&:focus {
outline: none;
}
`}
rows={9}
value={markdownContent}
/>
</ColumnFlex>
)
}
Editor.propTypes = {
markdownContent: PropTypes.string.isRequired,
setMarkdownContent: PropTypes.func.isRequired,
}
export default Editor;
This is a straight forward component which uses
<textarea/>
to provide the user a way to enter their inputs, which have to be further compiled down to render it as HTML content in the Preview component.
ここで、プレビューコンポーネント以外のほとんどのコンポーネントを作成しました.
ユーザのマークダウンコンテンツを簡単なHTMLにコンパイルするために何かを必要とするでしょう.そして、私たちにはすべてのコンパイラコードを書きたくありません.
このアプリケーションでは、我々は使用されます
marked
ライブラリをHTMLにマークダウンコンテンツをコンパイルする.したがって、このコマンドを実行することで、インストールする必要があります.npm i -S marked
または糸でyarn add marked
If you want to know more about this library, you can see it here
プレビューコンポーネントのコードを見ましょう
/* src/components/Preview.tsx */
import React from 'react'
import PropTypes from 'prop-types'
import marked from 'marked'
// this comment tells babel to convert jsx to calls to a function called jsx instead of React.createElement
/** @jsx jsx */
import { css, jsx } from '@emotion/core'
import { ColumnFlex } from './shared'
interface Props {
markdownContent: string,
theme: string
}
const Preview: React.FC<Props> = ({ markdownContent, theme }) => {
const mardownFormattedContent = ( marked(markdownContent));
return (
<ColumnFlex
id="preview"
css={css`
flex: 1;
padding: 16px;
`}
>
<h2>Preview</h2>
<div
css={theme === 'dark'
? css`
height: 100%;
border-radius: 4px;
border: none;
box-shadow: 0 -2px 10px rgba(0, 0, 0, 1);
font-size: 100%;
line-height: inherit;
overflow: auto;
background: #000;
padding: 8px 16px;
color: #fff;
`
: css`
height: 100%;
border-radius: 4px;
border: none;
box-shadow: 2px 2px 10px #999;
font-size: 100%;
line-height: inherit;
overflow: auto;
background: #fff;
padding: 8px 16px;
color: #000;
`}
dangerouslySetInnerHTML={{__html: mardownFormattedContent}}
>
</div>
</ColumnFlex>
)
}
Preview.propTypes = {
markdownContent: PropTypes.string.isRequired
}
export default Preview;
In this component, we are compiling the markdown content and storing it in mardownFormattedContent variable. And to show a preview of the content in HTML, we will have to use
dangerouslySetInnerHTML
prop to display the HTML content directly into our DOM, which we are doing by adding thisdangerouslySetInnerHTML={{__html: mardownFormattedContent}}
prop for the div element.
最後に、私たちのMarkdown Editorアプリケーションを作成する必要があるすべてのコンポーネントで準備ができています.私たちのすべてを持っていきましょう
App.tsx
ファイル./* src/App.tsx */
import React from 'react'
import { css, jsx } from '@emotion/core'
// Components
import Header from './components/Header'
import Main from './components/Main'
import Footer from './components/Footer';
import useDarkMode from './userDarkMode';
function App() {
const { theme, toggleTheme } = useDarkMode();
const themeStyles = theme === 'light'? {
backgroundColor: '#eee',
color: '#000'
}: {
backgroundColor: '#171616',
color: '#fff'
}
return (
<div
className="App"
style={themeStyles}
>
<Header theme={theme} toggleTheme={toggleTheme}/>
<Main theme={theme}/>
<Footer />
</div>
);
}
export default App;
我々のアプリのコンポーネントでは、我々は、子コンポーネントをインポートし、テーマの小道具を渡す.さて、上記のすべての手順に従っているならば、実行中のMarkdown Editorアプリケーションを持っているでしょう、私が使用したスタイルのために、あなたは私が述べたリンクを使用して私のソースコードを見ることができます.
Now, its time to create Github actions for our project to create continuous deployment workflow on every push to master.
4 githubアクションを通して連続配備を準備すること
我々は、Githubアクションのワークフローを使用してビルドし、すべてのプッシュをマスターにWebアプリケーションを展開します.
Since this is not a enterprise application that holds the branches for production and development, I will setup my workflow for master branch, but if in any time in future, you require to setup the Github action workflow for your enterprise application, Just be careful with the branches.
そのためにいくつかの手順に従います.
.github/workflows/
, これはすべてのワークフロー設定を保持します.JamesIves/github-pages-deploy-action
アプリケーションを配備するアクション..yml
ここでは、Githubページへのアプリケーションのビルドと配備の責任があります.名前を挙げましょうbuild-and-deploy-to-gh-pages.yml
build-and-deploy-to-gh-pages.yml
# build-and-deploy-to-gh-pages.yml
name: Build & deploy to GitHub Pages
on:
push:
branches:
- master
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v1
- name: Set up Node
uses: actions/setup-node@v1
with:
node-version: 10.x
- name: Set email
run: git config --global user.email "${{ secrets.adminemail }}"
- name: Set username
run: git config --global user.name "${{ secrets.adminname }}"
- name: npm install command
run: npm install
- name: Run build command
run: npm run build
- name: Deploy
uses: JamesIves/github-pages-deploy-action@releases/v3
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BASE_BRANCH: master
BRANCH: gh-pages # The branch the action should deploy to.
FOLDER: build # The folder the action should deploy.
このワークフローは、毎回実行され、我々はマスターに何かをプッシュしてgh-pages
枝.ワークフローファイルを破壊しましょう
name: Build & deploy to GitHub Pages
on:
push:
branches:
- master
これは、ワークフローの名前とトリガーを定義し、その中のジョブを実行します.ここでは、トリガを設定する任意のを聞いているPush
イベントmaster
枝.jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v1
- name: Set up Node
uses: actions/setup-node@v1
with:
node-version: 10.x
- name: Set email
run: git config --global user.email "${{ secrets.adminemail }}"
- name: Set username
run: git config --global user.name "${{ secrets.adminname }}"
- name: npm install command
run: npm install
- name: Run build command
run: npm run build
- name: Deploy
uses: JamesIves/github-pages-deploy-action@releases/v3
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BASE_BRANCH: master
BRANCH: gh-pages # The branch the action should deploy to.
FOLDER: build # The folder the action should deploy.
これは、我々のワークフローで最も重要な部分ですjobs
される.設定の行のいくつかは自明ですruns-on: ubuntu-latest
これはシステムを定義します.- name: Checkout
uses: actions/checkout@v1
これはREPOをチェックするためのアクションで、後のジョブではノードをインストールしてGitプロファイル設定を設定して開発環境を設定しています.その後、我々は実行しているnpm install
すべての依存関係を引き出し、最終的に実行するbuild
コマンド.- name: Deploy
uses: JamesIves/github-pages-deploy-action@releases/v3
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BASE_BRANCH: master
BRANCH: gh-pages # The branch the action should deploy to.
FOLDER: build # The folder the action should deploy.
After the build command has been completed, we are using
JamesIves/github-pages-deploy-action@releases/v3
action to deploy our build folder togh-pages
.
いつでも、あなたのマスターブランチに何かをプッシュします
gh-pages
枝.さて、展開が完了したら、すべてのあなたのアプリケーションをgithubリンクを実行しているhttps://yourusername.github.io/markdown-editor/ .
Don't forget to add
"homepage" : "https://yourusername.github.io/markdown-editor/"
inpackage.json
file, otherwise serving of static contents may cause problem.
あなたが私の記事が好きならば、あなたは私の毎日の紙のためにさえずりの上で私に続くことができます
The JavaSc®ipt Showcase
, また、あなたはGithubの上に私の個人的なプロジェクトに従うことができます.コメントを投稿してください.ありがとう液体誤差:内部
アシュワーム / 対応するスクリプトの編集
反応の使用によるMarkdownエディタ。JTTUBアクションワークフローを使用して連続展開と組み合わせるJSとTypesScript
Reference
この問題について(Markdownエディタを作成します.JTTUBアクションによる配備をもつJSとタイプスクリプト), 我々は、より多くの情報をここで見つけました https://dev.to/ashwamegh/creating-a-markdown-editor-in-react-js-typescript-with-deployment-through-github-actions-hfnテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol