Angular 2 along with Typescript compiler duplicates HTML and CSS documents

When working with Angular2, I usually set the following configuration in my tsconfig.json file:

"outDir": "dist/app"

This setup allows for the transpiled .js and .map files to be generated within the /dist/app/ folder or its subfolders. This typically works without any issues.

In my component.ts files, I often reference HTML and CSS files like this:

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

Is there a way to configure the compiler to also copy these referenced HTML and CSS files for the entire project? If so, how would I adjust my tsconfig.json?

I have reviewed the compiler options listed here https://www.typescriptlang.org/docs/handbook/compiler-options.html, but did not find any information regarding copying html/css files.

Update: My project's folder structure is as follows:

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

tsconfig.json contains:

"outDir": "dist/app"

And package.json includes:

{
"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 \\;",
......
}

However, despite this setup, the HTML files are not being copied over. Strangely, no error messages are displayed either.

Another Update:

If you're using a Linux OS, Bernardo's solution may work fine. However, for those on Windows OS, the following script should do the trick:

"scripts": {
"html": "XCOPY /S /y .\\app\\*.html .\\dist\\app" }

Answer №1

If you're looking for a solution that works across different operating systems, consider using copyfiles

npm install copyfiles --save-dev

Next, include the following script in your package.json file:

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

After adding this script, running npm run html will copy all CSS and HTML files from the app/ folder to dist/app/ directory.

UPDATE: I also wanted to mention angular-cli. This command line tool provided by the Angular team simplifies bundling processes (ng build --prod), among other functionalities.

Answer №2

Unfortunately, the TypeScript compiler only works with *.ts files.

If you need to include other file types like *.html and *.css in your project, you'll have to manually copy them using a method such as the cp shell command within an npm script or a tool like grunt-contrib-copy.

Here's an example using an npm script:

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

To execute this script, simply run npm run html in the terminal.

Alternatively, you can also use grunt for copying files. Here's an example configuration:

copy: {
      html: {
          src: ['**/*.html'],
          dest: 'dist',
          cwd: 'app',
          expand: true,
      }
}

Answer №3

For those struggling with this issue, Microsoft offers a helpful solution:-
https://github.com/Microsoft/TypeScript-Node-Starter
Be sure to take a look at the "copyStaticAssets" file. If previous solutions have not worked for you, give this a try - it might just be the answer you've been searching for.

Answer №4

After reading Bernardo's response, I made a modification to the code snippet:

"html": "cd app && tsc && find . \( -name '\*.html' -or -name '*.css' \) -type f -exec cp --parents {} ../dist \\;"
. The updated code now compiles and copies both HTML and CSS files in a single step. Additionally, I included
"clean": "rm -rf dist"
to completely delete the 'dist' directory. This tweak seems to be working well. Hope this explanation is helpful!

Answer №5

@yesh kumar, Thank you for providing the link. Below are the steps I followed:

  • Installed shelljs
  • Added static assets to the copyStaticAssets.ts file

import * as shell from "shelljs";

shell.cp("-R", "lib/certs", "dist/");

  • Configured ts-node copyStaticAssets.ts in the script section of package.json
    "scripts": {
      "build": "tsc && npm run copy-static-assets",
      "prod": "npm run build && npm run start",
      "copy-static-assets": "ts-node copyStaticAssets.ts"
     }

Answer №6

To explore a different approach from my in-depth response here: , you could consider keeping your css and html files together with the ts files. By utilizing module.id, which points to the js file of the component, and adjusting it accordingly, you can make use of relative paths effectively :)

For your specific scenario, you might want to try something along these lines:

@Component({
   moduleId: module.id.replace("/dist/", "/"),
...
});

Answer №7

Instead of relying on nodemon like I suggested in my previous response found here: Watching template files and moving them to the dist/ folder, you can now use Webpack within the Angular 4/5 ecosystem for a more efficient solution.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Unable to direct XHR requests even though the URL is functional in the browser

I am currently working on developing a REST API in TypeScript using NodeJS and Express. So far, the API is up and running on localhost. When I visit http://localhost:8080, everything functions as expected. Specifically, I have configured the route http:/ ...

Is there a way to insert data from one table into a MySQL Table in Drizzle and update the entry if it already exists?

My goal is to utilize Drizzle for inserting data into a table and updating it if the key already exists. In MySQL, the code would look like this: INSERT INTO myTable1(field1,field2,field3,field4) SELECT fieldOne,fieldTwo,fieldThree,fieldFour FROM myTable2 ...

Capturing authorization issues in Firebase using ngrx effects

I am currently working on an angular5/firebase/ngrx project and I'm encountering an issue when trying to handle errors during the signup process. When I attempt to submit the signup form with an email that already exists in the system, I receive the ...

Access the document within the Angular Material File Selection feature

I have implemented a Material file selection feature in my project. The code snippet below shows how I am doing it: <label for="uploadPicture" class="upload-file"> <mat-icon>add_a_photo</mat-icon> </label> <input type="file" ...

Something seems to be off with the app while running `docker-compose up

I am completely new to using docker. I currently have a mean stack application and I have set up the dockerfile for both the frontend and backend sections, which you can see below. After running docker-compose up, the process seems to complete successfully ...

The web server is now serving Index.html instead of main.js for AngularJS 2

Transitioning from an angular1 application to an angular2 one, I encountered an error after removing the ng-app directive and adding the system.config: Error: SyntaxError: Unexpected token < Evaluating https://localhost:8080/contents/app/main.js Error ...

Calculating the time difference between two dates in the format yyyy-MM-ddTHH:mm:ss.fffffff can be done by following these steps

Can someone help me figure out how to calculate the difference in days between the date and time 2021-02-23T08:31:37.1410141 (in the format yyyy-MM-ddTHH:mm:ss.fffffff) obtained from a server as a string, and the current date-time in an Angular application ...

The Angular HttpErrorResponse is a class used for handling

I am encountering an issue while attempting to retrieve a user's cart by submitting the username in the request URL. list: PanieDto[] = []; @Input() listform: PanieDto = new PanieDto(); isLoggedIn = false; showAdminBoard = false; showModeratorBoard = ...

Employ the VSTS node API to retrieve all commits within a specified branch

I have been utilizing the vsts-node-api with reasonable success. However, my goal is to retrieve all commits in a specific branch, as detailed in the REST API documentation located here. Unfortunately, the node api only allows for commit queries in a rep ...

run a function once ngFor has completed rendering the data

I'm attempting to run a function every time my ngFor finishes loading data from the API. However, the callback only works on the initial load of the ngFor. How can I make sure that the callback is executed whenever my ngFor data changes? I found a ...

Error in Angular 2 Router: Consistently redirecting to the homepage

I have recently created an Angular 5 application and have been debugging it without encountering any compile errors. Everything was working fine initially when I only used one route.ts file and one app.module.ts file for the entire project. However, as the ...

Defining the type of a React hook object in TypeScript when calling it

Within my code, I have implemented the following custom hook: const count = useDocsCount({ collectionRef: 'notifications', filter: { filterKey: 'seen', operator: '==', filterValue: false } }) ...

Exploring the utilization of type (specifically typescript type) within the @ApiProperty type in Swagger

Currently, I am grappling with a dilemma. In my API documentation, I need to include a 'type' in an @ApiProperty for Swagger. Unfortunately, Swagger seems to be rejecting it and no matter how many websites I scour for solutions, I come up empty-h ...

How can I transform this imperative reducer into a more declarative format using Ramda?

I am currently working with a reducer function that aggregates values in a specific way. The first argument is the aggregated value, while the second argument represents the next value. This function reduces over the same reaction argument, aggregating th ...

Error: Unable to establish connection - Asp.Net Core and Angular 10

Currently, I am following an Asp.net tutorial along with using the Angular server with CORS package integration. My main goal is to make a post request: // POST: api/Trackers // To protect from overposting attacks, enable the specific properties y ...

Difficulty with navigation buttons on multiple Bootstrap carousels implemented using ngFor in a single page

Currently, I'm engaged in developing a practice eCommerce platform where multiple product cards are showcased using data from a sample JSON file. Additionally, several Bootstrap carousels are integrated into the website to display images of each item. ...

Is there a way to verify if a user taps outside a component in react-native?

I have implemented a custom select feature, but I am facing an issue with closing it when clicking outside the select or options. The "button" is essentially a TouchableOpacity, and upon clicking on it, the list of options appears. Currently, I can only cl ...

Exploring Angular 4's Capabilities: Navigating a Multi-Dimensional Array

I am currently working with a multi-dimensional array that has two keys, and it is structured as follows: user: any = {}; // The index is incremented within a for loop to add values to the user object (this part is functioning correctly) this.user[index++ ...

Is it possible to reset the attributes of a container's children using a renderer?

Within a container, there are dropdowns, multiple selects, and quantity selections. When a button is clicked, I aim to reset the state of the component. https://i.stack.imgur.com/TY5un.png <input #select type="checkbox" value="somevalue"/> The ...

The PrimeNG FullCalendar feature seems to be malfunctioning and cannot be located

I've been working on integrating a FullCalendar module into my Angular 7 project. Despite following the steps provided in this link, I haven't had any luck: After executing this command: npm install <a href="/cdn-cgi/l/email-protection" clas ...