Skip to content

Commit

Permalink
fix(config): allow minimal config for build/serve (#3835)
Browse files Browse the repository at this point in the history
This PR fixes a lot of errors that would show up when `angular-cli.json` was missing some entries.

A config as small as the following now works for `ng build/serve`:

```
{
  "apps": [
    {
      "root": "src",
      "main": "main.ts"
    }
  ]
}
```

In future PRs we should verify the rest of the commands work correctly with minimal configs.
  • Loading branch information
filipesilva authored Jan 3, 2017
1 parent e2b051f commit f616158
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 30 deletions.
3 changes: 2 additions & 1 deletion packages/angular-cli/lib/config/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@
"type": "string"
},
"tsconfig": {
"type": "string"
"type": "string",
"default": "tsconfig.json"
},
"prefix": {
"type": "string"
Expand Down
6 changes: 4 additions & 2 deletions packages/angular-cli/models/json-schema/schema-tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,11 @@ export abstract class NonLeafSchemaTreeNode<T> extends SchemaTreeNode<T> {
if (!schema['oneOf']) {
type = schema['type'];
} else {
let testValue = value || schema['default'];
// Match existing value to one of the schema types
for (let testSchema of schema['oneOf']) {
if ((testSchema['type'] === 'array' && Array.isArray(value))
|| typeof value === testSchema['type']) {
if ((testSchema['type'] === 'array' && Array.isArray(testValue))
|| typeof testValue === testSchema['type']) {
type = testSchema['type'];
schema = testSchema;
break;
Expand Down
47 changes: 29 additions & 18 deletions packages/angular-cli/models/webpack-build-common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,8 @@ export function getWebpackCommonConfig(
main: [appMain]
};

if (!(environment in appConfig.environments)) {
throw new SilentError(`Environment "${environment}" does not exist.`);
}

// process global scripts
if (appConfig.scripts.length > 0) {
if (appConfig.scripts && appConfig.scripts.length > 0) {
const globalScripts = extraEntryParser(appConfig.scripts, appRoot, 'scripts');

// add entry points and lazy chunks
Expand All @@ -67,7 +63,7 @@ export function getWebpackCommonConfig(
}

// process global styles
if (appConfig.styles.length === 0) {
if (!appConfig.styles || appConfig.styles.length === 0) {
// create css loaders for component css
extraRules.push(...makeCssLoaders());
} else {
Expand Down Expand Up @@ -104,6 +100,33 @@ export function getWebpackCommonConfig(
}));
}

// process environment file replacement
if (appConfig.environments) {
if (!('source' in appConfig.environments)) {
throw new SilentError(`Environment configuration does not contain "source" entry.`);
}
if (!(environment in appConfig.environments)) {
throw new SilentError(`Environment "${environment}" does not exist.`);
}

extraPlugins.push(new webpack.NormalModuleReplacementPlugin(
// This plugin is responsible for swapping the environment files.
// Since it takes a RegExp as first parameter, we need to escape the path.
// See https://webpack.github.io/docs/list-of-plugins.html#normalmodulereplacementplugin
new RegExp(path.resolve(appRoot, appConfig.environments['source'])
.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&')),
path.resolve(appRoot, appConfig.environments[environment])
));
}

// process asset entries
if (appConfig.assets) {
extraPlugins.push(new GlobCopyWebpackPlugin({
patterns: appConfig.assets,
globOptions: { cwd: appRoot, dot: true, ignore: '**/.gitkeep' }
}));
}

if (progress) { extraPlugins.push(new ProgressPlugin({ profile: verbose, colors: true })); }

return {
Expand Down Expand Up @@ -145,22 +168,10 @@ export function getWebpackCommonConfig(
new BaseHrefWebpackPlugin({
baseHref: baseHref
}),
new webpack.NormalModuleReplacementPlugin(
// This plugin is responsible for swapping the environment files.
// Since it takes a RegExp as first parameter, we need to escape the path.
// See https://webpack.github.io/docs/list-of-plugins.html#normalmodulereplacementplugin
new RegExp(path.resolve(appRoot, appConfig.environments['source'])
.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&')),
path.resolve(appRoot, appConfig.environments[environment])
),
new webpack.optimize.CommonsChunkPlugin({
minChunks: Infinity,
name: 'inline'
}),
new GlobCopyWebpackPlugin({
patterns: appConfig.assets,
globOptions: { cwd: appRoot, dot: true, ignore: '**/.gitkeep' }
}),
new webpack.LoaderOptionsPlugin({
test: /\.(css|scss|sass|less|styl)$/,
options: {
Expand Down
14 changes: 6 additions & 8 deletions packages/angular-cli/models/webpack-build-typescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ const webpackLoader: string = g['angularCliIsLocal']


export const getWebpackNonAotConfigPartial = function(projectRoot: string, appConfig: any) {
let exclude = [ '**/*.spec.ts' ];
if (appConfig.test) { exclude.push(path.join(projectRoot, appConfig.root, appConfig.test)); };
return {
module: {
rules: [
Expand All @@ -23,10 +25,7 @@ export const getWebpackNonAotConfigPartial = function(projectRoot: string, appCo
new AotPlugin({
tsConfigPath: path.resolve(projectRoot, appConfig.root, appConfig.tsconfig),
mainPath: path.join(projectRoot, appConfig.root, appConfig.main),
exclude: [
path.join(projectRoot, appConfig.root, appConfig.test),
'**/*.spec.ts'
],
exclude: exclude,
skipCodeGeneration: true
}),
]
Expand All @@ -35,6 +34,8 @@ export const getWebpackNonAotConfigPartial = function(projectRoot: string, appCo

export const getWebpackAotConfigPartial = function(projectRoot: string, appConfig: any,
i18nFile: string, i18nFormat: string, locale: string) {
let exclude = [ '**/*.spec.ts' ];
if (appConfig.test) { exclude.push(path.join(projectRoot, appConfig.root, appConfig.test)); };
return {
module: {
rules: [
Expand All @@ -52,10 +53,7 @@ export const getWebpackAotConfigPartial = function(projectRoot: string, appConfi
i18nFile: i18nFile,
i18nFormat: i18nFormat,
locale: locale,
exclude: [
path.join(projectRoot, appConfig.root, appConfig.test),
'**/*.spec.ts'
]
exclude: exclude
})
]
};
Expand Down
3 changes: 2 additions & 1 deletion packages/angular-cli/tasks/serve-webpack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ export default Task.extend({
proxy: proxyConfig,
compress: serveTaskOptions.target === 'production',
watchOptions: {
poll: CliConfig.fromProject().config.defaults.poll
poll: CliConfig.fromProject().config.defaults &&
CliConfig.fromProject().config.defaults.poll
},
https: serveTaskOptions.ssl
};
Expand Down
14 changes: 14 additions & 0 deletions tests/e2e/tests/misc/minimal-config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { writeFile } from '../../utils/fs';
import { ng } from '../../utils/process';


export default function () {
return Promise.resolve()
.then(() => writeFile('angular-cli.json', JSON.stringify({
apps: [{
root: 'src',
main: 'main.ts'
}]
})))
.then(() => ng('build'));
}

0 comments on commit f616158

Please sign in to comment.