How to Deploy an Express.js App on GitHub Pages Using GitHub Actions
Deploying an Express.js app on GitHub Pages might sound challenging at first, but with the right tools and steps, it becomes a seamless process. GitHub Pages only supports static sites, so we need to convert our dynamic Express.js app into static files. In this article, we'll walk through the steps to achieve this using Webpack for bundling and GitHub Actions for automation.
Step 1: Set Up Your Express.js App
First, ensure you have an Express.js app. If you don't have one, you can create a simple app as follows:
mkdir express-app
cd express-app
npm init -y
npm install express
Create a file named server.js
:
const express = require('express');
const path = require('path');
const app = express();
app.use(express.static(path.join(__dirname, 'dist')));
app.get('*', (req, res) => {
res.sendFile(path.resolve(__dirname, 'dist', 'index.html'));
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
Step 2: Set Up Webpack
To bundle your app into static files, we'll use Webpack. Install Webpack and its dependencies:
npm install --save-dev webpack webpack-cli babel-loader @babel/core @babel/preset-env @babel/preset-react
Create a webpack.config.js
file:
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env', '@babel/preset-react'],
},
},
},
],
},
};
In your package.json
, add a build script:
"scripts": {
"build": "webpack --mode production"
}
Step 3: Create Your React Components
If you're using React with Express, create a simple React component. Create a directory src
and an index.js
file inside it:
import React from 'react';
import ReactDOM from 'react-dom';
const App = () => {
return (
<div>
<h1>Hello, Express and React!</h1>
</div>
);
};
ReactDOM.render(<App />, document.getElementById('root'));
Add an index.html
file in the src
directory:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Express App</title>
</head>
<body>
<div id="root"></div>
<script src="bundle.js"></script>
</body>
</html>
Step 4: Configure GitHub Actions
To automate the build and deployment process, create a GitHub Actions workflow. In your repository, create a .github/workflows/deploy.yml
file:
name: Deploy Express.js App to GitHub Pages
on:
push:
branches:
- main # Trigger the workflow on push to the main branch
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: '16'
- name: Install dependencies
run: npm install
- name: Build project
run: npm run build
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./dist
Step 5: Ensure Your Static Files Are Managed Properly
Make sure the dist
directory is included in your .gitignore
file, so it's not tracked in your repository:
/dist
Step 6: Commit and Push Your Code
Add, commit, and push your code to GitHub:
git add .
git commit -m "Set up deployment to GitHub Pages"
git push origin main
Conclusion
By following these steps, you can convert your Express.js app into static files and deploy it to GitHub Pages using GitHub Actions. This approach leverages Webpack for bundling and GitHub Actions for CI/CD, providing a streamlined deployment process.
If you have any questions or run into any issues, feel free to leave a comment below. Happy coding!
Top comments (1)
To be clear, GitHub Pages cannot run Express. The express part is completely ignored by the action that pushes to GitHub pages. Furthermore, by reading the example, this must be copied from an old source. For example, it installs Node v16 when the latest is v20, the checkout action is already v4; same for actions-gh-pages. If authors are taking the easy path of copying and pasting articles from other places, they should at least curate the content.