I'm trying to make Vite build my files and output them into the dist folder every time I save/make changes on to my files during development.
How would I do that?
Here is my vite.config.development.js file:
import { defineConfig } from "vite";
export default defineConfig({
base: "./",
build: {
rollupOptions: {
output: {
assetFileNames: "assets/[name].[ext]",
chunkFileNames: "assets/[name].[ext]",
entryFileNames: "assets/[name].js",
},
},
write: true,
},
});
Here is my scripts in package.json:
"frontend-dev": "vite --config vite.config.development.js",
It does the usual localhost:3000 thing, but it does not build my files and put them in the dist folder when I make changes to my source code.
Currently, I have to run a vite build npm script every time which takes a lot of time.
If you want Vite to do a rebuild on file changes, you can use the --watch flag:
vite build --watch
In your case, with a custom config file:
vite build --watch --config vite.config.development.js
With the --watch flag enabled, changes to the config file, as well as any files to be bundled, will trigger a rebuild and will update the files in dist.
Do you know NodeJS? If you know NodeJS, you can monitor folders and files with the fs module. By monitoring the src directory, you can trigger the vite whenever there is a change. This is the manual solution. I don't know if there are currently npm packages that provide this.
NodeJS Filestream Watch
Building on #Mussini's answer, you got options:
add --watch and optional --config vite build --watch --config vite.config.ts on cli
or add to package.json:
{
"name": "frontend",
...
"scripts": {
"dev": "vite",
...
"build-watch": "vite build --watch --config ./vite.config.ts",
"build": "vite build",
or integrate --watch into the vite.config.ts which adds watching to the build cmd by default (vite build does not exit!)
export default defineConfig({
build: {
watch: './vite.config.ts',
You likely want option 2 and use with npm run build-watch
I'm trying to run a dev server with TypeScript and an Angular application without transpiling ts files every time.
What I found is that I can run .ts files with ts-node but I want also to watch .ts files and reload my app/server. An example of this is the command gulp watch.
You can now simply npm install --save-dev ts-node nodemon and then run nodemon with a .ts file and it will Just Work:
nodemon app.ts
Previous versions:
I was struggling with the same thing for my development environment until I noticed that nodemon's API allows us to change its default behaviour in order to execute a custom command.
For example, for the most recent version of nodemon:
nodemon --watch "src/**" --ext "ts,json" --ignore "src/**/*.spec.ts" --exec "ts-node src/index.ts"
Or create a nodemon.json file with the following content:
{
"watch": ["src"],
"ext": "ts,json",
"ignore": ["src/**/*.spec.ts"],
"exec": "ts-node ./src/index.ts" // or "npx ts-node src/index.ts"
}
and then run nodemon with no arguments.
By virtue of doing this, you'll be able to live-reload a ts-node process without having to worry about the underlying implementation.
And with even older versions of nodemon:
nodemon --watch 'src/**/*.ts' --ignore 'src/**/*.spec.ts' --exec 'ts-node' src/index.ts
Or even better: externalize nodemon's config to a nodemon.json file with the following content, and then just run nodemon, as Sandokan suggested:
{
"watch": ["src/**/*.ts"],
"ignore": ["src/**/*.spec.ts"],
"exec": "ts-node ./index.ts"
}
I've dumped nodemon and ts-node in favor of a much better alternative, ts-node-dev
https://github.com/whitecolor/ts-node-dev
Just run ts-node-dev src/index.ts
[EDIT]
Since I wrote this answer, nodemon has improved a lot, the required config is much lighter now and performance is much better. I currently use both (on different projects, obviously), and am satisfied with both.
Here's an alternative to the HeberLZ's answer, using npm scripts.
My package.json:
"scripts": {
"watch": "nodemon -e ts -w ./src -x npm run watch:serve",
"watch:serve": "ts-node --inspect src/index.ts"
},
-e flag sets the extenstions to look for,
-w sets the watched directory,
-x executes the script.
--inspect in the watch:serve script is actually a node.js flag, it just enables debugging protocol.
This works for me:
nodemon src/index.ts
Apparently thanks to since this pull request: https://github.com/remy/nodemon/pull/1552
Summary of options from other answers
nodemon plus ts-node is pretty stable but needs to be explicitly configured and is somewhat slow
node-dev plus ts-node requires much less configuration than nodemon but is still slow
ts-node-dev is fast but unreliable
Note that tsx (which uses ESBuild under the hood) and swc don't do type checking; this should be acceptable since most editors have type checking built-in, and type checking should still be part of your build process. You can also do type checking separately alongside your tests or as a pre-push hook via tsc --noEmit.
(Recommended) tsx
ⓘ TL;DR: fastest with minimal configuration
As of 2023-02-01, tsx seems to be the best combination of speed and minimal configuration:
Install tsx
npm install --save-dev tsx
Update your package.json, e.g.
"scripts: {
"dev": "tsx watch src/index.ts",
Run it
npm run dev
(Adjust these steps if you just want to install tsx globally and run it directly)
Alternative 1: nodemon/node-dev + ts-node + swc
ⓘ TL;DR: as fast as tsx but with more configuration
An alternative option that combines the reliability of nodemon/node-dev with the speed of ts-node-dev is to use ts-node with swc, a TypeScript-compatible transpiler implemented in Rust which is an "order of magnitude faster" than the TypeScript transpiler.
Install nodemon or node-dev (whichever you prefer)
nodemon
npm install --save-dev nodemon
node-dev
npm install --save-dev node-dev
Set up ts-node with swc integration
https://github.com/TypeStrong/ts-node#swc-1
Install necessary packages
npm install --save-dev ts-node #swc/core #swc/helpers regenerator-runtime
Add this to tsconfig.json
"ts-node": {
"swc": true
}
Run nodemon or node-dev, e.g
nodemon --watch src src/index.ts
or:
node-dev src/index.ts
Alternative 2: nodemon/node-dev + ts-node transpileOnly
ⓘ TL;DR: fast, reliable
Here's an alternative that's slower than the previous option because it uses the standard TypeScript transpiler, but in my testing it's still faster than nodemon/node-dev + ts-node.
Basically it's the same as the previous option but without swc. It's faster than out-of-the-box ts-node by disabling type checking (see notes above regarding why this should be acceptable).
Install nodemon/node-dev as above
Install ts-node
npm install --save-dev ts-node
Modify your tsconfig.json to enable transpileOnly for ts-node
"ts-node": {
"transpileOnly": true
}
Call nodemon/node-dev as above
Alternative 3: nodemon + tsc --incremental
ⓘ TL;DR: fast, reliable, type checking, more finicky
This is nearly the same speed as the previous alternative. The only real advantage of this over the other options is that it does type checking.
In terms of downsides, it can be a bit more finicky; in my testing, I'm using dotenv to pick up my .env file for local development. But depending how your tsc build is configured in tsconfig.json, you may have to do some acrobatics to get it working.
But it's good to have options, so here it is:
Install nodemon as above
(It's possible that this may work with node-dev as well, but I didn't see an exec option for node-dev)
Configure tsconfig.json to transpile your TypeScript to JavaScript
In particular, noEmit should not be set to true
Configure nodemon to run the TypeScript compiler to do an incremental transpilation any time a TypeScript file is changed, e.g.
"dev": "nodemon -e ts --watch src .env --exec \"tsc --incremental && node src/index.js\"",
You can even remove --incremental to further simplify it, but it will end up being much slower, comparable to nodemon/node-dev + ts-node.
you could use ts-node-dev
It restarts target node process when any of required files changes (as standard node-dev) but shares Typescript compilation process between restarts.
Install
yarn add ts-node-dev --dev
and your package.json could be like this
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"tsc": "tsc",
"dev": "ts-node-dev --respawn --transpileOnly ./src/index.ts",
"prod": "tsc && node ./build/index.js"
}
Specifically for this issue I've created the tsc-watch library. you can find it on npm.
Obvious use case would be:
tsc-watch server.ts --outDir ./dist --onSuccess "node ./dist/server.js"
Add "watch": "nodemon --exec ts-node -- ./src/index.ts" to scripts section of your package.json.
i did with
"start": "nodemon --watch 'src/**/*.ts' --ignore 'src/**/*.spec.ts' --exec ts-node src/index.ts"
and yarn start.. ts-node not like 'ts-node'
I would prefer to not use ts-node and always run from dist folder.
To do that, just setup your package.json with default config:
....
"main": "dist/server.js",
"scripts": {
"build": "tsc",
"prestart": "npm run build",
"start": "node .",
"dev": "nodemon"
},
....
and then add nodemon.json config file:
{
"watch": ["src"],
"ext": "ts",
"ignore": ["src/**/*.spec.ts"],
"exec": "npm restart"
}
Here, i use "exec": "npm restart"
So all ts file will re-compile to js file and then restart the server.
To run while in dev environment,
npm run dev
Using this setup I will always run from the distributed files and no need for ts-node.
add this to your package.json file
scripts {
"dev": "nodemon --watch '**/*.ts' --exec 'ts-node' index.ts"
}
and to make this work you also need to install ts-node as dev-dependency
yarn add ts-node -D
run yarn dev to start the dev server
Another way could be to compile the code first in watch mode with tsc -w and then use nodemon over javascript. This method is similar in speed to ts-node-dev and has the advantage of being more production-like.
"scripts": {
"watch": "tsc -w",
"dev": "nodemon dist/index.js"
},
The first step - Install the below packages in deDependencies
npm i -D #types/express #types/node nodemon ts-node tsc typescript
or using yarn
yarn add -D #types/express #types/node nodemon ts-node tsc typescript
The second step - using this configuration in your tsconfig.json file
{
"compilerOptions": {
"target": "es6" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */,
"module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */,
"lib": [
"DOM",
"ES2017"
] /* Specify library files to be included in the compilation. */,
"sourceMap": true /* Generates corresponding '.map' file. */,
"outDir": "./dist" /* Redirect output structure to the directory. */,
"rootDir": "./src" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */,
"strict": true /* Enable all strict type-checking options. */,
"moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */,
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
"skipLibCheck": true /* Skip type checking of declaration files. */,
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
},
"exclude": ["node_modules"],
"include": ["./src"]
}
The third step - using these scripts in your package.json file
"scripts": {
"start": "node ./dist/server.js",
"dev": "nodemon -L ./src/server.ts && tsc -w"
},
STEP 1: You can simple install nodemon and ts-node (skip if you already done)
npm install --save-dev nodemon ts-node
STEP 2: You can configure the start script in package.json
"start": "nodemon ./src/app.ts"
As now nodemon automatically identify the typescript from the project now and use ts-node command by itself. Use npm start and it will automatically compile/watch and reload.
If you get any errors like typescript module not found in the project. simple use this command in the project folder.
npm link typescript
Just update these 3 packages
nodemon, ts-node, typescript
yarn global add nodemon ts-node typescript
or
npm install -g nodemon ts-node typescript
and now you can run this, problem solved
nodemon <filename>.ts
Clear logs of the console after changing
Javascript:
"start": "nodemon -x \"cls && node\" index.js",
Typescript:
"start": "nodemon -x \"cls && ts-node\" index.ts",
If you are having issues when using "type": "module" in package.json (described in https://github.com/TypeStrong/ts-node/issues/1007) use the following config:
{
"watch": ["src"],
"ext": "ts,json",
"ignore": ["src/**/*.spec.ts"],
"exec": "node --loader ts-node/esm --experimental-specifier-resolution ./src/index.ts"
}
or in the command line
nodemon --watch "src/**" --ext "ts,json" --ignore "src/**/*.spec.ts" --exec "node --loader ts-node/esm --experimental-specifier-resolution src/index.ts"
With nodemon and ts-node:
nodemon --watch source --ext ts,json --exec "node --loader ts-node/esm ./source/index.ts"
I am using an .env file to hold environment variables for the server. This works if I run the server with foreman start. But it doesn't work with nodemon.
I would like to use nodemon instead because it restarts automatically when you modify the server. How can I get nodemon to work with .env files?
Install dotenv npm i dotenv
Create .env file and your variables inside
Add the script to execute
"dev": "nodemon -r dotenv/config ./app/index.js " or
"start": "node -r dotenv/config ./app/index.js "
Run the app using npm run dev or npm run start
I have a production Procfile with:
web: node web.js
So I have created a Procfile_dev file with:
web: nodemon web.js
And when I am at development environment I run:
$ foreman start -f Procfile_dev
It works like a charm and doesn't affect production.
You can get nodemon to directly use the .env with the following command
$: env $(cat .env) nodemon app.js
Be aware that you'll have to restart it if you make changes to .env and it won't like it if there are any spaces in your .env file.
With recent versions of Node (since io.js 1.6), you can pass it the -r flag to require a module on start. This lets you directly load .env by using nodemon's --exec:
nodemon --exec 'node -r dotenv/config'
This requires the npm package dotenv to be installed.
Place your local configuration variables in the .env file and run foreman along with nodemon using the following command
$ foreman run nodemon web.js
This works pretty well for me so far,
nodemon -w . -w .env index.js
How it works:
"-w ." tells nodemon to watch the files in the current directory
"-w .env" tells nodemon to watch the .env file
"index.js" is just the file to run when changes occur (could be anything)
"scripts": {
"start": "node -r dotenv/config src/server.js dotenv_config_path=dev.env dotenv_config_debug=true",
"start:dev": "nodemon --exec \"npm start\""
}
In my case the .env file is used for development and not deployment. So I wanted my code to be decoupled from the .env file. Ideally I didn't want to import 'dotenv/config' anywhere in my code. This is my solution:
My nodemon config:
{
"watch": [
"src",
".env"
],
"ext": ".ts",
"exec": "ts-node -r dotenv/config ./src/index.ts"
}
My NPM script:
"start:dev": "nodemon"
In this solution ts-node requires dotenv, which sets up the environment variables before the main app starts. This means that nowhere in my code do I need a import 'dotenv/config'. dotenv can become a dev dependency, and this also prevents dotenv to be loaded at all once the code is deployed.
Thread necromancy!
Use grunt-env to load environmental variables from your heroku config.
In Three steps
Creating the file on root folder > .env
# .env ======
PORT=5000
WHO_AM_I="Who Knows"
Install the dotenv
Run below command
"dev": "nodemon -r dotenv/config src/app.js"
You can access the your defined variables using > process.env.varible_name
If you want to run Typescript in nodemon and require a particular .env file with dotenv then you can do:
In package.json scripts:
"dev": "nodemon -r dotenv/config src/myApp.ts dotenv_config_path=/path/to/your/env/file",
And a line in nodemon.json to tell nodemon to use ts-node when encountering Typescript extensions:
"execMap": {"ts": "node -r ts-node/register"},
This is useful for using a development .env file say .env.development.local for local dev work and leave the main .env file for live production variables.
Use the -w key to specify nodemon what to watch additionally.
"scripts": {
"dev": "env-cmd nodemon -w app -w *.js -w .env server.js"
}
Don't forget rerun npm run dev
Heroku Procfile
Change: web: node app.js to web: nodemon app.js
To load the dotenv package and any declared .env vars into the environment, you can do the following:
nodemon -r dotenv/config myapp.js
I use cross-env for environments.
npm i cross-env
set package.json.
"start": "cross-env NODE_ENV=production node dist/app.js",
"dev": "cross-env NODE_ENV=dev nodemon --exec ts-node src/app.ts",
npm run start OR npm run dev