Running Angular2 In Subdirectory

守給你的承諾、 提交于 2019-12-18 12:15:40

问题


I have an app which runs fine under localhost.

I tried to put it out on an IIS server today as a child application. So the new path would be localhost/SubDir.

System.js pukes everywhere trying to load modules now. I set the basePath and played with the path/map config variables for a few hours but couldn't land on the magic settings.

Does anyone have ideas what I'd want to tweak, or anything that would help with debugging?

Chrome Console

Chrome Network

Index HTML

<html>
<head>
    <script src="~/node_modules/es6-shim/es6-shim.js"></script>
    <script src="~/node_modules/systemjs/dist/system.src.js"></script>
    <script src="~/node_modules/angular2/bundles/angular2.dev.js"></script>
    <script src="~/node_modules/angular2/bundles/http.dev.js"></script>
    <script src="~/node_modules/angular2/bundles/router.dev.js"></script>

    <link href="~/node_modules/bootstrap/dist/css/bootstrap.css" rel="stylesheet" />

    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
      <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->

    <link href="~/assets/css/site.css" rel="stylesheet" />

    <script>
      System.config({
          packages: { 'app': { defaultExtension: 'js' } },
          baseURL: '/MedicheckAngular/',
          paths: {
              //'angular2/*': 'node_modules/angular2/ts/*.js'
          }
      });

      System.import('app/app');
    </script>

</head>
<body>
    <my-app>loading...</my-app>
</body>
</html>

And the App entry point

import {HTTP_PROVIDERS} from 'angular2/http';
import {bootstrap, bind, provide} from 'angular2/angular2';
import {RouteConfig, RouteParams, ROUTER_DIRECTIVES, APP_BASE_HREF, ROUTER_BINDINGS, LocationStrategy, PathLocationStrategy, HashLocationStrategy} from 'angular2/router';

import {AppLayout} from './components/app-layout/app-layout';


bootstrap(AppLayout, [
    ROUTER_BINDINGS,
    HTTP_PROVIDERS,
    provide(APP_BASE_HREF, {useValue:'/'}),
    provide(LocationStrategy, { useClass: HashLocationStrategy })
]);

App Folder Structure


回答1:


To host in a sub directory with apache, you can just do this:

Build command similar to this: ng build --base-href /myapp/

.htaccess file would look like this

RewriteEngine On
RewriteBase /myapp/
Options +FollowSymLinks

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.html [L,QSA]



回答2:


When you're deploying to a non-root path within a domain, you'll need to manually update the following:

<base href="/">

to:

<base href="/MedicheckAngular/">

in your dist/index.html, or make changes as follows:

  1. Change baseUrl: '/MedicheckAngular/' in webpack.common.js.
  2. Add /MedicheckAngular/ to the links in index.html.



回答3:


try to remove the baseURL from the config of systemjs and add the <base href="MedicheckAngular/" /> to your head part in the HTML DOM.

I had my Angular2 App in the subfolders "modules/angular" from the root. `

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Hallo</title>
    <base href="modules/angular/">
</head>
<body>
   <myapp>loading...</myapp>

   <script src="/modules/angular/node_modules/es6-shim/es6-shim.min.js"></script>
   <script src="/modules/angular/node_modules/systemjs/dist/system-polyfills.js"></script>
   <script src="/modules/angular/node_modules/angular2/es6/dev/src/testing/shims_for_IE.js"></script>
   <script src="/modules/angular/node_modules/angular2/bundles/angular2-polyfills.js">   </script>
   <script src="/modules/angular/node_modules/systemjs/dist/system.src.js"></script>
   <script src="/modules/angular/node_modules/rxjs/bundles/Rx.js"></script>
   <script src="/modules/angular/node_modules/angular2/bundles/angular2.dev.js"></script>

    <script>
    System.config({
        packages: {
            "apps": {
                format: 'register',
                defaultExtension: 'js'
            }
        }
    });
    System.import('apps/main').then(null, console.error.bind(console));
    </script>
</body>
</html>`



回答4:


I struggled for a while to do something similar. I have a wordpress running on an apache server. For SEO reason we wanted the angular app to be hosted on a sub-folder, in the way phpmyadmin is hosted.

  1. What I did is to create a subfolder in /apps/my-app-hosting-folder
  2. Create an alias to this folder : /my-alias => /apps/my-app-hosting-folder
  3. Change the base ref from base href="/" to base href=""

This worked.

The other things I tried didn't give me satisfaction for the following reasons :

  • set base ref to the alias : I would have needed to manually fix links through the app and with some weird configuration I ended up with something like www.exemple.com/my-alias/my-alias/index; something went wrong between the alias and the base ref.
  • leaving "/" broked some inner link by adding some weird "/" so I had broken url like : www.exemple.com/my-alias/node//blabla; I think it tries to work with the root folder of the server.

Hope it will help the futur readers.




回答5:


I put a ~ on the "base href"

<!-- Angular2 Code -->
<base href="~/">
<link rel="stylesheet" href="styles.css">
<!-- Polyfill(s) for older browsers -->
<script src="~/node_modules/core-js/client/shim.min.js"></script>
<script src="~/node_modules/zone.js/dist/zone.js"></script>
<script src="~/node_modules/reflect-metadata/Reflect.js"></script>
<script src="~/node_modules/systemjs/dist/system.src.js"></script>
<script src="~/systemjs.config.js"></script>
<script>
  System.import('app').catch(function(err){ console.error(err); });
</script>
<!-- Angular2 Code -->



回答6:


Here's what worked for us:

  1. Make the base ref point to the subdirectory containing the angular project. This will ensure that all the node_module dependencies are found, etc.

  2. Configure the PathLocationStrategy with a different APP_BASE_HREF so that html5 mode still works for the actual angular app.

    bootstrap(AppComponent, [..... bind(APP_BASE_HREF).toValue("/yardmap/planning")

ref: https://angular.io/docs/ts/latest/api/common/index/APP_BASE_HREF-let.html

ref: https://angular.io/docs/ts/latest/guide/router.html




回答7:


If you don't know the subdirectory upfront, you can use a dot as path at /src/index.html file like this:

<base href=".">

Then just build with command: ng build --prod. Then get the output from inside of /dist directory as usual.

Now your app can be placed in any web dir or even works from the filesystem (if no restricted API is used).




回答8:


I think that you've miss a subfolder.

What you've put in your 'index.html' file, means that files to load are located in your home directory.

/home/<your_directory>/[...] <- You try to load files from there.

I think that your server structure is more like that.

/home/<your_directory>/***<app_folder>***/[...] <- I think your files are located here.

If you have a console access to your server , try to locate your application folder, with pwd for example and then replace in your 'index.html' '~/' in your src tags with the returned path and it will work as expected.




回答9:


The full configuration for running Angular app in subdirectory.

Assuming "ng-app/" as the alias path. For example http://www.example.com/ng-app/

Apache config

Alias /ng-app  /<Directory path of index.html>/
Alias /assets /<Directory path of index.html>/assets/
<Directory /<Directory path of index.html>>
    DirectoryIndex index.html

    Require all granted
    RewriteEngine on
    RewriteCond %{REQUEST_FILENAME} -s [OR]
    RewriteCond %{REQUEST_FILENAME} -l [OR]
    RewriteCond %{REQUEST_FILENAME} -d
    RewriteRule ^.*$ - [NC,L]
    RewriteRule ^(.*) /index.html [NC,L]
</Directory>

Set baseUrl in index.html

<base href="/ng-app/">

Suppose the angular-app doesn't work on reload, Add the LocationStrategy provider in app.module.ts

import {LocationStrategy, HashLocationStrategy} from '@angular/common';
@NgModule({
    providers: [
        {provide: LocationStrategy, useClass: HashLocationStrategy}
    ]
});



回答10:


Not need to do more , just change one line after the build project in index.html

<base href="/">

to

<base href="/sub directory_name/">

If you want to access route in sub-directory more detail here https://angular.io/guide/deployment#production-servers



来源:https://stackoverflow.com/questions/34010970/running-angular2-in-subdirectory

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!