Skip to content

Commit

Permalink
feat(build): allow additional entry points
Browse files Browse the repository at this point in the history
  • Loading branch information
filipesilva committed Aug 12, 2016
1 parent f40e6f1 commit dc1f1c3
Show file tree
Hide file tree
Showing 25 changed files with 244 additions and 141 deletions.
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,8 @@ A build can specify both a build target (`development` or `production`) and an
environment file to be used with that build. By default, the development build
target is used.

At build time, `src/app/environments/environment.ts` will be replaced by
`src/app/environments/environment.{NAME}.ts` where `NAME` is the argument
At build time, `src/environments/environment.ts` will be replaced by
`src/environments/environment.NAME.ts` where `NAME` is the argument
provided to the `--environment` flag.

These options also apply to the serve command. If you do not pass a value for `environment`,
Expand All @@ -143,9 +143,10 @@ ng build --dev
ng build
```

You can also add your own env files other than `dev` and `prod` by creating a
`src/app/environments/environment.{NAME}.ts` and use them by using the `--env=NAME`
flag on the build/serve commands.
You can also add your own env files other than `dev` and `prod` by doing the following:
- create a `src/environments/environment.NAME.ts`
- add `{ NAME: 'src/environments/environment.NAME.ts' }` to the the `apps[0].environments` object in `angular-cli.json`
- use them by using the `--env=NAME` flag on the build/serve commands.

### Bundling

Expand Down
2 changes: 1 addition & 1 deletion addon/ng2/blueprints/component/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ module.exports = {
dir = dirParts.join(path.sep);
}
}
var srcDir = this.project.ngConfig.defaults.sourceDir;
var srcDir = this.project.ngConfig.apps[0].root;
this.appDir = dir.substr(dir.indexOf(srcDir) + srcDir.length);
this.generatePath = dir;
return dir;
Expand Down
1 change: 0 additions & 1 deletion addon/ng2/blueprints/ng2/files/__path__/app/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
export * from './environments/environment';
export * from './app.component';
export * from './app.module';
3 changes: 2 additions & 1 deletion addon/ng2/blueprints/ng2/files/__path__/main.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule, environment } from './app/';
import { environment } from './environments/environment';
import { AppModule } from './app/';

if (environment.production) {
enableProdMode();
Expand Down
2 changes: 2 additions & 0 deletions addon/ng2/blueprints/ng2/files/__path__/scripts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// You can add additional imports to this file and
// they will be loaded before your app
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/* You can add add global styles to this file, and also import other style files */
22 changes: 18 additions & 4 deletions addon/ng2/blueprints/ng2/files/angular-cli.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,24 @@
},
"apps": [
{
"main": "<%= sourceDir %>/main.ts",
"tsconfig": "<%= sourceDir %>/tsconfig.json",
"mobile": <%= isMobile %>
"root": "<%= sourceDir %>",
"outDir": "dist",
"assets": "assets",
"index": "index.html",
"main": "main.ts",
"test": "test.ts",
"tsconfig": "tsconfig.json",
"mobile": <%= isMobile %>,
"additionalEntries": [
{ "input": "polyfills.ts", "output": "polyfills.js" },
"scripts.ts",
"styles.<%= styleExt %>"
],
"environments": {
"source": "environments/environment.ts",
"prod": "environments/environment.prod.ts",
"dev": "environments/environment.dev.ts"
}
}
],
"addons": [],
Expand All @@ -24,7 +39,6 @@
},
"defaults": {
"prefix": "<%= prefix %>",
"sourceDir": "<%= sourceDir %>",
"styleExt": "<%= styleExt %>",
"prefixInterfaces": false,
"lazyRoutePrefix": "+"
Expand Down
Empty file.
84 changes: 63 additions & 21 deletions addon/ng2/models/webpack-build-common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,37 @@ import * as webpack from 'webpack';
import { ForkCheckerPlugin } from 'awesome-typescript-loader';
import { CliConfig } from './config';

export function getWebpackCommonConfig(projectRoot: string, sourceDir: string) {
export function getWebpackCommonConfig(projectRoot: string, environment: string, appConfig: any) {

const appRoot = path.resolve(projectRoot, appConfig.root);
const appMain = path.resolve(appRoot, appConfig.main);

const bundledWithMain = appConfig.additionalEntries
.filter(entry => typeof entry === "string")
.map(filename => path.resolve(appRoot, filename));

const separateBundles = appConfig.additionalEntries.filter(entry => typeof entry === "object");
const entries = Object.assign(
{ main: [appMain, ...bundledWithMain] },
separateBundles.reduce((obj, entry) =>
Object.assign(obj, { [entry.output]: path.resolve(appRoot, entry.input) }),
{})
);

const additionalFiles = separateBundles
.map(entry => path.resolve(appRoot, entry.input))
.concat(bundledWithMain);

return {
devtool: 'source-map',
resolve: {
extensions: ['', '.ts', '.js'],
root: path.resolve(projectRoot, `./${sourceDir}`)
root: appRoot
},
context: path.resolve(__dirname, './'),
entry: {
main: [path.resolve(projectRoot, `./${sourceDir}/main.ts`)],
polyfills: path.resolve(projectRoot, `./${sourceDir}/polyfills.ts`)
},
entry: entries,
output: {
path: path.resolve(projectRoot, './dist'),
path: path.resolve(projectRoot, appConfig.outDir),
filename: '[name].bundle.js'
},
module: {
Expand All @@ -27,8 +44,8 @@ export function getWebpackCommonConfig(projectRoot: string, sourceDir: string) {
test: /\.js$/,
loader: 'source-map-loader',
exclude: [
path.resolve(projectRoot, 'node_modules/rxjs'),
path.resolve(projectRoot, 'node_modules/@angular'),
path.resolve(appRoot, 'node_modules/rxjs'),
path.resolve(appRoot, 'node_modules/@angular'),
]
}
],
Expand All @@ -40,7 +57,7 @@ export function getWebpackCommonConfig(projectRoot: string, sourceDir: string) {
loader: 'awesome-typescript-loader',
query: {
useForkChecker: true,
tsconfig: path.resolve(projectRoot, `./${sourceDir}/tsconfig.json`)
tsconfig: path.resolve(appRoot, appConfig.tsconfig)
}
},
{
Expand All @@ -49,23 +66,47 @@ export function getWebpackCommonConfig(projectRoot: string, sourceDir: string) {
],
exclude: [/\.(spec|e2e)\.ts$/]
},
{ test: /\.json$/, loader: 'json-loader'},
{ test: /\.css$/, loaders: ['raw-loader', 'postcss-loader'] },
{ test: /\.styl$/, loaders: ['raw-loader', 'postcss-loader', 'stylus-loader'] },
{ test: /\.less$/, loaders: ['raw-loader', 'postcss-loader', 'less-loader'] },
{ test: /\.scss$|\.sass$/, loaders: ['raw-loader', 'postcss-loader', 'sass-loader'] },
{ test: /\.(jpg|png)$/, loader: 'url-loader?limit=128000'},
{ test: /\.html$/, loader: 'raw-loader' }

// in main, load css as raw text
       { exclude: additionalFiles, test: /\.css$/, loaders: ['raw-loader', 'postcss-loader'] },
       { exclude: additionalFiles, test: /\.styl$/, loaders: ['raw-loader', 'postcss-loader', 'stylus-loader'] },
       { exclude: additionalFiles, test: /\.less$/, loaders: ['raw-loader', 'postcss-loader', 'less-loader'] },
       { exclude: additionalFiles, test: /\.scss$|\.sass$/, loaders: ['raw-loader', 'postcss-loader', 'sass-loader'] },

// outside of main, load it via style-loader
       { include: additionalFiles, test: /\.css$/, loaders: ['style-loader', 'css-loader', 'postcss-loader'] },
       { include: additionalFiles, test: /\.styl$/, loaders: ['style-loader', 'css-loader', 'postcss-loader', 'stylus-loader'] },
       { include: additionalFiles, test: /\.less$/, loaders: ['style-loader', 'css-loader', 'postcss-loader', 'less-loader'] },
       { include: additionalFiles, test: /\.scss$|\.sass$/, loaders: ['style-loader', 'css-loader', 'postcss-loader', 'sass-loader'] },

       { test: /\.json$/, loader: 'json-loader' },
       { test: /\.(jpg|png)$/, loader: 'url-loader?limit=128000' },
       { test: /\.html$/, loader: 'raw-loader' },

       { test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, loader: 'url?limit=10000&mimetype=application/font-woff' },
       { test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url?limit=10000&mimetype=application/octet-stream' },
       { test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file' },
       { test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: 'url?limit=10000&mimetype=image/svg+xml' }
]
},
plugins: [
new ForkCheckerPlugin(),
new HtmlWebpackPlugin({
template: path.resolve(projectRoot, `./${sourceDir}/index.html`),
template: path.resolve(appRoot, appConfig.index),
chunksSortMode: 'dependency'
}),
new webpack.NormalModuleReplacementPlugin(
// escape the path to make a regex
// TODO: this isn't working!
new RegExp(path.resolve(appRoot, appConfig.environments.source)
.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&")),
path.resolve(appRoot, appConfig.environments[environment])
),
new webpack.optimize.CommonsChunkPlugin({
name: ['polyfills']
name: separateBundles
.concat('main')
.map(bundle => bundle.output)
.reverse()
}),
new webpack.optimize.CommonsChunkPlugin({
minChunks: Infinity,
Expand All @@ -74,9 +115,9 @@ export function getWebpackCommonConfig(projectRoot: string, sourceDir: string) {
sourceMapFilename: 'inline.map'
}),
new CopyWebpackPlugin([{
context: path.resolve(projectRoot, './public'),
context: path.resolve(appRoot, appConfig.assets),
from: '**/*',
to: path.resolve(projectRoot, './dist')
to: path.resolve(projectRoot, appConfig.outDir, appConfig.assets)
}])
],
node: {
Expand All @@ -89,3 +130,4 @@ export function getWebpackCommonConfig(projectRoot: string, sourceDir: string) {
}
}
};

4 changes: 2 additions & 2 deletions addon/ng2/models/webpack-build-development.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { CliConfig } from './config';
const path = require('path')

export const getWebpackDevConfigPartial = function(projectRoot: string, sourceDir: string) {
export const getWebpackDevConfigPartial = function(projectRoot: string, appConfig: any) {
return {
debug: true,
devtool: 'source-map',
Expand All @@ -14,7 +14,7 @@ export const getWebpackDevConfigPartial = function(projectRoot: string, sourceDi
tslint: {
emitErrors: false,
failOnHint: false,
resourcePath: path.resolve(projectRoot, `./${sourceDir}`)
resourcePath: path.resolve(projectRoot, appConfig.root)
},
node: {
fs: 'empty',
Expand Down
14 changes: 8 additions & 6 deletions addon/ng2/models/webpack-build-mobile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,25 @@ import * as CopyWebpackPlugin from 'copy-webpack-plugin';
import { PrerenderWebpackPlugin } from '../utilities/prerender-webpack-plugin.ts';
import { CliConfig } from './config';

export const getWebpackMobileConfigPartial = function (projectRoot: string, sourceDir: string) {
export const getWebpackMobileConfigPartial = function (projectRoot: string, appConfig: any) {
// Hardcoded files and paths here should be part of appConfig when
// reworking the mobile app functionality
return {
plugins: [
new CopyWebpackPlugin([
{from: path.resolve(projectRoot, `./${sourceDir}/icons`), to: path.resolve(projectRoot, './dist/icons')},
{from: path.resolve(projectRoot, `./${sourceDir}/manifest.webapp`), to: path.resolve(projectRoot, './dist')}
{from: path.resolve(projectRoot, appConfig.root, 'icons'), to: path.resolve(projectRoot, appConfig.outDir, 'icons')},
{from: path.resolve(projectRoot, appConfig.root, 'manifest.webapp'), to: path.resolve(projectRoot, appConfig.outDir)}
]),
new PrerenderWebpackPlugin({
templatePath: 'index.html',
configPath: path.resolve(projectRoot, `./${sourceDir}/main-app-shell.ts`),
appPath: path.resolve(projectRoot, `./${sourceDir}`)
configPath: path.resolve(projectRoot, appConfig.root, 'main-app-shell.ts'),
appPath: path.resolve(projectRoot, appConfig.root)
})
]
}
};

export const getWebpackMobileProdConfigPartial = function (projectRoot: string, sourceDir: string) {
export const getWebpackMobileProdConfigPartial = function (projectRoot: string, appConfig: any) {
return {
entry: {
'sw-install': path.resolve(__dirname, '../utilities/sw-install.js')
Expand Down
4 changes: 2 additions & 2 deletions addon/ng2/models/webpack-build-production.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import * as CompressionPlugin from 'compression-webpack-plugin';
import * as webpack from 'webpack';
import { CliConfig } from './config';

export const getWebpackProdConfigPartial = function(projectRoot: string, sourceDir: string) {
export const getWebpackProdConfigPartial = function(projectRoot: string, appConfig: any) {
return {
debug: false,
devtool: 'source-map',
Expand Down Expand Up @@ -36,7 +36,7 @@ export const getWebpackProdConfigPartial = function(projectRoot: string, sourceD
tslint: {
emitErrors: true,
failOnHint: true,
resourcePath: path.resolve(projectRoot, `./${sourceDir}`)
resourcePath: path.resolve(projectRoot, appConfig.root)
},
htmlLoader: {
minimize: true,
Expand Down
15 changes: 9 additions & 6 deletions addon/ng2/models/webpack-build-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,19 @@
const path = require('path');
const webpack = require('webpack');

const getWebpackTestConfig = function(projectRoot, sourceDir) {
const getWebpackTestConfig = function(projectRoot, appConfig) {

const appRoot = path.resolve(projectRoot, appConfig.root);

return {
devtool: 'inline-source-map',
context: path.resolve(__dirname, './'),
resolve: {
extensions: ['', '.ts', '.js'],
root: path.resolve(projectRoot, `./${sourceDir}`)
root: appRoot
},
entry: {
test: path.resolve(projectRoot, `./${sourceDir}/test.ts`)
test: path.resolve(appRoot, appConfig.test)
},
output: {
path: './dist.test',
Expand Down Expand Up @@ -43,7 +46,7 @@ const getWebpackTestConfig = function(projectRoot, sourceDir) {
{
loader: 'awesome-typescript-loader',
query: {
tsconfig: path.resolve(projectRoot, `./${sourceDir}/tsconfig.json`),
tsconfig: path.resolve(appRoot, appConfig.tsconfig),
module: 'commonjs',
target: 'es5',
useForkChecker: true
Expand All @@ -61,7 +64,7 @@ const getWebpackTestConfig = function(projectRoot, sourceDir) {
{ test: /\.less$/, loaders: ['raw-loader', 'postcss-loader', 'less-loader'] },
{ test: /\.scss$|\.sass$/, loaders: ['raw-loader', 'postcss-loader', 'sass-loader'] },
{ test: /\.(jpg|png)$/, loader: 'url-loader?limit=128000' },
{ test: /\.html$/, loader: 'raw-loader', exclude: [path.resolve(projectRoot, `./${sourceDir}/index.html`)] }
{ test: /\.html$/, loader: 'raw-loader', exclude: [path.resolve(appRoot, appConfig.index)] }
],
postLoaders: [
{
Expand All @@ -83,7 +86,7 @@ const getWebpackTestConfig = function(projectRoot, sourceDir) {
tslint: {
emitErrors: false,
failOnHint: false,
resourcePath: `./${sourceDir}`
resourcePath: `./${appConfig.root}`
},
node: {
fs: 'empty',
Expand Down
22 changes: 6 additions & 16 deletions addon/ng2/models/webpack-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import * as path from 'path';
import * as fs from 'fs';
import * as webpackMerge from 'webpack-merge';
import { CliConfig } from './config';
import { NgCliEnvironmentPlugin } from '../utilities/environment-plugin';
import {
getWebpackCommonConfig,
getWebpackDevConfigPartial,
Expand All @@ -18,33 +17,24 @@ export class NgCliWebpackConfig {
private webpackDevConfigPartial: any;
private webpackProdConfigPartial: any;
private webpackBaseConfig: any;
private webpackMaterialConfig: any;
private webpackMaterialE2EConfig: any;
private webpackMobileConfigPartial: any;
private webpackMobileProdConfigPartial: any;

constructor(public ngCliProject: any, public target: string, public environment: string) {
const sourceDir = CliConfig.fromProject().defaults.sourceDir;
const appConfig = CliConfig.fromProject().apps[0];

const environmentPath = `./${sourceDir}/app/environments/environment.${environment}.ts`;

this.webpackBaseConfig = getWebpackCommonConfig(this.ngCliProject.root, sourceDir);
this.webpackDevConfigPartial = getWebpackDevConfigPartial(this.ngCliProject.root, sourceDir);
this.webpackProdConfigPartial = getWebpackProdConfigPartial(this.ngCliProject.root, sourceDir);
this.webpackBaseConfig = getWebpackCommonConfig(this.ngCliProject.root, environment, appConfig);
this.webpackDevConfigPartial = getWebpackDevConfigPartial(this.ngCliProject.root, appConfig);
this.webpackProdConfigPartial = getWebpackProdConfigPartial(this.ngCliProject.root, appConfig);

if (CliConfig.fromProject().apps[0].mobile){
this.webpackMobileConfigPartial = getWebpackMobileConfigPartial(this.ngCliProject.root, sourceDir);
this.webpackMobileProdConfigPartial = getWebpackMobileProdConfigPartial(this.ngCliProject.root, sourceDir);
this.webpackMobileConfigPartial = getWebpackMobileConfigPartial(this.ngCliProject.root, appConfig);
this.webpackMobileProdConfigPartial = getWebpackMobileProdConfigPartial(this.ngCliProject.root, appConfig);
this.webpackBaseConfig = webpackMerge(this.webpackBaseConfig, this.webpackMobileConfigPartial);
this.webpackProdConfigPartial = webpackMerge(this.webpackProdConfigPartial, this.webpackMobileProdConfigPartial);
}

this.generateConfig();
this.config.plugins.unshift(new NgCliEnvironmentPlugin({
path: path.resolve(this.ngCliProject.root, `./${sourceDir}/app/environments/`),
src: 'environment.ts',
dest: `environment.${this.environment}.ts`
}));
}

generateConfig(): void {
Expand Down
Loading

0 comments on commit dc1f1c3

Please sign in to comment.