Angular-cli: ng build duplicates the index file

Created on 4 May 2017  Â·  14Comments  Â·  Source: angular/angular-cli

Bug Report or Feature Request (mark with an x)

- [x] bug report -> please search issues before submitting
- [ ] feature request

Versions.

@angular/cli: 1.0.2
node: 7.7.4
os: win32 x64
@angular/animations: 4.1.0
@angular/cli: 1.0.2
@angular/common: 4.1.0
@angular/compiler: 4.1.0
@angular/core: 4.1.0
@angular/forms: 4.1.0
@angular/http: 4.1.0
@angular/material: 2.0.0-beta.3
@angular/platform-browser: 4.1.0
@angular/platform-browser-dynamic: 4.1.0
@angular/router: 4.1.0
@angular/compiler-cli: 4.1.0

(this issue was also reproduced on @angular/cli 1.0.1)

Repro steps.


Have a file structure like this :

└───src
    ├───backend
    │   ├───Views
    │   │   └───Home
    │   └───wwwroot
    │       ├───assets
    │       │   └───css
    │       └───dist
    └───frontend
        ├───e2e
        ├───node_modules
        └───src
            ├───app
            └───environments

Where the angular application is located in the "frontend" folder, and your index file is src/backend/Views/Home/Index.cshtml
Specify "index": "../../backend/Views/Home/Index.cshtml" in your .angular-cli.json file.
Full config file :

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "project": {
    "name": "xxx"
  },
  "apps": [
    {
      "root": "src",
      "outDir": "../backend/wwwroot/dist",
      "deployUrl": "/dist/",
      "assets": [
        "assets",
        "favicon.ico"
      ],
      "index": "../../backend/Views/Home/Index.cshtml",
      "main": "main.ts",
      "polyfills": "polyfills.ts",
      "test": "test.ts",
      "tsconfig": "tsconfig.app.json",
      "testTsconfig": "tsconfig.spec.json",
      "prefix": "app",
      "styles": [
        "../../backend/wwwroot/assets/css/main.css"
      ],
      "scripts": [],
      "environmentSource": "environments/environment.ts",
      "environments": {
        "dev": "environments/environment.ts",
        "prod": "environments/environment.prod.ts"
      }
    }
  ],
  "e2e": {
    "protractor": {
      "config": "./protractor.conf.js"
    }
  },
  "lint": [
    {
      "project": "src/tsconfig.app.json"
    },
    {
      "project": "src/tsconfig.spec.json"
    },
    {
      "project": "e2e/tsconfig.e2e.json"
    }
  ],
  "test": {
    "karma": {
      "config": "./karma.conf.js"
    }
  },
  "defaults": {
    "styleExt": "css",
    "component": {}
  },
  "packageManager": "yarn"
}

Now run ng build. The console output is absolutely normal, but instead of injecting the <script> tags in the index file, a new one has been created in src/backend/backend/Views/Home/Index.cshtml instead of updating src/backend/Views/Home/Index.cshtml.

Note :

  • Trying another path for index configuration does not work, angular cli does not find the file.
  • Angular cli does find the index file as the content of the generated index file is based on my original file. But the path used to read the index file seems to be somehow different than the path used to write the file in my case.

My new file structure after running ng build :

└───src
    ├───backend
    │   ├───backend
    │   │   └───Views
    │   │       └───Home
    │   ├───Views
    │   │   └───Home
    │   └───wwwroot
    │       ├───assets
    │       │   └───css
    │       └───dist
    └───frontend
        ├───e2e
        ├───node_modules
        └───src
            ├───app
            └───environments
easy (hours) help wanted 2 (required) inconvenient

Most helpful comment

I finally understood how this "bug" works :
As mentioned in the docs, the index config property expects a file name and not a path, and has unexpected behaviors if a path is given.
This unexpected behavior is the following for me : when angular-cli reads the index file, the path is relative to root ('src', by default). But when it comes to rewrite the file with injected <script> tags, the path is relative to outDir (explanation below).

I think it is important to support more complex path for index & outDir in order to facilitate integration of angular in other frameworks such as asp.net core, that's why I think this needs a fix, or at least a warning in the docs

Why I came to think that index file rewrite is relative to outDir :
I changed my config with "outDir": "../backend/wwwroot/dist/foo", and the file structure after the ng build became

└───src
    ├───backend
    │   ├───Views
    │   │   └───Home
    │   └───wwwroot
    │       ├───assets
    │       │   └───css
    │       ├───backend
    │       │   └───Views
    │       │       └───Home
    │       └───dist
    │           └───foo
    └───frontend
        ├───e2e
        ├───node_modules
        └───src
            ├───app
            └───environments

So I'm pretty sure my index path ../../backend/Views/Home/Index.cshtml has been taken from the new dist/foo folder for rewriting.

All 14 comments

Angular CLI uses HtmlWebpackPlugin for injection. I believe it only supports normal html not .cshtml (ASP.NET)

I just tried with a .html file, and obtained the same result

I second that .cshtml in general should be fine. I'm having a similar structure with no issues ("index": "index.cshtml").

With the following differences:

  • I didn't change outDir
  • I have index.cshtml inside src (and have it as linked item in Visual Studio).

I don't remember why I used index this way, but I think the CLI has issues with the index being outside of the root directory (src by default).

I finally understood how this "bug" works :
As mentioned in the docs, the index config property expects a file name and not a path, and has unexpected behaviors if a path is given.
This unexpected behavior is the following for me : when angular-cli reads the index file, the path is relative to root ('src', by default). But when it comes to rewrite the file with injected <script> tags, the path is relative to outDir (explanation below).

I think it is important to support more complex path for index & outDir in order to facilitate integration of angular in other frameworks such as asp.net core, that's why I think this needs a fix, or at least a warning in the docs

Why I came to think that index file rewrite is relative to outDir :
I changed my config with "outDir": "../backend/wwwroot/dist/foo", and the file structure after the ng build became

└───src
    ├───backend
    │   ├───Views
    │   │   └───Home
    │   └───wwwroot
    │       ├───assets
    │       │   └───css
    │       ├───backend
    │       │   └───Views
    │       │       └───Home
    │       └───dist
    │           └───foo
    └───frontend
        ├───e2e
        ├───node_modules
        └───src
            ├───app
            └───environments

So I'm pretty sure my index path ../../backend/Views/Home/Index.cshtml has been taken from the new dist/foo folder for rewriting.

Would you be interested in working on a fix for this bug?

Sure I can give it a try, can I have an interlocutor to have some help on how to contribute to the repo ? @filipesilva @sumitarora

https://github.com/angular/angular-cli#development-hints-for-working-on-angular-cli should help you setup your local CLI install so you can test your fix.

This is where the path is used: https://github.com/angular/angular-cli/blob/master/packages/@angular/cli/models/webpack-configs/common.ts#L78

Here it is merged with the value on the cli config file: https://github.com/angular/angular-cli/blob/master/packages/@angular/cli/tasks/build.ts#L23

After investigation, I changed the configuration of the HtmlWebpackPlugin to make the index file path relative to root (it was, indeed, relative to outDir).
Here is the commit on my fork : https://github.com/bviale/angular-cli/commit/f4ca3937601325717b49f5d89bce4595bb910e03 which solved my "bug".

However, I broke ng serve and ng build with initial configuration because it was based on the fact that the index file is copied in the dist folder.

I think it is more a feature to add to support cases where we do not want to copy the index file.

How do you think this should be implemented ?

Not copying the index file isn't really a case we support to be honest. The index file needs to be copied over to the dist directory, and the necessary scripts are added. We don't support create builds 'in folder', only on a separate folder so that there is a deployable artifact.

So this now sounds to me more like an issue of configuration, where you need to find a output directory that makes sense within your project structure.

Ok, I know understand the philosophy of the index file, which is more like a template used to inject <script> in a copy of it in the dist folder.
The idea is that the index file chosen in the config will never be modified directly; this is what I was trying to accomplish.
This relies on HtmlWebpackPlugin template (input) and filename (output) configuration, where we force template to depend on our root configuration node and filename to depend on outDir.
Maybe we should clarify this point in the documentation.
Concerning the "bug", it is _as designed_.

Thanks for getting back on this @bviale, I'll close it then 👍

I have the problem that my <script> tags are not getting replaced. Instead, it always adds a new tag to index.html. Any idea why this behavior? The only thing I did different was to change the path of the index.html

.angular-cli.json:

"apps": [
  {
    "root": "src",
    "outDir": "dist",
    "assets": [
      "assets",
      "favicon.ico"
    ],
    "index": "../../index.html"

@dgroh we don't replace anything in index.html besides the base href value.

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

_This action has been performed automatically by a bot._

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rajjejosefsson picture rajjejosefsson  Â·  3Comments

jmurphzyo picture jmurphzyo  Â·  3Comments

NCC1701M picture NCC1701M  Â·  3Comments

donaldallen picture donaldallen  Â·  3Comments

ericel picture ericel  Â·  3Comments