Separate Angular2 TypeScript files and JavaScript files into different folders, maybe 'dist‘

I am using the 5 min quickstart from angular.io website, which contain a file structure like this:

angular2-quickstart
app
app.component.ts
boot.ts
index.html
license.md
package.json
tsconfig.json

the tsconfig.json is a code block like this :

{
"compilerOptions": {
"target": "ES5",
"module": "system",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": false,
"noImplicitAny": false
},
"exclude": [
"node_modules"
]
}

Also the package.json:

{
"name": "angular2-quickstart",
"version": "1.0.0",
"scripts": {
"tsc": "tsc",
"tsc:w": "tsc -w",
"lite": "lite-server",
"start": "concurrent \"npm run tsc:w\" \"npm run lite\" "
},
"license": "ISC",
"dependencies": {
"angular2": "2.0.0-beta.0",
"systemjs": "0.19.6",
"es6-promise": "^3.0.2",
"es6-shim": "^0.33.3",
"reflect-metadata": "0.1.2",
"rxjs": "5.0.0-beta.0",
"zone.js": "0.5.10"
},
"devDependencies": {
"concurrently": "^1.0.0",
"lite-server": "^1.3.1",
"typescript": "^1.7.3"
}
}

I change the sourceMap from true to false, so in the code editor, the map file is not generated again, but the js file still get generated.

I want to work on only ts file and don't want to get a brunch of js and js.map file, what should I do to put all my ts files in my regular develop floder like app folder and all the js and js.map files into a folder called dist?

A good example of this might be angular2-webpack-quickstart. But I didn't figure out how they do that?

Any advice how to do that, of course not manually.

Thanks,

43672 次浏览

You can transpile .ts files in the browser, just like plunker is doing in their angular 2 ts template.

Just launch editor, select new, then AngularJS, and 2.0.x (TS) option(on the very bottom). But the whole point of using webpack(or any other bundling tool) is to transpile files locally.

Probably late but here is a two-step solution.

Step 1

Change system.config.js by updating 'app' to 'dist/app':

var  map = {
'app':                        'app', // 'dist/app',
.
.
.
};

Now it will look like this:

var  map = {
'app':                        'dist/app', // 'dist/app',
.
.
.
};

Step 2

Create the dist folder.

Edit tsconfig.json and add:

"outDir": "dist"

The resulting tsconfig.json:

{
"compilerOptions": {
.
.
.
.


"outDir": "dist" // Pay attention here
},
"exclude": [
.
.
.
]
}

Run npm start and you should see all the compiled .js and .map.js files in the dist folder.

Note: Go through other answers. They are quite useful and informative too.

I may be also late but I did this.

First do what raheel shan said.

Then create the dist folder.

After creating the folder go to the file tsconfig.json and add this:

"outDir": "dist"

The resulting tsconfig.json

{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": false,
"noImplicitAny": false,
"outDir": "dist"
},
"exclude": [
"node_modules",
"typings/main",
"typings/main.d.ts"
]
}

If you now run npm start and save a file you should see all the compiled .js and .map.js in the dist folder.

Thanx raheel shan, your answer gave a head start,

As @Adavo rightly asked above in comments

Unfortunately, my html/css files is not present in the dist folder. How to do in order to copy all html/css in dist folder ?

The answer to this question is * provide full path to HTML/CSS File using '/' (from root Directory) in all the .ts Files and mainly in "templateURL" property of @Component

after a lot of time - I got it figured it out - without using Gulp :) Yipppeee

So, to solve this:

Unfortunately, my html/css files is not present in the dist folder. How to do in order to copy all html/css in dist folder ?

Do the steps in both @raheel shan and @Lirianer's answers. ...then you can finish it off with this.

I have solved this for my purposes using npm scripts. The scripts section in my package.json file is below. The solution is to run onchnage (an npm package - npm install --save onchange) concurrently with tsc and the server. Then use rsync to copy the assets you want to move:

"scripts": {
"start": "tsc && concurrently \"npm run tsc:w\" \"npm run lite\" \"npm run watchassets\" ",
"lite": "lite-server",
"postinstall": "typings install",
"tsc": "tsc",
"tsc:w": "tsc -w",
"typings": "typings",
"movesssets": "rsync -a --include='*.css' --include='*.html' --include='*/' --exclude='*' ./app/ ./build/",
"watchassets": "onchange 'app/**/*.css' 'app/**/*.html' -e 'build/*' -v -- rsync -a --include='*.css' --include='*.html' --include='*/' --exclude='*' ./app/ ./build/"
}

For those of you on Windows you can get rsync via Cygwin or with packaged solutions such as cwRsync.

I tried @WillyC's suggestion and worked like a charm, just note that you'll have to add the onchange dependency to your package.json file. I added a little just a little extra scripts to have a clean setup upon first run and also to remove leftover html/css files (it'd be nice if same could be done for TSC)

Anyway, here is a section of my package.json file

{
...
"scripts": {
"start": "npm run cleandist && npm run moveassets && tsc && concurrently \"tsc -w\" \"lite-server\" \"npm run watchassets\" ",
...
"cleandist": "rm -rf dist/*",
"moveassets": "rsync -a --include='*.css' --include='*.html' --include='*/' --exclude='*' ./app/ ./dist/",
"watchassets": "onchange 'app/**/*.css' 'app/**/*.html' -e 'dist/*' -v -- rsync -a --include='*.css' --include='*.html' --include='*/' --exclude='*' --delete ./app/ ./dist/"
},
...
"devDependencies": {
...
"onchange":"^3.0.2"
}
}

For the rsync delete, notice the --delete flag on the rsync command of the watchassets script

Angular2 TypeScript files and JavaScript files into different folder

Here is my config for Angular 2 the latest version V2.1.1, and it work very well!

tsconfig.json

{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": false,
"noImplicitAny": false,
"outDir": "./app/dist"
}
}

systemjs.config.js

/**
* System configuration for Angular samples
* Adjust as necessary for your application needs.
*/
(function (global) {
System.config({
paths: {
// paths serve as alias
'npm:': 'node_modules/'
},
// map tells the System loader where to look for things
map: {
// our app is within the app folder
// app: 'app/dist',  &&  main: './dist/main.js',
// Error: (SystemJS) XHR error (404 Not Found) loading http://localhost:3000/app/dist/dist/main.js(…)
app: 'app',
// angular bundles
'@angular/core': 'npm:@angular/core/bundles/core.umd.js',
'@angular/common': 'npm:@angular/common/bundles/common.umd.js',
'@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
'@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
'@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
'@angular/http': 'npm:@angular/http/bundles/http.umd.js',
'@angular/router': 'npm:@angular/router/bundles/router.umd.js',
'@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
'@angular/upgrade': 'npm:@angular/upgrade/bundles/upgrade.umd.js',
// other libraries
'rxjs':                      'npm:rxjs',
'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js'
},
// packages tells the System loader how to load when no filename and/or no extension
packages: {
app: {
// index.html import path
// Error: (SystemJS) XHR error (404 Not Found) loading http://localhost:3000/app/dist/main.js(…)
// app: 'app/dist',  &&  main: './main.js',
main: './dist/main.js',
defaultExtension: 'js'
},
rxjs: {
defaultExtension: 'js'
}
}
});
})(this);

enter image description here

I tried the suggestion of @raheel & it worked for me. I have modified the structure according to my needs.

I am using the following structure

I am using the following structure

To get this I have modified only two files 1. systemjs.config.js and 2.tsconfig.json

In systemjs.config.js I changed to

map: { // previously it was app: 'app', app: 'app/js', ...

systemjs.config.js

and in tsconfig.json I have to add "outDir": "app/js"

tsconfig.json

Unfortunately, my html/css files is not present in the dist folder. How to do in order to copy all html/css in dist folder ?

Relative paths in Angular 2 are not that straightforward because the framework wants to be flexible with how you load your files (CommonJs, SystemJs, .. etc) according to Component-Relative Paths in Angular 2 article.

As the article explains module.id when used with CommonJs (check your tsconfig.json) contains the absolute root of the module and it can be used to construct a relative path.

So a better alternative could be to leave the css/html files with the ts files and configure your component like below, assuming you just have your build files in a separate folder called dist.. This way your css and html files will be loaded with no problem using relative paths by converting the derived build path to the source one that contains them - essentially removing /dist/ or renaming it to /src/ ;)

@Component({
moduleId: module.id.replace("/dist/", "/"),
templateUrl: 'relative-path-to-template/component.html',
...
});

if you have separate folders for source and build you can do this instead:

@Component({
moduleId: module.id.replace("/dist/", "/src/"),
templateUrl: 'relative-path-to-template/component.html',
...
});

I tried few of the above mentioned options and finally, this is what I settled on: Peep - an extension for Visual Studio Code.

How to install:

  • View -> Extensions
  • Peep
  • Install
  • Reload
  • View -> Command Pallet
  • Peep None
  • modify .vscode/settings.json as required (mine shown below)

-

{
"typescript.check.workspaceVersion": false,
"files.exclude": {
"**/*.js": true,
"**/*.js.map": true,
"node_modules/": true,
"dist/": true,
"lib/": true
}
}

01/25/2017 - updates: angular-cli out of the box, takes care of this. and installation works and now.

I tried the solutions listed here. They are good, but not ideal for me. I want a simple solution. I don't want to hard-code the path information in all my component files. I don't want to install more npm packages to take care of this.

So I come up an easiest alternative. It's not a direct answer to this question, but it works very well for me.

I just tweak my workspace settings so that the js files under /app don't show. They are still there. They are just hidden from my workspace. To me, that's enough.

I'm using Sublime Text, so here is what I have for my project settings:

"file_exclude_patterns": ["app/*.js"]

I'm sure many other editors have similar functions.

UPDATE:

Just use Angular CLI. Everything is taken care of automatically.

My solution is a bit different from the above. I was starting from the Angular2 Quickstart seed defined here: https://github.com/angular/quickstart#create-a-new-project-based-on-the-quickstart

And then only changed the following:

  • Added "outDir": "../dist" to tsconfig.json
  • Changed the baseDir attribute inside bs-config.json to "baseDir": ["dist", "src"]

Then npm run start works as before (even html/css and other files without any copying), but compiled .js and .map files are built into dist/app and won't pollute your src/app directory.

Please note that I haven't tested how this affects testing yet.

I'm working with Angular 2.4. I needed an extra step to make it work. This was update systemJs reference to main.js file in index.html it's, from:

System.import('main.js').catch(function(err){ console.error(err); });

to:

System.import('dist/main.js').catch(function(err){ console.error(err); });

Adding on top of what raheel shan said. I had to make additional change in index.html to reflect to import correct javascript file now.

Here is summary from my side.

tsconfig.json

Before

{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": [ "es2015", "dom" ],
"noImplicitAny": true,
"suppressImplicitAnyIndexErrors": true
}
}

After:

{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": [ "es2015", "dom" ],
"noImplicitAny": true,
"suppressImplicitAnyIndexErrors": true,
"outDir": "dist"
},
"exclude": [
"node_modules",
"typings/main",
"typings/main.d.ts"
]
}

systemjs.config.js

Before:

'app': 'app',

After:

'app': 'dist/app', //'app

index.html

Before:

System.import('main.js').catch(function(err){ console.error(err); });

After:

System.import('dist/main.js').catch(function(err){ console.error(err); });

For Angular 4 with files from quickstart, all I had to do was the following (a mix of the previously stated answers but slightly different values) :

  • In tsconfig.json (add) : "outDir": "../dist"
  • In bs-config.json (change) : "baseDir": ["dist", "src"],
  • In bs-config.e2e.json (change) : "baseDir": ["dist", "src"],

No change to systemjs.config.js.

Inspired by @Nagyl, I developed my own way and I believe it's worth to share:

1) Install cpx

npm install cpx

2) Update bs-config.json and change baseDir from "src" to "dist"

"baseDir":"dist"

3) Update tsconfig.json and add outDir to end of compilerOptions:

"outDir": "../dist"

4) Update package.json: 4.1) add a new command to end of scripts:

"cpx": "cpx \"src/**/*.{html,css,js,png,jpg}\" dist --watch"

4.2) modify "start" line to include "cpx" command:

"start": "concurrently \"npm run build:watch\" \"npm run cpx\" \"npm run serve\"",

Step 2 modification

Step 3 modification

Step 4 modification