Angular CLI v6子目录部署路由问题:直接访问功能路由失效
Hey there, let's work through your issues one by one—first off, deploying an Angular CLI v6 app to a subdirectory is fully supported, and you don't need to split your Feature A and Feature B into separate apps. Hash routing is an option, but it's not the only one. Let's break down what's going wrong and how to fix it:
1. Why Directly Visiting /root/featureB Shows Feature A
Angular is a single-page application (SPA), which means all routes are handled client-side by Angular's router. When you type /root/featureB into your browser, your web server tries to find a physical file at that path (like /root/featureB/index.html), which doesn't exist. Instead, it falls back to serving the root /root/index.html (or even the domain root index.html if your server isn't configured right), but since the router isn't initialized properly for the subdirectory, it defaults to your Feature A route.
Fix: Configure Your Web Server to Rewrite Requests
You need to tell your server to forward all requests under /root/ to /root/index.html so Angular's router can take over. Here are common configs:
- Apache: Create a
.htaccessfile in your/root/directory with:RewriteEngine On RewriteBase /root/ RewriteRule ^index\.html$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /root/index.html [L] - Nginx: Add this to your server block:
location /root/ { try_files $uri $uri/ /root/index.html; } - IIS: Create a
web.configfile in/root/with:<configuration> <system.webServer> <rewrite> <rules> <rule name="Angular Routes" stopProcessing="true"> <match url=".*" /> <conditions logicalGrouping="MatchAll"> <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" /> <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" /> </conditions> <action type="Rewrite" url="/root/index.html" /> </rule> </rules> </rewrite> </system.webServer> </configuration>
2. Router-Outlet Placement Mistake
You mentioned adding <router-outlet> to index.html—that's the problem! The index.html is just the static entry point for your Angular app; it doesn't get processed by Angular's template compiler. The <router-outlet> needs to be placed inside your root component's template (usually app.component.html).
Think of it this way: Angular boots up into the root component (AppComponent), and that component's template is where the router injects your feature components. If you put <router-outlet> in index.html, Angular doesn't recognize it as part of its component tree, so it can't replace the content with your Feature A/B components.
3. EnableTracing Shows Route Recognized But Component Not Loading
This ties directly to the router-outlet issue. Angular's router is correctly parsing the URL, but there's nowhere to render the component because the outlet isn't in a valid Angular template. Once you move <router-outlet> to app.component.html, this should resolve itself.
Double-check your routing module too: make sure your routes are defined correctly, and that you've imported the Feature A/B components properly. For example:
// app-routing.module.ts const routes: Routes = [ { path: 'featureA', component: FeatureAComponent }, { path: 'featureB', component: FeatureBComponent }, { path: '', redirectTo: '/featureA', pathMatch: 'full' }, // Default route ];
4. Is Hash Routing the Only Alternative?
Nope! The server rewrite approach is the recommended solution for clean URLs. Hash routing (www.domain.com/root/#featureA) works because the browser treats everything after the # as a client-side fragment, so the server only ever serves /root/index.html. But it's a fallback—clean URLs are better for UX and SEO.
Final Checklist to Fix Everything
- Rebuild your app with the correct base-href (don't forget the trailing slash):
npm run build -- --base-href /root/ - Move
<router-outlet>fromindex.htmltoapp.component.html(make sure it's placed where you want your feature components to render). - Configure your web server with the rewrite rules above to forward all
/root/requests to/root/index.html. - Verify your routing module has correct path-to-component mappings and a proper default route.
Once you do all this, direct visits to /root/featureB should load the correct component, and your app will behave as expected.
内容的提问来源于stack exchange,提问作者t.j.

