Sure, let's create a step-by-step guide to build a static portfolio website using React for the front end and Node.js with Express for the back end. This example assumes you have Node.js and npm installed on your machine.
Step 1: Set Up Your Project
Create a new project folder:
mkdir static-portfolio cd static-portfolio
Initialize a new Node.js project:
npm init -y
Install necessary dependencies:
npm install express
Step 2: Create Your Folder Structure
Create the following folder structure:
static-portfolio/
|-- public/
| |-- index.html
| |-- styles/
| |-- main.css
| |-- images/
| |-- your-image.jpg
|-- src/
| |-- components/
| |-- App.js
|-- server.js
Step 3: Set Up Express Server
In server.js
, set up a basic Express server:
const express = require('express');
const path = require('path');
const app = express();
const PORT = process.env.PORT || 3000;
// Serve static files
app.use(express.static(path.join(__dirname, 'public')));
// Handle all other routes
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'public', 'index.html'));
});
// Start the server
app.listen(PORT, () => {
console.log(`Server is running on http://localhost:${PORT}`);
});
Step 4: Create React Components
Create a simple React component in src/components/App.js
:
import React from 'react';
const App = () => {
return (
<div>
<h1>Your Name</h1>
<p>Web Developer</p>
{/* Add more sections and content as needed */}
</div>
);
};
export default App;
Step 5: Create HTML and CSS Files
In public/index.html
, create the HTML file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="styles/main.css">
<title>Your Portfolio</title>
</head>
<body>
<div id="root"></div>
<script src="/bundle.js"></script>
</body>
</html>
In public/styles/main.css
, add your styles:
body {
font-family: 'Arial', sans-serif;
margin: 0;
padding: 0;
}
/* Add your styling here */
It looks like you're encountering the error because you're trying to use ES6 import
syntax in a CommonJS environment. Node.js, by default, supports CommonJS modules, and you need to either use the .mjs
extension for ES6 modules or configure your project to use Babel for transpilation.
Let's address this by modifying the server.js
file to use CommonJS syntax:
// src/server.js
const express = require('express');
const React = require('react');
const ReactDOMServer = require('react-dom/server');
const App = require('./components/App').default; // Use .default to get the default export
const app = express();
const port = 3000;
app.get('/', (req, res) => {
const jsx = React.createElement(App);
const reactDom = ReactDOMServer.renderToString(jsx);
res.send(`
<!DOCTYPE html>
<html>
<head>
<title>React Express Template</title>
</head>
<body>
<div id="app">${reactDom}</div>
<script src="/bundle.js"></script>
</body>
</html>
`);
});
app.listen(port, () => {
console.log(`Server is running on http://localhost:${port}`);
});
Make sure to use .default
when importing the App
component because the default export is being used.
If you prefer to use ES6 import syntax throughout your project, you'll need to set up Babel for transpilation. To do this, you can create a .babelrc
file in your project root:
// .babelrc
{
"presets": ["@babel/preset-env", "@babel/preset-react"]
}
And install the necessary Babel packages:
npm install --save-dev @babel/core @babel/preset-env @babel/preset-react
Then, you can modify your package.json
start script to use babel-node
:
// package.json
{
"scripts": {
"start": "babel-node src/server.js"
}
}
Now, you should be able to use ES6 import syntax without encountering the "Cannot use import statement outside a module" error.
Step 6: Bundle ReactComponents
The warning you're encountering is likely due to the way you are importing the App
component. It seems that the imported object might be incorrect or not resolving to the expected component.
Let's make sure the import statement is correct and that the App
component is being exported properly.
Modify your server.js
file as follows:
// src/server.js
const express = require('express');
const React = require('react');
const ReactDOMServer = require('react-dom/server');
const App = require('./components/App').default; // Ensure to use .default
const app = express();
const port = 3000;
app.get('/', (req, res) => {
const jsx = React.createElement(App);
const reactDom = ReactDOMServer.renderToString(jsx);
res.send(`
<!DOCTYPE html>
<html>
<head>
<title>React Express Template</title>
</head>
<body>
<div id="app">${reactDom}</div>
<script src="/bundle.js"></script>
</body>
</html>
`);
});
app.listen(port, () => {
console.log(`Server is running on http://localhost:${port}`);
});
Ensure that your App.js
file looks like this:
// src/components/App.js
import React from 'react';
const App = () => {
return (
<div>
<h1>Hello from React!</h1>
</div>
);
};
export default App;
Make sure that the App
component is the default export from App.js
. The default
property is used when you import the module using require
.
After making these changes, restart your server and see if the warning persists. If the problem persists, you might want to inspect the actual content of the App
import and ensure that it is a valid React component. You can add a console.log(App)
just before the React.createElement
line to log the imported App
component to the console and check its structure.
Install React and ReactDOM, and set up a simple build script:
npm install react react-dom
Update package.json
with the following scripts:
"scripts": {
"build": "npx babel src --out-dir public --presets @babel/preset-react",
"start": "node server.js"
}
Run the build script:
npm run build
Step 7: Run Your Application
Start the Express server:
npm start
Visit http://localhost:3000 in your browser, and you should see your static portfolio page.
Step 8: Customize Your Portfolio
Modify the App.js
file and add more sections, content, and styles to customize your portfolio. Update the HTML and CSS files as needed.
Congratulations! You've successfully created a static portfolio website using React, Node.js, and Express.