Skip to content

add optional "input" and "output" paths to "index" in angular-cli.json #7309

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
nekkon opened this issue Aug 9, 2017 · 38 comments
Closed

add optional "input" and "output" paths to "index" in angular-cli.json #7309

nekkon opened this issue Aug 9, 2017 · 38 comments

Comments

@nekkon
Copy link

nekkon commented Aug 9, 2017

It would be great if "input" and "output" optional paths were added to "index" in angular-cli.json. There are scenarios that can not be covered with current implementation. (even using deployUrl)

With the current implementation the path of index.html after build is forced to be the same with the location during development. This is not always the case. An example is when folder structure in development is different than production. In such case the output path of the index.html can not be the same.

For example in angular-cli.json:

{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"project": {
"name": "orco-frontend"
},
"apps": [
{
"name": "dm",
"root": "src",
"outDir": "dist/dm",
"assets": [
{ "glob": "/*", "input": "dm/assets/", "output": "./assets/" },
{ "glob": "favicon.ico", "input": "dm/", "output": "./" },
{ "glob": "
/*", "input": "shared/assets", "output": "./assets/" }
],
"index": "dm/index.html",
"deployUrl": "./",

In this example there is an app (dm) in src folder. The index.html file after build ends up in dist/dm/dm/index.html while it needs to be in dist/dm/index.html.

Even if you change outDir to the folder: "new location", index.html will still be built to the folder "new location"/dm/index.html. All the rest of the necessary files of the build will end up in the folder "new location" which is not the proper file/folder structure. This should not be forced to happen.

@intellix
Copy link
Contributor

intellix commented Aug 9, 2017

I'm thinking that this is more of a bug really. I think the index.html should always be in the root directory and not copied across with it's directory structure, since JS is forced into the root as well.

Other HTML files can be copied across as assets and would maintain their folder structure depending on where they are

@out-of-memory
Copy link

I have similar requirement, but with slight difference... I am not able to find any solutions and neither I was able to find any tickets around for that. If there is one then I am really sorry but please redirect me.
My requirement is simple...
I have multiple index.html files...
like index.html, index.stage.html, index.prod.html
now at the time of build I want "ng build" to pick index.stage.html and convert it to index.html,
if --env=stage. Is this possible.

@nekkon
Copy link
Author

nekkon commented Aug 9, 2017

@out-of-memory Maybe this can help you? Also, you don't explain why you would like something like that to happen. I think your request is different than this issue.

@intellix
Copy link
Contributor

intellix commented Aug 9, 2017

Found the culprit: https://github.com/angular/angular-cli/blob/master/packages/@angular/cli/models/webpack-configs/browser.ts#L67

If that's hardcoded to index.html then we get the solution that we're after:

filename: path.resolve(buildOptions.outputPath, 'index.html'),

Any thoughts about having a second property for outputIndex or flattening that second property @filipesilva before someone makes a PR?

Desired functionality.

To have the index.html reside in the same folder as scripts, which cannot be output anywhere else currently

The following would work I think:

appConfig.index.substr(appConfig.index.lastIndexOf('/') + 1);

@grizzm0
Copy link
Contributor

grizzm0 commented Aug 9, 2017

The reason you end up with dist/dm/dm/index.html is because you have dm in both index and outDir. Change index to index.html, root to src/dm and outDir to dist/dm.

See #7124 where I posted a more in depth response about this.

@nekkon
Copy link
Author

nekkon commented Aug 9, 2017

@grizzm0 Yes "dm" is both in index and outDir. I was forced to cause of an issue which is not solved yet. Also, could you confirm if the solution you suggest can be built with AOT and works when an app loads a lazy loaded module from "shared code"?

It would be great if "input" and "output" optional paths were added to "index". It does not harm anyone and index.html is not forced to have the same path (from root folder) in production and development.

@intellix
Copy link
Contributor

intellix commented Aug 9, 2017

I feel like the index.html should always be at root, so it's on the same level as the scripts it needs to load which are always at root.

I've almost got the root property working entirely. Got a few kinks to correct but it's mostly there. Will share what I have when I manage it 100% :)

@nekkon
Copy link
Author

nekkon commented Aug 9, 2017

@intellix In case you manage it 100%, also test your solution on the example I have . If it works after you build the app with AOT, --prod flag, (npm run app1:build) then everything should be fine.

@nekkon
Copy link
Author

nekkon commented Aug 9, 2017

@grizzm0 I have an example here . You can edit the tsconfig based on your solution and try running ng build --app app1 --prod to see if it can be built.

@intellix
Copy link
Contributor

intellix commented Aug 9, 2017

I've added an example using a different root property amongst a few other things like SCSS Vars and Image replacement: https://github.com/intellix/angular-cli-library

Thanks to @nekkon and @grizzm0 it serves, builds and can be tested. IDE is reporting that core/* imports don't exist so it's not perfect. I'll see about perfecting it

@nekkon
Copy link
Author

nekkon commented Aug 10, 2017

@intellix Your example does not work with AOT. Also you do not lazy load the shared module which is a common scenario. Add --prod flag to your build commands and see what I am talking about.

@nekkon
Copy link
Author

nekkon commented Aug 10, 2017

@grizzm0 @intellix I have created a new branch with an example of a lazy loaded module of the shared code. It follows your suggestions/solution. ng serve works, ng build works but ng build --prod does not. There are open issues with angular-cli that do not allow your suggestion/solution/examples to work. That is why I created the repo angular-cli-library. In that repo AOT works with/without lazy loaded modules, which is something important if you want your app to be built for production. The only problem is that index.html ends up in "app-name/index.html" instead of the outDir folder. That is why I created this issue. Until this is solved, if you copy/transfer index.html to the parent folder everything works properly. This is why I ask for the functionality @marcincichocki requested #7124.

@filipesilva
Copy link
Contributor

index keeping the relative path inside outDir as it does inside root is not a bug, but intended. I don't have a PR on hand but this was requested some time ago and is now part of the feature set.

It's part of an overall philosophy we follow that relative paths should always be maintained.

@nekkon
Copy link
Author

nekkon commented Aug 10, 2017

@filipesilva The functionality I request exists "input is relative to the project root (src/ default), while output is relative to outDir (dist default)." Relative paths are not maintained with assets, if you want to. I agree with this and find it very helpful. I ask for the same to be applied to index.

@filipesilva
Copy link
Contributor

It does exist for assets, yes. Mostly to support copying stuff from node_modules though, which is necessarily outside the source directory.

Is there something that prevents you from moving src/dm/dm/index.html one directory up though? That would give you the output you're looking for.

@grizzm0
Copy link
Contributor

grizzm0 commented Aug 10, 2017

@filipesilva This whole issue is about multiple apps more or less. I've suggested to change the root to src/dm and keep index as index.html.

This is related to what you and @intellix discussed on slack earlier today with the AOT issue.

@nekkon
Copy link
Author

nekkon commented Aug 11, 2017

@filipesilva Yes I can not move one directory up. I can not use @grizzm0 's suggestion as AOT does not work with modules that are lazily loaded outside the project. I do understand that under normal conditions @grizzm0 's suggestion is the way to go, but there are open issues (ex #5986 ) that prevent his solution to work 100% at the moment. That's why I asked to add the optional paths (input/output).

@grizzm0 You have been insisting the last two days to use your solution. You also say that a shared library of components can be used with it. Have you tested the example which @intellix made based on your solution? I have repeatedly asked you to, so you would see that with what you suggest AOT does not work.

By setting tsconfig the way I do, although it seems wrong, everything works fine for me (AOT+lazy loading of modules from a shared folder of modules/components). When all open issues are solved (something that will take time) I will change tsconfig to what @grizzm0 suggests.

@intellix
Copy link
Contributor

intellix commented Aug 11, 2017

The PR I've created flattens the output location of index.html so that it always exists at the root of the application alongside the JS bundles. I still think this is correct as you can't request JS files like: ../vendor.js unless you do some Web Server hackery.

Basically an index.html in another folder upwards will never work out of the box without #7314

One thing that does work for loading files from a Core location, is moving the SRC to a separate repository without a build-step and requiring them in via node_modules

@nekkon
Copy link
Author

nekkon commented Aug 11, 2017

@intellix "you can't request JS files like: ../vendor.js" -> deployUrl can be used to do that. Just telling you so you know. I did it by setting "deployUrl": "./". That's why index.html works properly in the root folder in "dist/dm" although it is built in "dist/dm/dm". If I had set it to "../" it would had done what you say it can't.

@intellix Your PR does solve the problem we have, but it could create problems/issues to users that want it to work otherwise. I would support you if that might not happen. That's why I asked for the optional paths for index as that wouldn't cause any problem/issues to anyone, but give more options to developers.

I believe things should be flexible for each developer to have enough options that cover all possible scenarios. If you make things too strict, absolute and you miss usage scenarios, you disappoint them and make them feel that this was built only for a few people/companies and not for everyone. (as they can't change how angular-cli works by default.)

@filipesilva
Copy link
Contributor

If #5986 is what prevents @grizzm0's approach from working, it should be fixed instead as it's supposed to work.

Bear in mind that sharing code directly between apps without a library is not an officially supported usecase... It might or might not work with paths.

@intellix
Copy link
Contributor

intellix commented Aug 21, 2017

@nekkon I've changed my example repository to look closer to yours, as that's working better for us at the moment as well. One thing that's not supported there though still is CoreModule lazy loading it's own things. I think this is probably related to #5986 where another "package" can't lazy-load it's own things. It works to serve and without AOT though.

ERROR in ./src/$$_gendir lazy
Module not found: Error: Can't resolve '/Sites/github/intellix/angular-cli-library/src/$$_gendir/core/modules/lazy/lazy.module.ngfactory.ts' in '/Sites/github/intellix/angular-cli-library/src/$$_gendir'
resolve '/Sites/github/intellix/angular-cli-library/src/$$_gendir/core/modules/lazy/lazy.module.ngfactory.ts' in '/Sites/github/intellix/angular-cli-library/src/$$_gendir'
  using description file: /Sites/github/intellix/angular-cli-library/package.json (relative path: ./src/$$_gendir)
    Field 'browser' doesn't contain a valid alias configuration
  after using description file: /Sites/github/intellix/angular-cli-library/package.json (relative path: ./src/$$_gendir)
    using description file: /Sites/github/intellix/angular-cli-library/package.json (relative path: ./src/$$_gendir/core/modules/lazy/lazy.module.ngfactory.ts)
      no extension
        Field 'browser' doesn't contain a valid alias configuration
        /Sites/github/intellix/angular-cli-library/src/$$_gendir/core/modules/lazy/lazy.module.ngfactory.ts doesn't exist
      .ts
        Field 'browser' doesn't contain a valid alias configuration
        /Sites/github/intellix/angular-cli-library/src/$$_gendir/core/modules/lazy/lazy.module.ngfactory.ts.tsdoesn't exist
      .js
        Field 'browser' doesn't contain a valid alias configuration
        /Sites/github/intellix/angular-cli-library/src/$$_gendir/core/modules/lazy/lazy.module.ngfactory.ts.jsdoesn't exist
      as directory
        /Sites/github/intellix/angular-cli-library/src/$$_gendir/core/modules/lazy/lazy.module.ngfactory.ts doesn't exist
[/Sites/github/intellix/angular-cli-library/src/$$_gendir/core/modules/lazy/lazy.module.ngfactory.ts]
[/Sites/github/intellix/angular-cli-library/src/$$_gendir/core/modules/lazy/lazy.module.ngfactory.ts.ts]
[/Sites/github/intellix/angular-cli-library/src/$$_gendir/core/modules/lazy/lazy.module.ngfactory.ts.js]
[/Sites/github/intellix/angular-cli-library/src/$$_gendir/core/modules/lazy/lazy.module.ngfactory.ts]
 @ ./src/$$_gendir lazy
 @ ./node_modules/@angular/core/@angular/core.es5.js
 @ ./src/red/main.ts
 @ multi ./src/red/main.ts

On the note of having fake packages/libraries though. We tried the monorepos stuff but I believe we had the same issues to do with AOT from another place. I tried this: sparkles-dev/a-glimpse-at-yarn-workspaces#2

@nekkon
Copy link
Author

nekkon commented Aug 21, 2017

@intellix In my library repo CoreModule has no issues in being lazy loaded, as with any other module being lazy loaded from inside the "src" directory/subdirectory. From the error message above I think your problem is related to #7341. I have solved this issue (workaround) in my library. As I have previously said, my library repo is a result of many workarounds and except of this issue everything else works fine atm. It saves you time if you use something that works than continuously trying to solve problems/issues.

@intellix
Copy link
Contributor

intellix commented Aug 21, 2017

I don't believe your repository has solved the same thing. Yours is doing:

'app1' lazy loads a component from 'app1' that depends on something from 'shared'

The problem I'm having is that I already have a huge application and just need to decorate it with different SCSS variables and Images depending on the app served. This means I have something like:

'shared' depends on a lazy-module from 'shared'. 'app1' imports 'SharedModule'.

It's essentially something outside of src not being able to lazy-load it's own stuff.

@nekkon
Copy link
Author

nekkon commented Aug 22, 2017

@intellix 'shared' depends on a lazy-module from 'shared'. 'app1' imports 'SharedModule'

You can also do that and it works. The only restriction is for all modules to be in the src folder (either in shared or in each app). If you want the files to be outside the src folder there is an issue open which does not allow you to.

@Lakston
Copy link
Contributor

Lakston commented Nov 22, 2017

Has something been done to manage this in the end ?

I have a multi app setup and my index output for (for example) "app2" is build-app2/app/modules/app2/index.html instead of build-app2/index.html because the path of my index in my dev folder is copied to the build folder as per the angular-cli.json path :

      "name": "app2",
      "root": "src",
      "outDir": "dist-app2",
      "index": "app/modules/app2/index.html",

Edit : In case someone is having the same problem I'll post how I solved this for now :

  • I changed my root folder for "app2" so that the index would be directly in the root
  • I made all the other paths (polyfills, assets, ts.config etc...) needed relative to the root folder path

My angular-cli.json file now looks like this for "app2" :

  "name": "app2",
  "root": "src/app/modules/app2", <-- new root
  "outDir": "dist-app2",
  "assets": ["../../../assets/i18n"], <-- relative path to root
  "index": "index.html", <-- index.html is now directly in root
  "main": "main-export.ts", <-- so is my main file // optional though
  "polyfills": "../../../polyfills.ts", <-- relative path to root
  "tsconfig": "../../../tsconfig.app.json", <-- relative path to root
  "testTsconfig": "../../../tsconfig.spec.json", <-- relative path to root
  "styles": ["../../../scss/modules/export.scss"], <-- relative path to root
  "scripts": [],
  "environmentSource": "../../environments/environment.ts", <-- relative path to root

My output folder structure is now normal :

dist-app2/index.html

@demilsson
Copy link

demilsson commented Dec 7, 2017

@Lakston That's a nice idea, but the opposite problem will then occur with the assets.

Say the folder structure is like this:

[project]
    [src]
        main-app2.ts
        polyfills.ts
        (etc)
        [apps]
            [app2]
                [styles]
                    styles.scss
                app.module.ts
                index.html
        [assets]
            image.png

And that the app config is

"name": "app2",
"root": "src/apps/app2",
"outDir": "dist/app2",
"assets": ["../../assets"], <-- relative path to root
"index": "index.html",
"main": "../../main-app2.ts",
"polyfills": "../../polyfills.ts",
"tsconfig": "../../tsconfig.app.json",
"testTsconfig": "../../tsconfig.spec.json",
"styles": ["styles/styles.scss"],
"scripts": [],
"environmentSource": "../../environments/environment.ts",

The output of the build will then be:

[project]
    [dist]
        [app2]
            index.html
            (etc)
    [assets] <-- asset folder is added to the project root folder
        image.png

Since the assets folder was accessed using a relative path, it is also seems to be copied using the same relative path, in this case two levels above the intended dist output folder.

We definitely need a flexible way to deal with this.

@Lakston
Copy link
Contributor

Lakston commented Dec 8, 2017

I have since found a better way to handle my 4 apps, it required me to duplicate some files and folders (like my assets) but I am happy of how things are going now.

I've read some commits and found out about the appRoot option (I think it was introduced in this commit) so now my angular-cli.json files looks like this :

 {
      "name": "app",
      "root": "src/modules/app",
      "appRoot": ".", <= introduced the appRoot option
      "outDir": "dist-app",
      "assets": ["assets"],
      "index": "index.html",
      "main": "main-export.ts",
      ... many params,
      "environmentSource": "../../environments/environment.ts",
      "environments": {
        "dev": "../../environments/environment.ts",
        "prod": "../../environments/environment.prod.ts"
      }
    },
    {
      "name": "app2",
      "root": "src/modules/"",
      "appRoot": ".", <= introduced the appRoot option
      "outDir": "dist-"",
      "assets": ["assets"],
      "index": "index.html",
      "main": "main-app2.ts"
      }
    },

I have duplicated quite a few files but now the benefit of this is that I can generate things via the CLI, the proper paths will be respected and the right app module will get updated like so :
ng g c components/new-component --app app2

It will create the components in the right place and update app2.module.ts

I am in the process of making typescript aliases so I can avoid some ../../../ paths for shared files and I'm sure I am not even touching on the potential of appRoot, hopefully some doc will come out or someone smarter than me will show us the 'proper way' !

But for now, this works !

@nekkon
Copy link
Author

nekkon commented Dec 8, 2017

@Lakston Hi, can you explain how appRoot is different than setting the root folder of the app? As I see from your example both apps have "." as the value. How does setting "." change things? Maybe this could solve the "index" issue. Thanks in advance and for pointing out this new option. Maybe @vsavkin can explain it to us or add it to the docs?

@Lakston
Copy link
Contributor

Lakston commented Dec 8, 2017

I am confused by this too, from what I can gather it allows me to use the ng generate which didn't work before I put it in, it still does not fix the index issue that's why I specified that I had to duplicate a lot of files, we definitely need some doc about this and examples !

@jpduckwo
Copy link

jpduckwo commented Mar 5, 2018

I would definitely like to do something like this in the app definition with index.

index: { "input": "index.other.html", "output": "./index.html" },

I have a second version of an app that requires a different index.html and at the moment the output keeps the alternative index name...
I have worked around it with an npm script to rename it after building - not ideal for sure.

@ahmadhsalim
Copy link

@jpduckwo This is what I want too. I'm using Angular inside a PHP Laravel application and the front page will be served from the blade template welcome.blade.php so I want angular-cli to copy the index file to resources/assets/views/welcome.blade.php but all other files should be in the default public/dist folder.
For now what I'm doing is to copy the contents of the public/dist/index.html file into the welcome.blade.php file. Index file usually doesn't change so it works most of the time.

@marticrespi
Copy link

Any news about it? I have multiple apps and I can't move to root dist folder for each app, because it is generated with relative paths inside index.html linking styles, main bundle..

@intellix
Copy link
Contributor

intellix commented Mar 13, 2018

@marticrespi since encountering this, NX CLI came out which was made for multiple apps. I've personally moved to there and would recommend others to as it has some good tooling for multiple apps: https://nrwl.io/nx

@listepo-alterpost
Copy link

@intellix we also using nrwl, but "index": "../../../libs/common/index.html",still not working for aot.

@bluebaroncanada
Copy link

bluebaroncanada commented Apr 15, 2019

Still a "No."; eh?

@clydin
Copy link
Member

clydin commented Sep 19, 2019

This is now supported in Angular CLI 8.2.0 or greater.

@clydin clydin closed this as completed Sep 19, 2019
@bluebaroncanada
Copy link

Awesome.

@angular-automatic-lock-bot
Copy link

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.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Oct 21, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.