如何同时运行Elixir(Phoenix)后端与Angular 8前端?
Hey there! Let's work through getting your Angular 8 + Elixir/Phoenix app running with a single command (just like your old Elm setup) and fix those missing template file requests. Here's a step-by-step breakdown of the best approaches:
1. Fix the Template 404 Issue First
The localhost:4000/app.component.html request error happens because you're likely running Angular in JIT (Just-in-Time) mode, which loads templates at runtime. For integration with Phoenix (and production-ready builds), switch to AOT (Ahead-of-Time) compilation—this embeds templates directly into your bundled JS files, eliminating external template requests.
To enable AOT:
- For development: Run
ng build --watch --aotinstead ofng serve - For production: Run
ng build --prod --aot(the--prodflag enables AOT by default in Angular 8, but explicitly adding it won't hurt)
2. Simplify Integration: Let Angular CLI Output Directly to Phoenix's Static Directory
Instead of manually copying files from Angular's dist folder or referencing them in your webpack config, configure Angular to build directly into Phoenix's priv/static directory. This aligns it with Phoenix's static asset pipeline.
Update angular.json
Find the outputPath setting under your project's architect.build.options and change it to point to Phoenix's static folder:
"outputPath": "../priv/static/angular"
Now when you run ng build, all compiled Angular assets (JS, CSS, assets) will go straight to where Phoenix expects them.
Serve Angular Assets from Phoenix
Add a static route in Phoenix's lib/your_app_web/router.ex to serve Angular's assets:
scope "/", YourAppWeb do pipe_through :browser # Serve Angular's static assets plug Plug.Static, at: "/angular", from: :your_app, gzip: false, only: ~w(angular js css assets) # Your other routes here... get "/*path", PageController, :index # Catch-all route for Angular SPA end
The catch-all route ensures Angular handles client-side routing correctly.
3. Unified Startup Command
To avoid running two separate commands (mix phx.server and ng build --watch), you can tie them together in one of two ways:
Option A: Use Phoenix Mix Aliases
Edit mix.exs and add a custom alias to run both processes:
defp aliases do [ # ... your existing aliases "dev": ["cmd ng build --watch --aot", "phx.server"] ] end
Now running mix dev will start Angular's watcher and Phoenix's server in sequence.
Option B: Use concurrently for Parallel Execution
If you prefer both processes running in parallel (so you see logs from both), install concurrently via npm:
npm install --save-dev concurrently
Then add a script to your project's root package.json:
"scripts": { "dev": "concurrently \"ng build --watch --aot\" \"mix phx.server\"" }
Run it with npm run dev.
4. If You Want to Stick with Custom Webpack
If you'd rather use your existing webpack config instead of Angular CLI, here are key fixes:
- Remove dist directory references: Your
entryshouldn't point toangular/dist/...files. Instead, let webpack compile Angular from source. Install Angular-specific webpack tools like@angular-devkit/build-angularto handle the compilation properly. - Ensure templates are embedded: Verify your
raw-loaderis correctly processing.htmlfiles—this will inline templates into JS, preventing 404s. - Auto-generate chunk files: Configure webpack's
optimization.splitChunksto automatically generate runtime, vendor, and styles chunks instead of manually referencing them:optimization: { splitChunks: { chunks: 'all', cacheGroups: { vendor: { test: /[\\/]node_modules[\\/]/, name: 'vendor', chunks: 'all' }, runtime: { name: 'runtime', chunks: 'all' } } }, // ... your existing minimizers }
Why Your Elm Project Worked Seamlessly
Elm's compilation is typically integrated directly into Phoenix's default webpack setup, so running mix phx.server triggers Elm compilation automatically. Angular has its own robust build tooling, so we just need to connect that tooling to Phoenix's workflow.
内容的提问来源于stack exchange,提问作者teatimes

