Can I configure VSCode Typescript build task to copy (and update if needed) all non-typescript files from source to dist folder when I build it?

Viewed 106

I have two folders in my project, src where I want to write all of my code and dist where I want to have a ready to run program once I build all the typescript files, right now after building it looks like this:

Screenshot of the current project tree

Ideally I want my build task to make sure that the dist folder is a 1:1 copy of the src folder with all .ts files replaced with newly built .js files and to update all other files like .html if I change them in the src folder when I build typescript.

1 Answers

This seems to be a pretty common case, yet there's no "officially-recommended" way to do it. (Here's a related GitHub issue: ms/TS#30835.)

You can solve this using a couple of npm packages to help with filesystem manipulation, and some npm scripts to define the behavior you want:

Packages

First, install these packages:

npm install copyfiles rimraf

npm scripts

Then, write a few npm scripts in your package.json to combine all of the behavior you want:

package.json:

{
  ...
  "scripts": {
    "prebuild": "rimraf ./dist",
    "build": "npm run compile && npm run copy-assets",
    "compile": "tsc",
    "copy-assets": "copyfiles --all --up 1 --exclude \"./**/*.{ts,tsx}\" \"./src/**/*\" ./dist"
  },
  "dependencies": {
    "copyfiles": "^2.4.1",
    "rimraf": "^3.0.2",
    "typescript": "^4.5.4"
  }
  ...
}

Script explanations:

  • prebuild: (This is a pre-script, and runs before the build script) simply deletes the dist directory and its contents before the build script runs

  • build: Runs other scripts: first the compile script, then (if it was successful) the copy-assets script

  • compile: Runs tsc to compile your TypeScript project files according to your tsconfig.json (presumably, based on your screenshot, you have configured compilerOptions.outDir to "dist")

  • copy-assets: Copies all files/folders from src to dist (excluding files ending in .ts and .tsx). I'll explain this one further, part by part:

    • copyfiles: runs the command
    • --all: enables copying of all files (including dotfiles)
    • --up 1: by default, the target directory src will be copied to the destination directory dist: instead, this moves all files up one level: everything that would have been copied to dist/src/ is copied directly into dist/
    • --exclude "./**/*.{ts,tsx}": a glob pattern to exclude all files that end in .ts and .tsx
    • "./src/**/*": a glob pattern for the target: copy all files in src recursively
    • ./dist: the destination directory for the copied files

Use

Once you've installed those two packages and added the npm scripts, all you need to do is run the build script to compile your TypeScript project and copy all the asset files to dist:

npm run build

example:

./src
├── index.html
├── script.ts
├── script2.ts
├── subdir
│   ├── Component.tsx
│   └── data.json
└── texture.png

./dist
├── index.html
├── script.js
├── script2.js
├── subdir
│   ├── Component.js
│   └── data.json
└── texture.png

Done!

Related