Development tools refactor

- common webpack config
  - use latest karma-coverage + remap-istanbul
  - use webpack-ngc instead of ngc buildstep
  - update dev dependencies
  - use V8LazyParseWebpackPlugin
This commit is contained in:
Roman Hotsiy 2017-01-06 21:38:04 +02:00
parent ec7803eecf
commit 049094f179
No known key found for this signature in database
GPG Key ID: 5CB7B3ACABA57CB0
14 changed files with 267 additions and 269 deletions

1
.gitignore vendored
View File

@ -33,6 +33,7 @@ lib/**/*.shim.ngstyle.ts
/dist /dist
/demo/build /demo/build
.tmp .tmp
compiled
/coverage /coverage
.ghpages-tmp .ghpages-tmp
stats.json stats.json

View File

@ -1,6 +1,6 @@
.DS_Store .DS_Store
**/.* **/.*
.tmp compiled
node_modules node_modules
jspm_packages jspm_packages

View File

@ -26,6 +26,7 @@
"**/.*", "**/.*",
"node_modules", "node_modules",
"tests", "tests",
"compiled",
"lib", "lib",
"demo", "demo",
"build", "build",

View File

133
build/webpack.common.js Normal file
View File

@ -0,0 +1,133 @@
const webpack = require('webpack');
const CheckerPlugin = require('awesome-typescript-loader').CheckerPlugin;
const StringReplacePlugin = require("string-replace-webpack-plugin");
const CommonsChunkPlugin = require('webpack/lib/optimize/CommonsChunkPlugin');
const ngcWebpack = require('ngc-webpack');
const VERSION = JSON.stringify(require('../package.json').version);
const root = require('./helpers').root;
module.exports = function (options) {
const conf = {
performance: { hints: false },
output: {
path: root('dist'),
filename: '[name].js',
sourceMapFilename: '[name].[id].map',
chunkFilename: '[id].chunk.js'
},
resolve: {
extensions: ['.ts', '.js', '.json', '.css'],
alias: {
http: 'stream-http',
https: 'stream-http'
}
},
externals: {
'jquery': 'jquery',
'esprima': 'esprima' // optional dep of ys-yaml not needed for redoc
},
module: {
exprContextCritical: false,
rules: [
{
enforce: 'pre',
test: /\.ts$/,
exclude: [
/node_modules/
],
loader: StringReplacePlugin.replace({
replacements: [
{
pattern: /styleUrls:\s*\[\s*'([\w\.\/-]*)\.css'\s*\][\s,]*$/gm,
replacement: function (match, p1, offset, string) {
return `styleUrls: ['${p1}.scss'],`;
}
},
{
pattern: /(\.\/components\/Redoc\/redoc-initial-styles\.css)/gm,
replacement: function (match, p1, offset, string) {
return p1.replace('.css', '.scss');
}
}
]
})
},
{
enforce: 'pre',
test: /\.js$/,
loader: 'source-map-loader',
exclude: [
/node_modules/
]
},
{
test: /\.json$/,
use: 'json-loader'
},
{
test: /lib[\\\/].*\.css$/,
loaders: ['raw-loader'],
exclude: [/redoc-initial-styles\.css$/]
}, {
test: /\.css$/,
loaders: ['style-loader', 'css-loader?-import'],
exclude: [/lib[\\\/](?!.*redoc-initial-styles).*\.css$/]
},
{
test: /lib[\\\/].*\.scss$/,
loaders: ['raw-loader', "sass-loader"],
exclude: [/redoc-initial-styles\.scss$/]
},
{
test: /\.scss$/,
loaders: ['style-loader', 'css-loader?-import', "sass-loader"],
exclude: [/lib[\\\/](?!.*redoc-initial-styles).*\.scss$/]
},
{
test: /\.html$/,
loader: 'raw-loader'
}
],
},
plugins: [
new CheckerPlugin(),
new webpack.DefinePlugin({
'IS_PRODUCTION': options.IS_PRODUCTION,
'LIB_VERSION': VERSION,
'AOT': options.AOT
}),
new StringReplacePlugin()
],
node: {
global: true,
crypto: 'empty',
fs: 'empty',
process: true,
module: false,
clearImmediate: false,
setImmediate: false
}
};
if (options.AOT) {
conf.plugins.push(
new ngcWebpack.NgcWebpackPlugin({
disable: !options.AOT,
tsConfig: root('tsconfig.webpack.json'),
resourceOverride: root('build/resource-override.js')
})
);
}
return conf;
}

View File

@ -1,41 +1,24 @@
const webpack = require('webpack'); const webpack = require('webpack');
const ForkCheckerPlugin = require('awesome-typescript-loader').ForkCheckerPlugin; const CheckerPlugin = require('awesome-typescript-loader').CheckerPlugin;
const StringReplacePlugin = require("string-replace-webpack-plugin"); const StringReplacePlugin = require("string-replace-webpack-plugin");
const root = require('./helpers').root; const root = require('./helpers').root;
const VERSION = JSON.stringify(require('../package.json').version); const VERSION = JSON.stringify(require('../package.json').version);
const IS_PRODUCTION = process.env.NODE_ENV === "production"; const IS_PRODUCTION = process.env.NODE_ENV === "production";
// TODO Refactor common parts of config
module.exports = { const webpackMerge = require('webpack-merge'); // used to merge webpack configs
const commonConfig = require('./webpack.common.js');
module.exports = webpackMerge(commonConfig({
IS_PRODUCTION: process.env.NODE_ENV === "production",
AOT: false
}), {
devtool: '#inline-source-map', devtool: '#inline-source-map',
performance: { hints: false },
resolve: {
extensions: ['.ts', '.js', '.json', '.css'],
alias: {
http: 'stream-http',
https: 'stream-http'
}
},
externals: {
'jquery': 'jquery',
'esprima': 'esprima' // optional dep of ys-yaml not needed for redoc
},
node: {
fs: "empty",
crypto: "empty",
global: true,
process: true,
module: false,
clearImmediate: false,
setImmediate: false
},
entry: { entry: {
'redoc': './lib/index.ts', 'polyfills': './lib/polyfills.ts',
'vendor': './lib/vendor.ts', 'vendor': './lib/vendor.ts',
'polyfills': './lib/polyfills.ts' 'redoc': './lib/index.ts',
}, },
devServer: { devServer: {
contentBase: root('demo'), contentBase: root('demo'),
watchContentBase: true, watchContentBase: true,
@ -47,87 +30,22 @@ module.exports = {
hot: false, hot: false,
stats: 'errors-only' stats: 'errors-only'
}, },
output: {
path: root('dist'),
filename: '[name].js',
sourceMapFilename: '[name].[id].map',
chunkFilename: '[id].chunk.js',
// devtoolModuleFilenameTemplate: "[resource-path]",
// devtoolFallbackModuleFilenameTemplate: "[resource-path]?[hash]",
},
module: { module: {
exprContextCritical: false, rules: [
rules: [{ {
enforce: 'pre', test: /\.ts$/,
test: /\.js$/, use: [
loader: 'source-map-loader', 'awesome-typescript-loader?{configFileName: "tsconfig.webpack.json"}',
exclude: [ 'angular2-template-loader',
/node_modules/ ],
] exclude: [/\.(spec|e2e)\.ts$/]
}, { },
enforce: 'pre', ]
test: /\.ts$/,
exclude: [
/node_modules/
],
loader: StringReplacePlugin.replace({
replacements: [
{
pattern: /styleUrls:\s*\[\s*'([\w\.\/-]*)\.css'\s*\][\s,]*$/gm,
replacement: function (match, p1, offset, string) {
return `styleUrls: ['${p1}.scss'],`;
}
},
{
pattern: /(\.\/components\/Redoc\/redoc-initial-styles\.css)/gm,
replacement: function (match, p1, offset, string) {
return p1.replace('.css', '.scss');
}
}
]
})
}, {
test: /\.ts$/,
loaders: [
'awesome-typescript-loader',
'angular2-template-loader'
],
exclude: [/\.(spec|e2e)\.ts$/]
}, {
test: /lib[\\\/].*\.scss$/,
loaders: ['raw-loader', "sass-loader"],
exclude: [/redoc-initial-styles\.scss$/]
}, {
test: /\.scss$/,
loaders: ['style-loader', 'css-loader?-import', "sass-loader"],
exclude: [/lib[\\\/](?!.*redoc-initial-styles).*\.scss$/]
}, {
test: /\.css$/,
loaders: ['style-loader', 'css-loader?-import'],
}, {
test: /\.html$/,
loader: 'raw-loader'
}]
}, },
plugins: [ plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.optimize.CommonsChunkPlugin({ new webpack.optimize.CommonsChunkPlugin({
name: ['vendor', 'polyfills'], name: ['vendor', 'polyfills'],
minChunks: Infinity minChunks: Infinity
}), })
]
new webpack.DefinePlugin({ })
'IS_PRODUCTION': IS_PRODUCTION,
'LIB_VERSION': VERSION,
'AOT': IS_PRODUCTION
}),
new ForkCheckerPlugin(),
new StringReplacePlugin()
],
}

View File

@ -1,4 +1,5 @@
const webpack = require('webpack'); const webpack = require('webpack');
const V8LazyParseWebpackPlugin = require('v8-lazy-parse-webpack-plugin');
const VERSION = JSON.stringify(require('../package.json').version); const VERSION = JSON.stringify(require('../package.json').version);
@ -11,31 +12,15 @@ const BANNER =
const IS_MODULE = process.env.IS_MODULE != null; const IS_MODULE = process.env.IS_MODULE != null;
const config = { const webpackMerge = require('webpack-merge'); // used to merge webpack configs
context: root(), const commonConfig = require('./webpack.common.js');
devtool: 'source-map',
performance: { hints: false }, const config = webpackMerge(commonConfig({
IS_PRODUCTION: true,
AOT: true
}), {
devtool: 'source-map',
resolve: {
extensions: ['.ts', '.js', '.json', '.css'],
alias: {
http: 'stream-http',
https: 'stream-http'
}
},
externals: {
'jquery': 'jquery',
'esprima': 'esprima' // optional dep of ys-yaml not needed for redoc
},
node: {
fs: "empty",
crypto: "empty",
global: true,
process: true,
module: false,
clearImmediate: false,
setImmediate: false
},
entry: { entry: {
'redoc': IS_MODULE ? ['./lib/vendor.ts', './lib/redoc.module.ts'] : ['./lib/polyfills.ts', './lib/vendor.ts', './lib/index.ts'] 'redoc': IS_MODULE ? ['./lib/vendor.ts', './lib/redoc.module.ts'] : ['./lib/polyfills.ts', './lib/vendor.ts', './lib/index.ts']
}, },
@ -48,34 +33,18 @@ const config = {
libraryTarget: 'umd', libraryTarget: 'umd',
umdNamedDefine: true umdNamedDefine: true
}, },
module: { module: {
exprContextCritical: false, rules: [
rules: [{ {
enforce: 'pre', test: /\.ts$/,
test: /\.js$/, use: [
loader: 'source-map-loader', 'awesome-typescript-loader?{configFileName: "tsconfig.webpack.json"}',
exclude: [ 'angular2-template-loader',
/node_modules/ ],
] exclude: [/\.(spec|e2e)\.ts$/]
}, { }
test: /node_modules\/.*\.ngfactory\.ts$/, ]
loader: 'awesome-typescript-loader'
}, {
test: /\.ts$/,
loader: 'awesome-typescript-loader',
exclude: /(node_modules)/,
}, {
test: /lib[\\\/].*\.css$/,
loaders: ['raw-loader'],
exclude: [/redoc-initial-styles\.css$/]
}, {
test: /\.css$/,
loaders: ['style-loader', 'css-loader?-import'],
exclude: [/lib[\\\/](?!.*redoc-initial-styles).*\.css$/]
}]
}, },
plugins: [ plugins: [
new webpack.LoaderOptionsPlugin({ new webpack.LoaderOptionsPlugin({
minimize: true, minimize: true,
@ -84,7 +53,8 @@ const config = {
new webpack.optimize.UglifyJsPlugin({ new webpack.optimize.UglifyJsPlugin({
compress: { compress: {
warnings: false, warnings: false,
screw_ie8: true screw_ie8: true,
negate_iife: false // for lazy v8
}, },
mangle: { screw_ie8 : true }, mangle: { screw_ie8 : true },
output: { output: {
@ -93,13 +63,9 @@ const config = {
sourceMap: true sourceMap: true
}), }),
new webpack.BannerPlugin(BANNER), new webpack.BannerPlugin(BANNER),
new webpack.DefinePlugin({ new V8LazyParseWebpackPlugin()
'IS_PRODUCTION': true, ]
'LIB_VERSION': VERSION, })
'AOT': true
})
],
}
if (IS_MODULE) { if (IS_MODULE) {
config.externals = { config.externals = {
@ -114,17 +80,6 @@ if (IS_MODULE) {
'rxjs': 'rxjs', 'rxjs': 'rxjs',
'zone.js/dist/zone': 'zone.js/dist/zone' 'zone.js/dist/zone': 'zone.js/dist/zone'
}; };
config.module.rules.push({
test: /\.ts$/,
loader: 'angular2-template-loader',
exclude: [/\.(spec|e2e)\.ts$/]
});
config.module.rules.push({
test: /\.html$/,
loader: 'raw-loader'
});
} }
module.exports = config; module.exports = config;

View File

@ -1,73 +1,31 @@
const webpack = require('webpack'); const webpack = require('webpack');
const root = require('./helpers').root; const root = require('./helpers').root;
const VERSION = JSON.stringify(require('../package.json').version);
const webpackMerge = require('webpack-merge'); // used to merge webpack configs
const commonConfig = require('./webpack.common.js');
module.exports = { module.exports = webpackMerge(commonConfig({
IS_PRODUCTION: true,
AOT: false
}), {
devtool: 'inline-source-map', devtool: 'inline-source-map',
performance: { hints: false },
resolve: {
extensions: ['.ts', '.js', '.json', '.css'],
alias: {
http: 'stream-http',
https: 'stream-http'
}
},
externals: {
'jquery': 'jquery',
'esprima': 'esprima' // optional dep of ys-yaml not needed for redoc
},
node: {
fs: "empty",
crypto: "empty",
global: true,
process: true,
module: false,
clearImmediate: false,
setImmediate: false
},
output: {
path: root('dist'),
filename: '[name].js',
sourceMapFilename: '[name].map',
chunkFilename: '[id].chunk.js'
},
module: { module: {
exprContextCritical: false, exprContextCritical: false,
rules: [{ rules: [
enforce: 'pre', {
test: /\.js$/,
loader: 'source-map-loader',
exclude: [
/node_modules/
]
},{
test: /\.ts$/, test: /\.ts$/,
loaders: [ use: 'awesome-typescript-loader'
'awesome-typescript-loader' },
] {
}, {
test: /\.ts$/, test: /\.ts$/,
loaders: [ use: [
'angular2-template-loader' 'angular2-template-loader',
], ],
exclude: [/\.(spec|e2e)\.ts$/] exclude: [/\.(spec|e2e)\.ts$/]
}, { },
test: /lib[\\\/].*\.css$/, {
loaders: ['raw-loader'],
exclude: [/redoc-initial-styles\.css$/]
}, {
test: /\.css$/,
loaders: ['style-loader', 'css-loader?-import'],
exclude: [/lib[\\\/](?!.*redoc-initial-styles).*\.css$/]
}, {
test: /\.html$/,
loader: 'raw-loader'
}, {
/** /**
* Instruments JS files with Istanbul for subsequent code coverage reporting. * Instruments JS files with Istanbul for subsequent code coverage reporting.
* Instrument only testing sources. * Instrument only testing sources.
@ -85,11 +43,6 @@ module.exports = {
}, },
plugins: [ plugins: [
new webpack.DefinePlugin({
'IS_PRODUCTION': false,
'LIB_VERSION': VERSION,
'AOT': 'false'
}),
new webpack.LoaderOptionsPlugin({ new webpack.LoaderOptionsPlugin({
test: /\.ts$/, test: /\.ts$/,
sourceMap: false, sourceMap: false,
@ -106,4 +59,4 @@ module.exports = {
/(?:[^\\\/]*(?:[\\\/]|$))*[^\\\/]*\.css$/ // ignore css files /(?:[^\\\/]*(?:[\\\/]|$))*[^\\\/]*\.css$/ // ignore css files
]) ])
], ],
} })

View File

@ -9,13 +9,13 @@ module.exports = function (config) {
}, },
coverageReporter: { coverageReporter: {
dir: 'coverage/', type: 'in-memory'
reporters: [ },
{type: 'html'},
{type: 'lcov'}, remapCoverageReporter: {
{type: 'json'}, 'text-summary': null,
{type: 'text-summary'} 'text-lcov': './coverage/lcov.info',
] 'html': './coverage/html'
}, },
webpack: testWebpackConfig, webpack: testWebpackConfig,
webpackMiddleware: { webpackMiddleware: {
@ -42,7 +42,7 @@ module.exports = function (config) {
}, },
colors: true, colors: true,
singleRun: true, singleRun: true,
reporters: travis ? ['mocha', 'coverage', 'coveralls'] : ['mocha', 'coverage'], reporters: travis ? ['mocha', 'coverage', 'remap-coverage', 'coveralls'] : ['mocha', 'coverage', 'remap-coverage'],
browsers: ['PhantomJS'], browsers: ['PhantomJS'],

View File

@ -1,5 +1,5 @@
import { platformBrowser } from '@angular/platform-browser'; import { platformBrowser } from '@angular/platform-browser';
import { AppModuleNgFactory } from './app.module.ngfactory'; import { AppModuleNgFactory } from '../compiled/lib/app.module.ngfactory';
export function bootstrapRedoc() { export function bootstrapRedoc() {
return platformBrowser().bootstrapModuleFactory(AppModuleNgFactory); return platformBrowser().bootstrapModuleFactory(AppModuleNgFactory);

View File

@ -19,9 +19,11 @@
"e2e": "npm run build:prod && npm run e2e-copy && npm run webdriver && protractor", "e2e": "npm run build:prod && npm run e2e-copy && npm run webdriver && protractor",
"deploy": "node ./build/prepare_deploy.js && deploy-to-gh-pages --update demo", "deploy": "node ./build/prepare_deploy.js && deploy-to-gh-pages --update demo",
"ngc": "ngc -p .", "ngc": "ngc -p .",
"webpack:prod": "webpack --config build/webpack.prod.js --profile --bail", "clean:aot": "npm run rimraf -- .tmp lib/**/*.css",
"rimraf": "rimraf",
"webpack:prod": "npm run clean:aot && npm run build:sass && webpack --config build/webpack.prod.js --profile --bail",
"build:sass": "node-sass -q -o lib lib", "build:sass": "node-sass -q -o lib lib",
"build:prod": "npm run build:sass && npm run ngc && npm run webpack:prod", "build:prod": "npm run webpack:prod",
"build:prod-module": "npm run build:sass && npm run ngc && npm run webpack:prod && IS_MODULE=true npm run webpack:prod", "build:prod-module": "npm run build:sass && npm run ngc && npm run webpack:prod && IS_MODULE=true npm run webpack:prod",
"build-dist": "npm run build:prod", "build-dist": "npm run build:prod",
"stats": "webpack --config build/webpack.prod.js --json > stats.json", "stats": "webpack --config build/webpack.prod.js --json > stats.json",
@ -57,7 +59,7 @@
"@types/requirejs": "^2.1.26", "@types/requirejs": "^2.1.26",
"@types/should": "^8.1.28", "@types/should": "^8.1.28",
"angular2-template-loader": "^0.6.0", "angular2-template-loader": "^0.6.0",
"awesome-typescript-loader": "^2.2.4", "awesome-typescript-loader": "~3.0.0-beta.17",
"branch-release": "^1.0.3", "branch-release": "^1.0.3",
"chalk": "^1.1.3", "chalk": "^1.1.3",
"codelyzer": "^2.0.0-beta.4", "codelyzer": "^2.0.0-beta.4",
@ -66,27 +68,30 @@
"css-loader": "^0.26.0", "css-loader": "^0.26.0",
"deploy-to-gh-pages": "^1.1.2", "deploy-to-gh-pages": "^1.1.2",
"http-server": "^0.9.0", "http-server": "^0.9.0",
"istanbul-instrumenter-loader": "^0.2.0", "istanbul-instrumenter-loader": "^1.2.0",
"jasmine-core": "^2.4.1", "jasmine-core": "^2.4.1",
"jasmine-spec-reporter": "^2.4.0", "jasmine-spec-reporter": "^2.4.0",
"karma": "^1.2.0", "karma": "^1.2.0",
"karma-chrome-launcher": "^2.0.0", "karma-chrome-launcher": "^2.0.0",
"karma-coverage": "github:douglasduteil/karma-coverage#next", "karma-coverage": "^1.1.1",
"karma-coveralls": "^1.1.2", "karma-coveralls": "^1.1.2",
"karma-jasmine": "^1.0.2", "karma-jasmine": "^1.0.2",
"karma-mocha-reporter": "^2.0.0", "karma-mocha-reporter": "^2.0.0",
"karma-phantomjs-launcher": "^1.0.0", "karma-phantomjs-launcher": "^1.0.0",
"karma-phantomjs-shim": "^1.1.2", "karma-phantomjs-shim": "^1.1.2",
"karma-remap-coverage": "^0.1.4",
"karma-should": "^1.0.0", "karma-should": "^1.0.0",
"karma-sinon": "^1.0.4", "karma-sinon": "^1.0.4",
"karma-sourcemap-loader": "^0.3.7", "karma-sourcemap-loader": "^0.3.7",
"karma-webpack": "^1.8.0", "karma-webpack": "^1.8.1 ",
"ngc-webpack": "^1.1.0",
"node-sass": "^4.1.1", "node-sass": "^4.1.1",
"phantomjs-prebuilt": "^2.1.7", "phantomjs-prebuilt": "^2.1.7",
"protractor": "^4.0.10", "protractor": "^4.0.10",
"raw-loader": "^0.5.1", "raw-loader": "^0.5.1",
"rimraf": "^2.5.4",
"rxjs": "^5.0.1", "rxjs": "^5.0.1",
"sass-loader": "^4.0.2", "sass-loader": "^4.1.1",
"shelljs": "^0.7.0", "shelljs": "^0.7.0",
"should": "^11.1.0", "should": "^11.1.0",
"sinon": "^1.17.2", "sinon": "^1.17.2",
@ -94,10 +99,12 @@
"string-replace-webpack-plugin": "0.0.4", "string-replace-webpack-plugin": "0.0.4",
"style-loader": "^0.13.1", "style-loader": "^0.13.1",
"ts-helpers": "^1.1.1", "ts-helpers": "^1.1.1",
"tslint": "^4.0.2", "tslint": "^4.2.0",
"typescript": "2.0.9", "typescript": "2.0.10",
"webpack": "^2.1.0-beta.28", "v8-lazy-parse-webpack-plugin": "^0.3.0",
"webpack-dev-server": "^2.1.0-beta.12", "webpack": "2.2.0-rc.3",
"webpack-dev-server": "^2.2.0-rc.0",
"webpack-merge": "^2.3.1",
"zone.js": "^0.7.2" "zone.js": "^0.7.2"
}, },
"dependencies": { "dependencies": {

View File

@ -61,15 +61,6 @@ beforeEach(function() {
}); });
}); });
// afterEach(function() {
// TestBed.resetTestingModule();
// });
// afterEach(function() {
// TestBed.resetTestEnvironment();
// })
var testContext = require.context('..', true, /\.spec\.ts/); var testContext = require.context('..', true, /\.spec\.ts/);
/* /*

View File

@ -6,7 +6,6 @@
"target": "es5", "target": "es5",
"noImplicitAny": false, "noImplicitAny": false,
"sourceMap": true, "sourceMap": true,
"outDir": ".tmp",
"pretty": true, "pretty": true,
"moduleResolution": "node", "moduleResolution": "node",
"types": [ "types": [
@ -20,7 +19,6 @@
"compileOnSave": false, "compileOnSave": false,
"exclude": [ "exclude": [
"node_modules", "node_modules",
".tmp",
"dist" "dist"
], ],
"awesomeTypescriptLoaderOptions": { "awesomeTypescriptLoaderOptions": {

41
tsconfig.webpack.json Normal file
View File

@ -0,0 +1,41 @@
{
"compilerOptions": {
"target": "es5",
"module": "es2015",
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"allowSyntheticDefaultImports": true,
"sourceMap": true,
"noEmit": true,
"noEmitHelpers": true,
"strictNullChecks": false,
"baseUrl": "./src",
"paths": {
},
"lib": [
"es2015",
"dom"
],
"types": [
"node"
]
},
"exclude": [
"node_modules",
"dist",
"**/*.spec.ts",
"**/*.e2e.ts"
],
"awesomeTypescriptLoaderOptions": {
"forkChecker": true,
"useWebpackText": true
},
"angularCompilerOptions": {
"genDir": "./compiled",
"skipMetadataEmit": true
},
"compileOnSave": false,
"buildOnSave": false,
"atom": { "rewriteTsconfig": false }
}