熟悉Angular新手:基于Node.js(Express)与Ember.js搭建简易CMS的疑问
Hey there! Since you’re already comfortable with Angular, picking up Ember should feel familiar once you get past the initial convention differences. Let’s walk through building your CMS with Express (public site) and Ember (admin dashboard) step by step.
I’d recommend organizing your project like this to keep things clean and separated:
your-cms/ ├── public-site/ # Express + Handlebars public frontend │ ├── views/ # Handlebars templates (layouts + pages) │ ├── routes/ # Public page route handlers │ ├── public/ # Static assets (CSS, JS, images) │ └── server.js # Express entry point ├── admin-dashboard/ # Ember.js admin application │ ├── app/ # Core Ember code (routes, components, services) │ └── dist/ # Built Ember app (served by Express in production) └── package.json # Optional: root scripts to run both apps at once
First, initialize your Express project and install dependencies:
- Create the
public-sitefolder, runnpm init -y - Install required packages:
npm install express express-handlebars cors body-parser
Here’s a basic server.js to get started with Handlebars and API endpoints:
const express = require('express'); const exphbs = require('express-handlebars'); const cors = require('cors'); const bodyParser = require('body-parser'); const app = express(); const PORT = process.env.PORT || 3000; // Configure Handlebars as the view engine app.engine('handlebars', exphbs({ defaultLayout: 'main' })); app.set('view engine', 'handlebars'); // Middleware setup app.use(cors()); app.use(bodyParser.json()); app.use(express.static('public')); // Public page route example (home page) app.get('/', (req, res) => { res.render('home', { title: 'Welcome to My CMS' }); }); // API routes for Ember admin (replace with database logic later) app.get('/api/posts', (req, res) => { res.json([{ id: 1, title: 'First Post', content: 'Hello CMS World!' }]); }); app.listen(PORT, () => { console.log(`Express server running on port ${PORT}`); });
Create a views/layouts/main.handlebars base template and views/home.handlebars for your home page content to get the public site working.
Ember CLI works similarly to Angular CLI but follows stricter conventions—perfect for building a structured admin interface:
- Install Ember CLI globally:
npm install -g ember-cli - Create the admin app:
ember new admin-dashboard - Start the dev server:
cd admin-dashboard && ember serve(runs on port 4200 by default, just like Angular)
Key Ember Concepts (Angular Parallels)
Since you know Angular, here’s a quick mapping to ease your transition:
- Routes: Ember’s router is declarative, like Angular’s Router. Use
ember generate route poststo auto-create route, template, and controller files. - Components: Reusable components work just like Angular’s—run
ember generate component post-formto build a form for creating/editing content. - Services: Singleton services (same as Angular’s) for shared logic (API calls, auth). Use
ember generate service apito create an API communication service.
Configure Ember for Development
Update admin-dashboard/config/environment.js to point to your Express API and avoid route conflicts:
const ENV = { // ... other settings apiUrl: process.env.API_URL || 'http://localhost:3000/api', locationType: 'hash', // Prevents Ember routes from clashing with Express in dev }; if (environment === 'development') { ENV.APP.API_URL = 'http://localhost:3000/api'; }
Let’s build an Ember service to handle API calls (similar to Angular’s HttpClient):
Run ember generate service api and update app/services/api.js:
import Service from '@ember/service'; import fetch from 'fetch'; export default class ApiService extends Service { async getPosts() { const response = await fetch(`${ENV.apiUrl}/posts`); return await response.json(); } async createPost(postData) { const response = await fetch(`${ENV.apiUrl}/posts`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(postData) }); return await response.json(); } }
Then use this service in your posts route (app/routes/posts.js) to load data:
import Route from '@ember/routing/route'; import { inject as service } from '@ember/service'; export default class PostsRoute extends Route { @service api; async model() { return await this.api.getPosts(); } }
Add the corresponding POST endpoint to your Express server.js:
app.post('/api/posts', (req, res) => { // Replace with actual database save logic const newPost = { id: Date.now(), ...req.body }; res.status(201).json(newPost); });
When you’re ready to test the full app or deploy:
- Build the Ember admin app:
cd admin-dashboard && ember build --environment production - Update your Express
server.jsto serve the Ember build at/admin:
// Serve Ember admin static files app.use('/admin', express.static('../admin-dashboard/dist')); // Catch-all for Ember routes (ensures Ember's router works) app.get('/admin/*', (req, res) => { res.sendFile('../admin-dashboard/dist/index.html', { root: __dirname }); });
Now running npm start in public-site lets you access:
- Public site:
http://localhost:3000 - Admin dashboard:
http://localhost:3000/admin
- Local Dev: Run
ember serve(admin) andnpm start(Express) simultaneously. Ember’s hot reload works just like Angular’s. - Auth: Add JWT authentication to your Express API, then use Ember’s
ember-simple-authaddon (similar to Angular’s auth guards) to protect admin routes. - Environment Variables: Use
dotenvin Express and Ember’s environment config to switch between dev/production API URLs.
| Angular Concept | Ember Equivalent | Notes |
|---|---|---|
| Angular CLI | Ember CLI | Use ember generate instead of ng generate; stricter conventions |
| HttpClient | Fetch API / Ember Data | Ember Data is an ORM for REST APIs (like Angular services + RxJS) |
| Components | Ember Components | Templates use Handlebars (which you already use in Express!) |
| Services | Ember Services | Singleton by default, injected with @service decorator |
| Router Guards | Ember Route Hooks | Use beforeModel to check auth before rendering a route |
内容的提问来源于stack exchange,提问作者Alexandro

