24

I'd like to to know if it is possible to hook into angular-cli's build/watch command:

ng build /w

which generates files and drops them in the project's /dist folder

I just want after the build completes to copy the dist folder to another directory, is it possible?

jenson-button-event
  • 18,101
  • 11
  • 89
  • 155

5 Answers5

15

I managed to achieve what I wanted with parallel tasks, copyfiles and npm watch:

npm dev dependencies:

"npm-watch": "^0.1.8",
"parallelshell": "^2.0.0",
"copyfiles": "^1.2.0",

package.json snippet:

"watch": {
    "copy-files": "dist/*.js"
  },
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "lint": "tslint \"src/**/*.ts\" --project src/tsconfig.json --type-check && tslint \"e2e/**/*.ts\" --project e2e/tsconfig.json --type-check",
    "test": "ng test",
    "pree2e": "webdriver-manager update --standalone false --gecko false",
    "e2e": "protractor",
    "watch": "npm-watch",
    "copy-files": "copyfiles src/** dist/** ../angular",
    "ng-build": "ng build -w",
    "build": "parallelshell \"ng build\" \"npm run watch\" "
  },

Then

npm run build

FWIW the watch config is saying, if anything in dist/*.js changes, run the "copy-files" npm script...

pjpscriv
  • 866
  • 11
  • 20
jenson-button-event
  • 18,101
  • 11
  • 89
  • 155
  • Keep getting `directory not empty, rmdir '[...]\dist'` error from ng build when copyfiles runs close to build start or before build has completed. Only sure workaround I found was running 2 command line windows: one with `ng build --watch`, then once build has finished, another with `npm run watch`. This, instead of relying on parallelshell to do the same thing. Is there a single-command solution? Tried to add `timeout 20 &` before `npm run watch` in "build" package.json script, but that won't work with parallelshell (using Windows) – Balage Feb 21 '19 at 20:19
  • 1
    There are some other npm packages `npm-run-all` `concurrently` available to run tasks in parallel. – Rajez Mar 29 '19 at 10:10
5

One way is to run npm run build and have a postbuild script that copies the content of index.html from your dist folder to your html/cshtml file in your desired folder and changes the script and link tag's paths in your newly copied file to point to the dist folder after the build it complete. Now run ng build --watch and start development. I'm using angular 6 and angular-cli with .Net MVC 4.5 and I use ~\Views\Home as my desired destination folder.

To have the watch mode running in my project I Run npm run build:watch Now the watch mode works. Below is my package.json:

"scripts": {
        "ng": "ng",
        "build": "ng build",
        "build:watch": "npm run build && ng build --watch",
        "build:prod": "ng build --prod && npm run postbuild",
        "postbuild": "npm run copyindex && npm run fixpath",
        "copyindex": "copy /D \".\\dist\\index.html\" \"Views\\Home\\Index.cshtml\" /Y",
        "fixpath": "powershell -Command \"(gc Views\\Home\\Index.cshtml) -replace '(\\w+\\.js|\\w+\\.css)', '~/dist/$1' | Out-File Views\\Home\\Index.cshtml\"",
    },

package.json explanation : after running npm run build the postbuild gets called automatically. postbuild will call copyindex and fixpath one after another.

  • copyindex will copy the content of my dist\index.html to my Views\Home\Index.cshtml.
  • fixpath will add ~/dist/ to the beginning of all js and css file paths in my Index.cshtml.
  • build:watch: calls ng build --watch.
  • build:prod: is for prod build and calls ng build --prod and postbuild one after another.

Note

  • The commands can be run in any console on windows (cmd or bash).
  • I used powershell in my fixpath. It can be replaced by your favorite tool.
pjpscriv
  • 866
  • 11
  • 20
Amir Shirazi
  • 706
  • 8
  • 9
  • 1
    is there any way to have postbuild run in --watch mode after every rebuild? – Balage Feb 21 '19 at 20:34
  • 1
    @Balage you can use "npm run build:watch" which run npm build first, it will copy the index.html to index.cshtml then it will watch the changes, whenever you change some thing in index.html, you need to run this command again. – Nguyen Tran Jul 20 '19 at 06:11
4

If you just want to change the folder that it outputs to you can set that in the angular-cli.json file. There is an 'outdir' setting in that you can change to be the folder you want it to output to.

jenson-button-event
  • 18,101
  • 11
  • 89
  • 155
EricJ
  • 912
  • 1
  • 6
  • 12
2

You should create your own node build script which calls the ng build command and after that copies the files to a directory:

let thread = exec('ng build -e=prod --prod', { maxBuffer: 1024 * 5000});
thread.on('close', (data) => {
    //do your moving stuff here
});

There is no way to hook into the cli (yet), and I don't think they will allow it. As far as I remember, they like to keep things closed there, because this way they are able to change/tune/update the build process a lot, without older builds going haywire

Poul Kruijt
  • 69,713
  • 12
  • 145
  • 149
  • is there a way to hook into the --watch builds with your solution? maybe if you set npm-watch to watch your entire src folder and then trigger a full ng re-build every time a file changes? that would be clumsy – Balage Feb 21 '19 at 20:40
-1

Those looking for solution in angular 6+

In angular.json

in "build" --> options --> "outputPath":"your_path"
Amit
  • 1,460
  • 1
  • 14
  • 39