diff --git a/packages/@angular/cli/blueprints/ng2/files/karma.conf.js b/packages/@angular/cli/blueprints/ng2/files/karma.conf.js index 0aa416f5d560..328acb70f395 100644 --- a/packages/@angular/cli/blueprints/ng2/files/karma.conf.js +++ b/packages/@angular/cli/blueprints/ng2/files/karma.conf.js @@ -29,7 +29,6 @@ module.exports = function (config) { fixWebpackSourcePaths: true }, angularCli: { - config: './.angular-cli.json', environment: 'dev' }, reporters: config.angularCli && config.angularCli.codeCoverage diff --git a/packages/@angular/cli/models/webpack-config.ts b/packages/@angular/cli/models/webpack-config.ts index 4c5765b979ec..64173c60eb4b 100644 --- a/packages/@angular/cli/models/webpack-config.ts +++ b/packages/@angular/cli/models/webpack-config.ts @@ -2,6 +2,7 @@ const webpackMerge = require('webpack-merge'); import { CliConfig } from './config'; import { BuildOptions } from './build-options'; import { + getBrowserConfig, getCommonConfig, getDevConfig, getProdConfig, @@ -20,6 +21,7 @@ export interface WebpackConfigOptions { export class NgCliWebpackConfig { public config: any; + public wco: WebpackConfigOptions; constructor(buildOptions: BuildOptions) { this.validateBuildOptions(buildOptions); @@ -32,26 +34,29 @@ export class NgCliWebpackConfig { buildOptions = this.addTargetDefaults(buildOptions); buildOptions = this.mergeConfigs(buildOptions, appConfig); - const wco: WebpackConfigOptions = { projectRoot, buildOptions, appConfig }; + this.wco = { projectRoot, buildOptions, appConfig }; + } + public buildConfig() { let webpackConfigs = [ - getCommonConfig(wco), - getStylesConfig(wco), - this.getTargetConfig(wco) + getCommonConfig(this.wco), + getBrowserConfig(this.wco), + getStylesConfig(this.wco), + this.getTargetConfig(this.wco) ]; - if (appConfig.main || appConfig.polyfills) { - const typescriptConfigPartial = buildOptions.aot - ? getAotConfig(wco) - : getNonAotConfig(wco); + if (this.wco.appConfig.main || this.wco.appConfig.polyfills) { + const typescriptConfigPartial = this.wco.buildOptions.aot + ? getAotConfig(this.wco) + : getNonAotConfig(this.wco); webpackConfigs.push(typescriptConfigPartial); } - // add style config this.config = webpackMerge(webpackConfigs); + return this.config; } - getTargetConfig(webpackConfigOptions: WebpackConfigOptions): any { + public getTargetConfig(webpackConfigOptions: WebpackConfigOptions): any { switch (webpackConfigOptions.buildOptions.target) { case 'development': return getDevConfig(webpackConfigOptions); @@ -61,14 +66,15 @@ export class NgCliWebpackConfig { } // Validate build options - private validateBuildOptions(buildOptions: BuildOptions) { + public validateBuildOptions(buildOptions: BuildOptions) { + buildOptions.target = buildOptions.target || 'development'; if (buildOptions.target !== 'development' && buildOptions.target !== 'production') { throw new Error("Invalid build target. Only 'development' and 'production' are available."); } } // Fill in defaults for build targets - private addTargetDefaults(buildOptions: BuildOptions) { + public addTargetDefaults(buildOptions: BuildOptions) { const targetDefaults: any = { development: { environment: 'dev', @@ -89,7 +95,7 @@ export class NgCliWebpackConfig { } // Fill in defaults from .angular-cli.json - private mergeConfigs(buildOptions: BuildOptions, appConfig: any) { + public mergeConfigs(buildOptions: BuildOptions, appConfig: any) { const mergeableOptions = { outputPath: appConfig.outDir, deployUrl: appConfig.deployUrl @@ -98,7 +104,7 @@ export class NgCliWebpackConfig { return Object.assign({}, mergeableOptions, buildOptions); } - private addAppConfigDefaults(appConfig: any) { + public addAppConfigDefaults(appConfig: any) { const appConfigDefaults: any = { scripts: [], styles: [] diff --git a/packages/@angular/cli/models/webpack-configs/browser.ts b/packages/@angular/cli/models/webpack-configs/browser.ts new file mode 100644 index 000000000000..b85670529389 --- /dev/null +++ b/packages/@angular/cli/models/webpack-configs/browser.ts @@ -0,0 +1,51 @@ +import * as webpack from 'webpack'; +import * as path from 'path'; +const HtmlWebpackPlugin = require('html-webpack-plugin'); + +import { packageChunkSort } from '../../utilities/package-chunk-sort'; +import { BaseHrefWebpackPlugin } from '../../lib/base-href-webpack'; +import { extraEntryParser, lazyChunksFilter } from './utils'; +import { WebpackConfigOptions } from '../webpack-config'; + + +export function getBrowserConfig(wco: WebpackConfigOptions) { + const { projectRoot, buildOptions, appConfig } = wco; + + const appRoot = path.resolve(projectRoot, appConfig.root); + const nodeModules = path.resolve(projectRoot, 'node_modules'); + + let extraPlugins: any[] = []; + + // figure out which are the lazy loaded entry points + const lazyChunks = lazyChunksFilter([ + ...extraEntryParser(appConfig.scripts, appRoot, 'scripts'), + ...extraEntryParser(appConfig.styles, appRoot, 'styles') + ]); + + if (buildOptions.vendorChunk) { + extraPlugins.push(new webpack.optimize.CommonsChunkPlugin({ + name: 'vendor', + chunks: ['main'], + minChunks: (module: any) => module.resource && module.resource.startsWith(nodeModules) + })); + } + + return { + plugins: [ + new HtmlWebpackPlugin({ + template: path.resolve(appRoot, appConfig.index), + filename: path.resolve(buildOptions.outputPath, appConfig.index), + chunksSortMode: packageChunkSort(appConfig), + excludeChunks: lazyChunks, + xhtml: true + }), + new BaseHrefWebpackPlugin({ + baseHref: buildOptions.baseHref + }), + new webpack.optimize.CommonsChunkPlugin({ + minChunks: Infinity, + name: 'inline' + }) + ].concat(extraPlugins) + }; +} diff --git a/packages/@angular/cli/models/webpack-configs/common.ts b/packages/@angular/cli/models/webpack-configs/common.ts index f561b50133b7..11c6409e77ab 100644 --- a/packages/@angular/cli/models/webpack-configs/common.ts +++ b/packages/@angular/cli/models/webpack-configs/common.ts @@ -1,13 +1,10 @@ import * as webpack from 'webpack'; import * as path from 'path'; import { GlobCopyWebpackPlugin } from '../../plugins/glob-copy-webpack-plugin'; -import { packageChunkSort } from '../../utilities/package-chunk-sort'; -import { BaseHrefWebpackPlugin } from '../../lib/base-href-webpack'; -import { extraEntryParser, lazyChunksFilter, getOutputHashFormat } from './utils'; +import { extraEntryParser, getOutputHashFormat } from './utils'; import { WebpackConfigOptions } from '../webpack-config'; const ProgressPlugin = require('webpack/lib/ProgressPlugin'); -const HtmlWebpackPlugin = require('html-webpack-plugin'); /** @@ -32,12 +29,6 @@ export function getCommonConfig(wco: WebpackConfigOptions) { let extraRules: any[] = []; let entryPoints: { [key: string]: string[] } = {}; - // figure out which are the lazy loaded entry points - const lazyChunks = lazyChunksFilter([ - ...extraEntryParser(appConfig.scripts, appRoot, 'scripts'), - ...extraEntryParser(appConfig.styles, appRoot, 'styles') - ]); - if (appConfig.main) { entryPoints['main'] = [path.resolve(appRoot, appConfig.main)]; } @@ -56,19 +47,10 @@ export function getCommonConfig(wco: WebpackConfigOptions) { // add entry points and lazy chunks globalScripts.forEach(script => { let scriptPath = `script-loader!${script.path}`; - if (script.lazy) { lazyChunks.push(script.entry); } entryPoints[script.entry] = (entryPoints[script.entry] || []).concat(scriptPath); }); } - if (buildOptions.vendorChunk) { - extraPlugins.push(new webpack.optimize.CommonsChunkPlugin({ - name: 'vendor', - chunks: ['main'], - minChunks: (module: any) => module.resource && module.resource.startsWith(nodeModules) - })); - } - // process asset entries if (appConfig.assets) { extraPlugins.push(new GlobCopyWebpackPlugin({ @@ -111,21 +93,7 @@ export function getCommonConfig(wco: WebpackConfigOptions) { ].concat(extraRules) }, plugins: [ - new webpack.NoEmitOnErrorsPlugin(), - new HtmlWebpackPlugin({ - template: path.resolve(appRoot, appConfig.index), - filename: path.resolve(buildOptions.outputPath, appConfig.index), - chunksSortMode: packageChunkSort(appConfig), - excludeChunks: lazyChunks, - xhtml: true - }), - new BaseHrefWebpackPlugin({ - baseHref: buildOptions.baseHref - }), - new webpack.optimize.CommonsChunkPlugin({ - minChunks: Infinity, - name: 'inline' - }) + new webpack.NoEmitOnErrorsPlugin() ].concat(extraPlugins), node: { fs: 'empty', diff --git a/packages/@angular/cli/models/webpack-configs/index.ts b/packages/@angular/cli/models/webpack-configs/index.ts index 64d0358482cf..7c985a1e093d 100644 --- a/packages/@angular/cli/models/webpack-configs/index.ts +++ b/packages/@angular/cli/models/webpack-configs/index.ts @@ -1,7 +1,9 @@ +export * from './browser'; export * from './common'; export * from './development'; export * from './production'; export * from './styles'; +export * from './test'; export * from './typescript'; export * from './utils'; export * from './xi18n'; diff --git a/packages/@angular/cli/models/webpack-configs/test.js b/packages/@angular/cli/models/webpack-configs/test.js deleted file mode 100644 index fdb986e7835c..000000000000 --- a/packages/@angular/cli/models/webpack-configs/test.js +++ /dev/null @@ -1,129 +0,0 @@ -// this config must be JS so that the karma plugin can load it - -const path = require('path'); -const webpack = require('webpack'); -const ngtools = require('@ngtools/webpack'); - - -const g = global; -const webpackLoader = g['angularCliIsLocal'] - ? g.angularCliPackages['@ngtools/webpack'].main - : '@ngtools/webpack'; - -const ProgressPlugin = require('webpack/lib/ProgressPlugin'); - - -/** - * Enumerate loaders and their dependencies from this file to let the dependency validator - * know they are used. - * - * require('source-map-loader') - * require('istanbul-instrumenter-loader') - * - */ - - -const getTestConfig = function (projectRoot, environment, appConfig, testConfig) { - - const appRoot = path.resolve(projectRoot, appConfig.root); - const extraRules = []; - const extraPlugins = []; - - if (testConfig.codeCoverage) { - extraRules.push({ - test: /\.(js|ts)$/, loader: 'istanbul-instrumenter-loader', - enforce: 'post', - exclude: [ - /\.(e2e|spec)\.ts$/, - /node_modules/ - ] - }); - } - - if (testConfig.progress) { - extraPlugins.push(new ProgressPlugin({ colors: true })); - } - - return { - devtool: testConfig.sourcemap ? 'inline-source-map' : 'eval', - context: projectRoot, - resolve: { - extensions: ['.ts', '.js'], - plugins: [ - new ngtools.PathsPlugin({ - tsConfigPath: path.resolve(appRoot, appConfig.tsconfig) - }) - ] - }, - entry: { - test: path.resolve(appRoot, appConfig.test) - }, - output: { - path: './dist.test', - filename: '[name].bundle.js' - }, - module: { - rules: [ - { - test: /\.js$/, - enforce: 'pre', - loader: 'source-map-loader', - exclude: [ - /node_modules/ - ] - }, - { - test: /\.ts$/, - loaders: [ - { - loader: webpackLoader, - query: { - tsConfigPath: path.resolve(appRoot, appConfig.tsconfig), - module: 'commonjs' - } - } - ], - exclude: [/\.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', exclude: [path.resolve(appRoot, appConfig.index)] } - ].concat(extraRules) - }, - plugins: [ - new webpack.SourceMapDevToolPlugin({ - filename: null, // if no value is provided the sourcemap is inlined - test: /\.(ts|js)($|\?)/i // process .js and .ts files only - }), - 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.environmentSource) - .replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&')), - path.resolve(appRoot, appConfig.environments[environment]) - ), - new webpack.ContextReplacementPlugin( - /angular(\\|\/)core(\\|\/)(esm(\\|\/)src|src)(\\|\/)linker/, - appRoot - ) - ].concat(extraPlugins), - node: { - fs: 'empty', - global: true, - crypto: 'empty', - tls: 'empty', - net: 'empty', - process: true, - module: false, - clearImmediate: false, - setImmediate: false - } - }; -} - -module.exports.getTestConfig = getTestConfig; diff --git a/packages/@angular/cli/models/webpack-configs/test.ts b/packages/@angular/cli/models/webpack-configs/test.ts new file mode 100644 index 000000000000..54061f231a91 --- /dev/null +++ b/packages/@angular/cli/models/webpack-configs/test.ts @@ -0,0 +1,49 @@ +import * as path from 'path'; +import * as webpack from 'webpack'; + +import { CliConfig } from '../config'; +import { WebpackTestOptions } from '../webpack-test-config'; + +/** + * Enumerate loaders and their dependencies from this file to let the dependency validator + * know they are used. + * + * require('istanbul-instrumenter-loader') + * + */ + + +export function getTestConfig(testConfig: WebpackTestOptions) { + + const configPath = CliConfig.configFilePath(); + const projectRoot = path.dirname(configPath); + const appConfig = CliConfig.fromProject().config.apps[0]; + const extraRules: any[] = []; + + if (testConfig.codeCoverage) { + extraRules.push({ + test: /\.(js|ts)$/, loader: 'istanbul-instrumenter-loader', + enforce: 'post', + exclude: [ + /\.(e2e|spec)\.ts$/, + /node_modules/ + ] + }); + } + + return { + devtool: testConfig.sourcemap ? 'inline-source-map' : 'eval', + entry: { + test: path.resolve(projectRoot, appConfig.root, appConfig.test) + }, + module: { + rules: [].concat(extraRules) + }, + plugins: [ + new webpack.SourceMapDevToolPlugin({ + filename: null, // if no value is provided the sourcemap is inlined + test: /\.(ts|js)($|\?)/i // process .js and .ts files only + }) + ] + }; +} diff --git a/packages/@angular/cli/models/webpack-configs/typescript.ts b/packages/@angular/cli/models/webpack-configs/typescript.ts index f461efe5a0d3..7d1afa63a74a 100644 --- a/packages/@angular/cli/models/webpack-configs/typescript.ts +++ b/packages/@angular/cli/models/webpack-configs/typescript.ts @@ -116,3 +116,27 @@ export const getAotConfig = function(wco: WebpackConfigOptions) { ] }; }; + +export const getNonAotTestConfig = function(wco: WebpackConfigOptions) { + return { + module: { + rules: [ + { + test: /\.ts$/, + loader: webpackLoader, + query: { module: 'commonjs' }, + exclude: [/\.(e2e)\.ts$/] + } + ] + }, + plugins: [ + _createAotPlugin(wco, { + exclude: [], + skipCodeGeneration: true, + compilerOptions: { + module: 'commonjs' + } + }), + ] + }; +}; diff --git a/packages/@angular/cli/models/webpack-test-config.ts b/packages/@angular/cli/models/webpack-test-config.ts new file mode 100644 index 000000000000..a2600fc22be9 --- /dev/null +++ b/packages/@angular/cli/models/webpack-test-config.ts @@ -0,0 +1,38 @@ +import * as webpack from 'webpack'; +const webpackMerge = require('webpack-merge'); + +import { BuildOptions } from './build-options'; +import { NgCliWebpackConfig } from './webpack-config'; +import { + getCommonConfig, + getStylesConfig, + getNonAotTestConfig, + getTestConfig +} from './webpack-configs'; + +export interface WebpackTestOptions extends BuildOptions { + codeCoverage?: boolean; +} +export class WebpackTestConfig extends NgCliWebpackConfig { + constructor(private testOptions: WebpackTestOptions) { + super(testOptions); + } + + public buildConfig() { + let webpackConfigs = [ + getCommonConfig(this.wco), + getStylesConfig(this.wco), + this.getTargetConfig(this.wco), + getNonAotTestConfig(this.wco), + getTestConfig(this.testOptions) + ]; + + this.config = webpackMerge(webpackConfigs); + + // Remove any instance of CommonsChunkPlugin, not needed with karma-webpack. + this.config.plugins = this.config.plugins.filter((plugin: any) => + !(plugin instanceof webpack.optimize.CommonsChunkPlugin)); + + return this.config; + } +} diff --git a/packages/@angular/cli/models/webpack-xi18n-config.ts b/packages/@angular/cli/models/webpack-xi18n-config.ts index 8338d5bf1052..d46ba6c3f48d 100644 --- a/packages/@angular/cli/models/webpack-xi18n-config.ts +++ b/packages/@angular/cli/models/webpack-xi18n-config.ts @@ -16,14 +16,16 @@ export class XI18nWebpackConfig extends NgCliWebpackConfig { public config: any; - constructor(extractOptions: XI18WebpackOptions) { - + constructor(public extractOptions: XI18WebpackOptions) { super({ target: 'development', verbose: extractOptions.verbose, progress: extractOptions.progress }); + super.buildConfig(); + } + public buildConfig() { const configPath = CliConfig.configFilePath(); const projectRoot = path.dirname(configPath); const appConfig = CliConfig.fromProject().config.apps[0]; @@ -31,9 +33,10 @@ export class XI18nWebpackConfig extends NgCliWebpackConfig { const extractI18nConfig = getWebpackExtractI18nConfig(projectRoot, appConfig, - extractOptions.genDir, - extractOptions.i18nFormat); + this.extractOptions.genDir, + this.extractOptions.i18nFormat); this.config = webpackMerge([this.config, extractI18nConfig]); + return this.config; } } diff --git a/packages/@angular/cli/plugins/karma.js b/packages/@angular/cli/plugins/karma.ts similarity index 70% rename from packages/@angular/cli/plugins/karma.js rename to packages/@angular/cli/plugins/karma.ts index c5f38afcd647..a7a155eadeb7 100644 --- a/packages/@angular/cli/plugins/karma.js +++ b/packages/@angular/cli/plugins/karma.ts @@ -1,9 +1,13 @@ -const path = require('path'); -const fs = require('fs'); +import * as path from 'path'; +import * as fs from 'fs'; -const getTestConfig = require('../models/webpack-configs/test').getTestConfig; +import { CliConfig } from '../models/config'; +import { Pattern } from './glob-copy-webpack-plugin'; +import { extraEntryParser } from '../models/webpack-configs/utils'; +import { WebpackTestConfig, WebpackTestOptions } from '../models/webpack-test-config'; -function isDirectory(path) { + +function isDirectory(path: string) { try { return fs.statSync(path).isDirectory(); } catch (_) { @@ -11,25 +15,20 @@ function isDirectory(path) { } } -const init = (config) => { - // load Angular CLI config - if (!config.angularCli || !config.angularCli.config) { - throw new Error('Missing \'angularCli.config\' entry in Karma config'); - } - const angularCliConfig = require(path.join(config.basePath, config.angularCli.config)); - const appConfig = angularCliConfig.apps[0]; +const init: any = (config: any) => { + const appConfig = CliConfig.fromProject().config.apps[0]; const appRoot = path.join(config.basePath, appConfig.root); - const environment = config.angularCli.environment || 'dev'; - const testConfig = { - codeCoverage: config.angularCli.codeCoverage || false, - sourcemap: config.angularCli.sourcemap, - progress: config.angularCli.progress - } + const testConfig: WebpackTestOptions = Object.assign({ + environment: 'dev', + codeCoverage: false, + sourcemap: true, + progress: true, + }, config.angularCli); // Add assets. This logic is mimics the one present in GlobCopyWebpackPlugin. if (appConfig.assets) { config.proxies = config.proxies || {}; - appConfig.assets.forEach(pattern => { + appConfig.assets.forEach((pattern: Pattern) => { // Convert all string patterns to Pattern type. pattern = typeof pattern === 'string' ? { glob: pattern } : pattern; // Add defaults. @@ -50,7 +49,7 @@ const init = (config) => { // The `files` entry serves the file from `/base/{asset.input}/{asset.glob}`. // We need to add a URL rewrite that exposes the asset as `/{asset.output}/{asset.glob}`. - let relativePath, proxyPath; + let relativePath: string, proxyPath: string; if (fs.existsSync(assetPath)) { relativePath = path.relative(config.basePath, assetPath); proxyPath = path.join(pattern.output, pattern.glob); @@ -66,8 +65,8 @@ const init = (config) => { }); } - // add webpack config - const webpackConfig = getTestConfig(config.basePath, environment, appConfig, testConfig); + // Add webpack config. + const webpackConfig = new WebpackTestConfig(testConfig).buildConfig(); const webpackMiddlewareConfig = { noInfo: true, // Hide webpack output because its noisy. stats: { // Also prevent chunk and module display output, cleaner look. Only emit errors. @@ -80,23 +79,22 @@ const init = (config) => { chunkModules: false }, watchOptions: { - poll: config.angularCli.poll + poll: testConfig.poll } }; config.webpack = Object.assign(webpackConfig, config.webpack); config.webpackMiddleware = Object.assign(webpackMiddlewareConfig, config.webpackMiddleware); - // replace the @angular/cli preprocessor with webpack+sourcemap + // Replace the @angular/cli preprocessor with webpack+sourcemap. Object.keys(config.preprocessors) .filter((file) => config.preprocessors[file].indexOf('@angular/cli') !== -1) .map((file) => config.preprocessors[file]) .map((arr) => arr.splice(arr.indexOf('@angular/cli'), 1, 'webpack', 'sourcemap')); - // Add global scripts + // Add global scripts. This logic mimics the one in webpack-configs/common. if (appConfig.scripts && appConfig.scripts.length > 0) { - const globalScriptPatterns = appConfig.scripts - .map(script => typeof script === 'string' ? { input: script } : script) + const globalScriptPatterns = extraEntryParser(appConfig.scripts, appRoot, 'scripts') // Neither renamed nor lazy scripts are currently supported .filter(script => !(script.output || script.lazy)) .map(script => ({ @@ -109,7 +107,7 @@ const init = (config) => { // Unshift elements onto the beginning of the files array. // It's important to not replace the array, because // karma already has a reference to the existing array. - Array.prototype.unshift.apply(config.files, globalScriptPatterns); + config.files.unshift(...globalScriptPatterns); } // Add polyfills file before everything else @@ -120,19 +118,20 @@ const init = (config) => { included: true, served: true, watched: true - } - Array.prototype.unshift.apply(config.files, [polyfillsPattern]); + }; config.preprocessors[polyfillsFile] = ['webpack', 'sourcemap']; + // Same as above. + config.files.unshift(polyfillsPattern); } -} +}; init.$inject = ['config']; -// dummy preprocessor, just to keep karma from showing a warning -const preprocessor = () => (content, file, done) => done(null, content); +// Dummy preprocessor, just to keep karma from showing a warning. +const preprocessor: any = () => (content: any, _file: string, done: any) => done(null, content); preprocessor.$inject = []; -// also export karma-webpack and karma-sourcemap-loader +// Also export karma-webpack and karma-sourcemap-loader. module.exports = Object.assign({ 'framework:@angular/cli': ['factory', init], 'preprocessor:@angular/cli': ['factory', preprocessor] diff --git a/packages/@angular/cli/tasks/build.ts b/packages/@angular/cli/tasks/build.ts index 30af991b0b9d..b99d2986af31 100644 --- a/packages/@angular/cli/tasks/build.ts +++ b/packages/@angular/cli/tasks/build.ts @@ -25,7 +25,7 @@ export default Task.extend({ } rimraf.sync(path.resolve(project.root, outputPath)); - const webpackConfig = new NgCliWebpackConfig(runTaskOptions).config; + const webpackConfig = new NgCliWebpackConfig(runTaskOptions).buildConfig(); const webpackCompiler = webpack(webpackConfig); const statsConfig = getWebpackStatsConfig(runTaskOptions.verbose); diff --git a/packages/@angular/cli/tasks/eject.ts b/packages/@angular/cli/tasks/eject.ts index 877150df0abe..61cf807d5592 100644 --- a/packages/@angular/cli/tasks/eject.ts +++ b/packages/@angular/cli/tasks/eject.ts @@ -406,7 +406,7 @@ export default Task.extend({ throw new SilentError ('Output path MUST not be project root directory!'); } - const webpackConfig = new NgCliWebpackConfig(runTaskOptions).config; + const webpackConfig = new NgCliWebpackConfig(runTaskOptions).buildConfig(); const serializer = new JsonWebpackSerializer(process.cwd(), outputPath); const output = serializer.serialize(webpackConfig); const webpackConfigStr = `${serializer.generateVariables()}\n\nmodule.exports = ${output};\n`; diff --git a/packages/@angular/cli/tasks/extract-i18n.ts b/packages/@angular/cli/tasks/extract-i18n.ts index 4fdea3d210a5..5ec1df3d5bcb 100644 --- a/packages/@angular/cli/tasks/extract-i18n.ts +++ b/packages/@angular/cli/tasks/extract-i18n.ts @@ -24,7 +24,7 @@ export const Extracti18nTask = Task.extend({ i18nFormat: runTaskOptions.i18nFormat, verbose: runTaskOptions.verbose, progress: runTaskOptions.progress - }).config; + }).buildConfig(); const webpackCompiler = webpack(config); diff --git a/packages/@angular/cli/tasks/serve.ts b/packages/@angular/cli/tasks/serve.ts index 480a1cc5af33..4e40b018b07a 100644 --- a/packages/@angular/cli/tasks/serve.ts +++ b/packages/@angular/cli/tasks/serve.ts @@ -39,7 +39,7 @@ export default Task.extend({ serveTaskOptions = Object.assign({}, serveDefaults, serveTaskOptions); - let webpackConfig = new NgCliWebpackConfig(serveTaskOptions).config; + let webpackConfig = new NgCliWebpackConfig(serveTaskOptions).buildConfig(); const serverAddress = url.format({ protocol: serveTaskOptions.ssl ? 'https' : 'http', diff --git a/plugins/karma.js b/plugins/karma.js index a46d7d5ac108..a678af857a38 100644 --- a/plugins/karma.js +++ b/plugins/karma.js @@ -1,4 +1,5 @@ // This file is necessary when using a linked @angular/cli to this repo, meaning that // require('@angular/cli/plugins/karma') will load this file, and we just forward to // the actual published file. +require('../lib/bootstrap-local'); module.exports = require('../packages/@angular/cli/plugins/karma'); diff --git a/plugins/webpack.js b/plugins/webpack.js index 959c93437d69..ef9f8960ed91 100644 --- a/plugins/webpack.js +++ b/plugins/webpack.js @@ -1,4 +1,4 @@ -// This file is necessary when using a linked angular-cli to this repo, meaning that +// This file is necessary when using a linked @angular/cli to this repo, meaning that // require('@angular/cli/plugins/webpack') will load this file, and we just forward to // the actual published file. require('../lib/bootstrap-local'); diff --git a/tests/e2e/tests/build/styles/imports.ts b/tests/e2e/tests/build/styles/imports.ts index 192761637d6c..5d7d71b7f077 100644 --- a/tests/e2e/tests/build/styles/imports.ts +++ b/tests/e2e/tests/build/styles/imports.ts @@ -1,6 +1,5 @@ import { writeMultipleFiles, - deleteFile, expectFileToMatch, replaceInFile } from '../../../utils/fs'; @@ -8,8 +7,12 @@ import { expectToFail } from '../../../utils/utils'; import { ng } from '../../../utils/process'; import { stripIndents } from 'common-tags'; import { updateJsonFile } from '../../../utils/project'; +import { getGlobalVariable } from '../../../utils/env'; export default function () { + // Disable parts of it in webpack tests. + const ejected = getGlobalVariable('argv').eject; + const extensions = ['css', 'scss', 'less', 'styl']; let promise = Promise.resolve(); @@ -56,6 +59,8 @@ export default function () { /.outer.*.inner.*background:\s*#[fF]+/)) .then(() => expectFileToMatch('dist/main.bundle.js', /h1.*background:\s*#000+/)) + // Also check imports work on ng test + .then(() => !ejected && ng('test', '--single-run')) // change files back .then(() => updateJsonFile('.angular-cli.json', configJson => { const app = configJson['apps'][0];