Sitemap
Lola

Lola

0Lolatw

[React] Typescript +WebPack + Firebase Hosting

9 min readFeb 10, 2023

--

因為是寫 Angular 的過來人,基本上不寫 Typescript 渾身不對勁,所以寫React 當然也用 Typescript。

建立 React Typescript 可參考官方文件,以下記錄自己開發時用到的打包工具,使用版本為 WebPack 5 。

1. 安裝 Webpack 及相關套件

官方教學:webpack。在 Global 安裝 webpack,這邊直接安裝最新版。

$ npm install -g webpack@latest
$ npm install -g webpack-cli@latest

接下來的套件,使用 npm install {lib_name} --save-dev 安裝即可,因為 webpack 打包使用的套件,在佈署到 server 上網站是用不到的。

以下套件不一定每個都會使用到,或者有習慣的替代方案也都可以抽換。

// 建議安裝,本地啟動測試用
$ npm install --save-dev webpack-dev-server

// 各種 loader
$ npm install --save-dev ts-loader
$ npm install --save-dev style-loader
$ npm install --save-dev css-loader

// babel
$ npm install --save-dev @babel/core
$ npm install --save-dev @babel/preset-env
$ npm install --save-dev @babel/preset-react
$ npm install --save-dev babel-loader

// 決定 HTML 引入
$ npm install --save-dev html-webpack-plugin

// 環境變數
$ npm install --save-dev dotenv-webpack

2. 建立 webpack.config.js

接下來在專案根目錄建立 webpack.config.js

const webpack = require('webpack');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
mode: 'development',
entry: './src/index.tsx',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: '/'
},
resolve: {
extensions: ['.tsx', '.ts', '.js']
},
module: {
rules: [{
test: /\.(ts|tsx)$/,
exclude: /node_modules/,
loader: 'ts-loader',
include: path.join(__dirname, 'src')
},
{
test: /\.(js|jsx)$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel-loader',
options: { presets: ['@babel/env', '@babel/preset-react'] },
},
{
test: /\.css$/i,
use: ['style-loader', 'css-loader'],
},
// webpack 5 圖片引入
{
test: /\.svg/,
type: 'asset/inline'
},
{
test: /\.(png|jpeg)$/,
type: 'asset/resource'
}
],
},
plugins: [
new HtmlWebpackPlugin({
filename: "index.html",
// 請把根目錄的 public 移動到 src 下
template: './src/public/index.html'
}),
new webpack.DefinePlugin({
environment: JSON.stringify({
API : 'your_local_api'
}),
}),
],
// webpack-dev-server run on port 4000
devServer: {
static: path.join(__dirname, "dist"),
compress: false,
port: 4000,
historyApiFallback: true,
open: true
},
};

Webpack 5 針對 raw-loader、url-loader、file-loader 改為使用 asset/* 的方式,詳細文件請參閱:Asset Modules | webpack。

使用環境變數

webpack.DefinePlugin 可以儲存環境變數,在 typescript 上的引入方式比較麻煩:

declare const environment: any;
const _environment = environment
export { _environment as environment };

export const API = environment['API'];

Typescript 的編譯調整

根目錄的 tsconfig.json

{
"compilerOptions": {
// + webpack output 的檔案目錄
"outDir": "./dist/",
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": false,
"jsx": "react-jsx",
"noImplicitAny": false,
"strictPropertyInitialization": false,
"removeComments": true
},
"include": [
"src"
]
}

3. 指令

package.json 的指令

{
...,
"scripts": {
// 本地啟動
"dev": "webpack-dev-server --mode=development",
// 打包 webpack.config.js (dev 環境)
"build:dev": "webpack --config webpack.config.js",
// 打包 webpack.prod.config.js (prod 環境)
"build:prod": "webpack --config webpack.prod.config.js",
// firebase 部屬專案流量小都不收費,可以建立一個來測試是否有部屬成功
"deploy": "webpack --config webpack.prod.config.js && firebase deploy"
},
}

這邊把環境變數 API 顯示在畫面上,本地啟動就會看到 your_local_api。

Press enter or click to view image in full size

4. [Optional] 佈署到 Firebase 上

這邊是示範如何打包佈署到 Firebase 上,因為 Firebase Hosting(同 github page)在一定用量下是免費的,推薦可以試試。

  1. 至 Firebase Console 建立專案,並選擇「Hosting」。
Press enter or click to view image in full size

2. 接著照著 「設定 Firebase 託管」的步驟安裝。

Get Lola’s stories in your inbox

Join Medium for free to get updates from this writer.

如果不清楚如何回答 firebase init 的問題,下方為懶人包:


1. Which Firebase features do you want to set up for this directory? Press Space to select features, then Enter to confir
m your choices.
> Hosting: Configure files for Firebase Hosting and (optionally) set up GitHub Action deploys

2. Please select an option:
> Use an existing project

// 以下選錯也沒關係,firebase 只是幫你建檔而已
3. What do you want to use as your public directory?
> dist

4. Configure as a single-page app (rewrite all urls to /index.html)?
> Yes

5. Set up automatic builds and deploys with GitHub?
> No

接著本地專案就會出現 firebase.json ,如果有不同請調整:

{
"hosting": {
"public": "dist",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
}
}

佈署

於根目錄執行 npm run deploy 後就可以將服務佈署至 Firebase 了。

範例:React App (react-0lolatw-webpack.web.app)

Press enter or click to view image in full size

程式碼:0Lola/react-0lolatw-webpack: react + typescript+ webpack + delpy to firebase (github.com)

--

--