正在顯示「 2020 年 10 月 」的所有結果
10月 21, 2020 React
### Bundle

在使用 React 時是一定會使用到 Webpack 等等工具來把 JSX、CSS、IMAGES... 等等進行打包。如果你的 APP 已經建立得非常大時,產生的 Bundle 檔案也會非常巨大。使用者在下載時就會花上很多時間了喔 !

### 解決方法

我們可以通過使用 React 內建的 Lazy loading 來解決一次過下載巨大 Bundle 檔案的問題。它的原理是把單一的 Bundle 檔案依不同的 package 來分割開,然後在使用者實際使用時才動態載入。

### 內裏是 Promise

我們有以下的 module ,作用把兩個傳入的數字相加。

```js
// math.js
export default sum(a, b) => a + b;
```

在傳統的使用方法,我們是以下這樣 :

```js
import sum from './math.js';

console.log(sum(1, 2)); // 3
```

使用 Lazy Loading 的話,載入的 object 就會變成了 Promise 物件:

```js
import('./math.js')
	.then(sum => console.log(sum(1, 2))); // 3
```

### 實際使用

在實際使用上,我們可以通過使用 `React.lazy` 方法來簡單化整個載入的流程。

```js
// 載入 SomeComponent
const SomeComponent = React.lazy(() => import('./SomeComponent.jsx'));
```

然可以作為一般的 Component 來使用,但是需要放在 React.Suspense 元件內。

```js
<React.Suspense fallback={<div>Loading...</div>}>
	<SomeComponent />
</React.Suspense>
```

React.Suspense 是處理其子 Component 如果有 Lazy Loading 動作時,就會劃出 fallback 的元件出來,等待 Lazy Load 完成後,就會顯示元件。

### 筆者推介使用方法

因為在 React 內得多元件都可以重用,但是如果有使用 React Router 的話,不同 URL 之間的元件是一定不會重用的,所以我們可以簡單把 React.Suspense 包住整個 Router。然後把不同 Route 內的 Component 都轉成使用 Lazy Load,這樣就已經可以簡單快速地分割出合適的 Bundle 檔案了。

### 官方文件

官方文件 : https://zh-hant.reactjs.org/docs/code-splitting.html
10月 21, 2020 React
### Image slider / Carousels

在網站上很多時都會使用流水式的 Banner 來告訴使用者最近的事情。

![](https://cdn.19site.net/files/c7/fe/c7fe495b-dd20-41f2-85f0-9e57e10d96e2.png 'Image Slider 都概像這樣子')

### 選擇現成的 Library

初時筆者找到了 `react-alice-carousel` 這個套件,好像很簡單易用,所以後快速的試了一下。不過發現有個問題到現時最新的 Version 都好像還沒有修正好,就是在圖片滑動的中途,如果整個 Component 出現 unmount 的情況,就會出現 Error : Updated on unmounted component。

雖然在它們的 github 上好像沒有人 report 過這樣的 issue。不過筆者確實是遇到了,所以還是選擇另家的好了。

### nuka-carousel

這是另一家大神寫出來的 Image slider,使用上也是非常之簡單。  
Github: https://github.com/FormidableLabs/nuka-carousel

下面會簡單記錄一下使用的方法。

### 安裝

可以使用 npm 來安裝。

```sh
$ npm install nuka-carousel
```

### 使用

使用上也是十分之簡單,只要用 Carousel 包住想要用來 Slide 的內容就可以了,高度是自動的,內容可以用 Array 填入就可以。配上 Div 使用 background 來使用就非常得心應手。

```js
import React from 'react';
import Carousel from 'nuka-carousel';

export default class extends React.Component {
	render() {
		return (		
			<Carousel>
				<img src="https://via.placeholder.com/400/ffffff/c0392b/&text=slide1" />
				<img src="https://via.placeholder.com/400/ffffff/c0392b/&text=slide2" />
				<img src="https://via.placeholder.com/400/ffffff/c0392b/&text=slide3" />
				<img src="https://via.placeholder.com/400/ffffff/c0392b/&text=slide4" />
				<img src="https://via.placeholder.com/400/ffffff/c0392b/&text=slide5" />
				<img src="https://via.placeholder.com/400/ffffff/c0392b/&text=slide6" />
			</Carousel>
		);
	}
}
```

送上 div 顯示圖片的咒語:

```js
<div
	style={{
		background: '#FFFFFF url(https://via.placeholder.com/400/ffffff/c0392b/&text=slide1) center center / cover no-repeat',
		height: '0px',
		paddingBottom: '30%'
	}}
/>
```

以下是筆者使用的 Config:

```js
<Carousel 
	autoplay={ true }
	autoplayInterval={ 4000 }
	withoutControls={ false }
	wrapAround={ true }
	speed={ 1000 }
	renderCenterLeftControls={ () => {} }
	renderCenterRightControls={ () => {} }
>
	{items}
</Carousel>
```
### 設定 Nginx

要在 nginx 上取得 proxy 的 client address,需要事先在設定 nginx 時就要加入下
`--with-http_realip_module` 的設定。如果安裝的 nginx 是由 apt 上下載的,就可以使用以下指令來查看你的 nginx 有沒有設定 `--with-http_realip_module` 模組。

```sh
$ nginx -V

nginx version: nginx/1.18.0 (Ubuntu)
built with OpenSSL 1.1.1f  31 Mar 2020
TLS SNI support enabled
configure arguments: --with-cc-opt='-g -O2 -fdebug-prefix-map=/build/nginx-5J5hor/nginx-1.18.0=. -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -fPIC' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --modules-path=/usr/lib/nginx/modules --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-compat --with-pcre-jit --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_dav_module --with-http_slice_module --with-threads --with-http_addition_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module=dynamic --with-http_sub_module --with-http_xslt_module=dynamic --with-stream=dynamic --with-stream_ssl_module --with-mail=dynamic --with-mail_ssl_module
```

如果在輸出的結看看到了模組的名稱,就代表已經設定好了。

### 設定來自 Cloudflare 的 IP address

然後需要把來自 Cloudflare 的 IP address 設定到 nginx.conf 檔案內。

參考 Cloudflare 的網站 : https://support.cloudflare.com/hc/en-us/articles/200170786-Restoring-original-visitor-IPs-Logging-visitor-IP-addresses-with-mod-cloudflare-

```txt
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
set_real_ip_from 104.16.0.0/12;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 131.0.72.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 172.64.0.0/13;
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 197.234.240.0/22;
set_real_ip_from 198.41.128.0/17;
set_real_ip_from 2400:cb00::/32;
set_real_ip_from 2606:4700::/32;
set_real_ip_from 2803:f800::/32;
set_real_ip_from 2405:b500::/32;
set_real_ip_from 2405:8100::/32;
set_real_ip_from 2c0f:f248::/32;
set_real_ip_from 2a06:98c0::/29;
```

再設定 Cloudflare 的 IP 寫入 header 欄位名稱。

```txt
real_ip_header CF-Connecting-IP;
#real_ip_header X-Forwarded-For;
```

設定好後,在 Nginx 的 Virtual Host Config 檔案內使用變數 $remote_addr 時,就可以取得 Cloudflare 傳入的真正地址了。

下面是 Virtual Host Config 檔案使用 Reverse proxy 的例子 :

```txt
location / {
	proxy_set_header X-Forwarded-For $remote_addr;
	proxy_set_header Host $http_host;
	proxy_pass https://localhost:81;
}
```
10月 05, 2020 Javascript
由於不同之間的 browser 都有差異,所以如果要保險起見,需要以多種的語法來最最得 scroll top 值來確保安全。而已經有大神寫好了這個簡單的語法 !

```js
window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0
```
過去文章
2025 (9)
4 (5)
3 (1)
2 (3)
2024 (25)
11 (3)
10 (3)
9 (1)
3 (18)
2022 (6)
10 (1)
6 (2)
5 (1)
3 (1)
1 (1)
2021 (21)
11 (7)
7 (1)
6 (2)
5 (2)
4 (6)
3 (2)
2 (1)
2020 (92)
12 (1)
11 (2)
10 (4)
9 (10)
8 (5)
7 (1)
6 (3)
5 (1)
4 (4)
3 (25)
2 (7)
1 (29)
2019 (57)
12 (25)
11 (7)
9 (25)