35

In Angular2 I would have

"outDir": "dist/app"

in tsconfig.json. As a result the transpiled .js and .map files are generated in /dist/app/ folder and/or its sub folders. That works all fine.

In my components.ts files I also used referenced html and css like this

@Component({
  selector: 'my-app', 
  templateUrl: 'app/appshell/app.component.html',
  styleUrls: ['app/appshell/app.component.css'],
  ......
}

Is there any way to make compiler to also copy the referenced html and css files for the whole project? If yes, how would I configure my tsconfig.json?

I looked into the compiler options here https://www.typescriptlang.org/docs/handbook/compiler-options.html but didn't find anything about copying html/css files.

Update: My folder structure is like this

Root
  |--app       // for ts
  |--dist/app  // for js

tsconfig.json

"outDir": "dist/app"

package.json

{
  "name": "TestApp",
  "version": "1.0.0",
  "scripts": {
    "start": "tsc && concurrently \"tsc -w\" \"lite-server\" ",
    "html": "find ./app -name '*.html' -type f -exec cp --parents {} ./dist \\;",
    ......
}

It doesn't copy html files. There is no error though.

Update again:

For those who are on Linux OS, Bernardo's solution is a working one. For those who are on Windows OS, the following should work.

  "scripts": {
    "html": "XCOPY /S /y .\\app\\*.html .\\dist\\app" }
Michail Michailidis
  • 11,792
  • 6
  • 63
  • 106
Shawn
  • 5,130
  • 13
  • 66
  • 109
  • 1
    Just to expose you to ecosystems that you might not have considered, its easy to package everthing as JS today with TypeScript+React+FreeStyle (https://medium.com/@basarat/css-modules-are-not-the-solution-1235696863d6) – basarat Aug 01 '16 at 23:21
  • `xcopy` is deprecated. An good alternative would be a `"static": "robocopy app dist\\app *.html *.css /e /purge"` and a `"build": "npm run start && npm run static"`. So you could build the whole app in one step or separately. – Nuno André Aug 22 '18 at 14:39

7 Answers7

56

For an OS independent solution, use copyfiles

npm install copyfiles --save-dev

Then add a script to package.json

"scripts": {
  "html": "copyfiles -u 1 app/**/*.html app/**/*.css dist/"
}

Now npm run html should copy all css and html files from the app/ folder to dist/app/

EDIT: I'd like to amend my answer to point out angular-cli. This command line tooling utility is supported by the angular team and makes bundling a breeze (ng build --prod), among other things.

Ali Cheaito
  • 3,746
  • 3
  • 25
  • 30
19

No, the TypeScript compiler is just for *.ts file.

You have to copy other files like *.html and *.css using a copy method like cp shell command inside a npm script or grunt-contrib-copy for example.

Example using npm script:

"scripts": {
  "html": "find ./app -name '*.html' -type f -exec cp --parents {} ./dist \\;"
}

Just run npm run html in the shell.

Example using grunt:

copy: {
      html: {
          src: ['**/*.html'],
          dest: 'dist',
          cwd: 'app',
          expand: true,
      }
}
Bernardo Pacheco
  • 1,445
  • 1
  • 14
  • 23
  • Thanks for the reply. what is the syntax for npm recursive cp script? `"html": "cp -R app/*.html dist/app/",` does not work. – Shawn Aug 01 '16 at 22:15
  • @Shawn I've updated the npm html script. Now it'll copy all the *.html files keeping the directory structure. Please, test it. – Bernardo Pacheco Aug 01 '16 at 23:16
  • Bernardo, I tried your code. It didn't copy the html files. I updated my post to let you see what I did. Maybe I missed something. – Shawn Aug 02 '16 at 01:24
  • @Shawn thanks for the update, now I see what's wrong. You must copy to the `./dist` folder instead of `./dist/app` folder. The `--parents` already clone the folder structure. Use exactly the command that I put above. Also, you must have to ensure that the `./dist` folder exist before you copy the html files. So, before running `npm run html`, the `dist` folder must exist. – Bernardo Pacheco Aug 02 '16 at 01:52
  • Bernardo, dist folder exists and I did exactly `"html": "find ./app -name '*.html' -type f -exec cp --parents {} ./dist \\;"`. But it still didn't do it. – Shawn Aug 02 '16 at 04:45
  • What are the errors in the console? The package.json you post show you're copying to dist/app. – Bernardo Pacheco Aug 02 '16 at 12:46
  • There is no error. I updated my post. the `find` command is a OS command or npm command? – Shawn Aug 02 '16 at 14:16
  • @Shawn you're running your whole build process, not the command we're discussing. Please, run just `npm run html` to copy the html files. – Bernardo Pacheco Aug 02 '16 at 14:30
  • Sorry I misunderstood you. I ran `npm run html` and it gave the error `File not found - '*.html'`. Do I need to add a recursive option? – Shawn Aug 02 '16 at 14:49
  • I think `find` command is a lunix command. If yes, then I would have to find similar things for Windows. – Shawn Aug 02 '16 at 15:18
  • I tried this command and its giving the error find: missing argument to `-exec'. "mycommand": "find ./src/utils/curl -name \"*.exe\" -type f -exec cp --parents {} ./lib \\;" and then when I run mycommand, i get the above error – Minu Jul 08 '19 at 21:01
  • is there an tsconfig command that will run this script on change detected? – Omar May 12 '20 at 19:13
4

This approach is provided by Microsoft:-
https://github.com/Microsoft/TypeScript-Node-Starter
Check out the file "copyStaticAssets". None of the solutions above worked for me, so I hope this helps someone like me.

Yash Gadle
  • 427
  • 6
  • 14
3

From the Bernardo's answer I changed this

 "html": "find ./app -name '.html' -type f -exec cp --parents {} ./dist \\;" 
for this
"html": "cd app && tsc && find . \( -name '.html' -or -name '*.css' \) -type f -exec cp --parents {} ../dist \\;"
and is working good. Compile and copy html and css files in one instruction I also added this
"clean": "rm -rf dist"
in order to remove the whole directory dist. Hope this help!
vicmac
  • 645
  • 2
  • 6
  • 10
2

@yesh kumar, Thanks for sharing the link. Here the steps I did

  • Installshelljs
  • Add static assets to copyStaticAssets.ts file

import * as shell from "shelljs";

shell.cp("-R", "lib/certs", "dist/");
  • Configure ts-node copyStaticAssets.ts in package.json script section
    "scripts": {
      "build": "tsc && npm run copy-static-assets",
      "prod": "npm run build && npm run start",
      "copy-static-assets": "ts-node copyStaticAssets.ts"
     }
0

As an alternative from my detailed answer here: https://stackoverflow.com/a/40694657/986160 could be to leave your css and html with the ts files. Then you can use module.id which will have the path pointing to the js of the component and after converting it accordingly you can essentially use relative paths :)

For your case I think something like that will work:

@Component({
   moduleId: module.id.replace("/dist/", "/"),
...
});
Community
  • 1
  • 1
Michail Michailidis
  • 11,792
  • 6
  • 63
  • 106
0

As an alternative using nodemon from my answer here: Watch template files and copy them to dist/ folder could be configured using package.json to put your css and html files with a simple copy commnad of your host OS.

But, in this days, you have Webpack in the Angular 4/5 ecosystem.

0zkr PM
  • 825
  • 9
  • 11