From 446564d0ac14f7571d01f9af5070c804ec93752e Mon Sep 17 00:00:00 2001 From: Adam Lee Date: Fri, 23 Dec 2016 16:28:59 -0500 Subject: [PATCH] feat(new): include app level import paths for style preprocessors - fixed linter errors - re-run build-config-interface - refactored variable names to preprocessors instead of style - use cliConfig to determine preprocessor for project --- packages/angular-cli/lib/config/schema.d.ts | 94 +++++++++++++++++++ packages/angular-cli/lib/config/schema.json | 15 +++ .../models/webpack-build-common.ts | 50 +++++++++- .../models/webpack-build-production.ts | 18 ---- packages/angular-cli/models/webpack-config.ts | 4 +- 5 files changed, 157 insertions(+), 24 deletions(-) create mode 100644 packages/angular-cli/lib/config/schema.d.ts diff --git a/packages/angular-cli/lib/config/schema.d.ts b/packages/angular-cli/lib/config/schema.d.ts new file mode 100644 index 000000000000..2e16384a0f3e --- /dev/null +++ b/packages/angular-cli/lib/config/schema.d.ts @@ -0,0 +1,94 @@ +export interface CliConfig { + /** + * The global configuration of the project. + */ + project?: { + version?: string; + name?: string; + }; + /** + * Properties of the different applications in this project. + */ + apps?: { + root?: string; + outDir?: string; + assets?: string | string[]; + deployUrl?: string; + index?: string; + main?: string; + test?: string; + tsconfig?: string; + prefix?: string; + mobile?: boolean; + /** + * Global styles to be included in the build. + */ + styles?: (string | { + [name: string]: any; + input?: string; + })[]; + /** + * Global scripts to be included in the build. + */ + scripts?: (string | { + [name: string]: any; + input?: string; + })[]; + /** + * Name and corresponding file for environment config. + */ + environments?: { + [name: string]: any; + }; + /** + * Options to pass to style loaders in webpack. + */ + webpackStyleLoaderOptions?: { + /** + * Paths to include. Paths will be resolved to project root. + */ + includePaths?: string[]; + }; + }[]; + /** + * Configuration reserved for installed third party addons. + */ + addons?: { + [name: string]: any; + }[]; + /** + * Configuration reserved for installed third party packages. + */ + packages?: { + [name: string]: any; + }[]; + e2e?: { + protractor?: { + config?: string; + }; + }; + test?: { + karma?: { + config?: string; + }; + }; + defaults?: { + styleExt?: string; + prefixInterfaces?: boolean; + poll?: number; + viewEncapsulation?: string; + changeDetection?: string; + inline?: { + style?: boolean; + template?: boolean; + }; + spec?: { + class?: boolean; + component?: boolean; + directive?: boolean; + module?: boolean; + pipe?: boolean; + service?: boolean; + }; + }; +} diff --git a/packages/angular-cli/lib/config/schema.json b/packages/angular-cli/lib/config/schema.json index c8626d1aac1d..1f11c4af2878 100644 --- a/packages/angular-cli/lib/config/schema.json +++ b/packages/angular-cli/lib/config/schema.json @@ -115,6 +115,21 @@ "description": "Name and corresponding file for environment config.", "type": "object", "additionalProperties": true + }, + "webpackStyleLoaderOptions": { + "description": "Options to pass to style loaders in webpack.", + "type": "object", + "properties": { + "includePaths": { + "description": "Paths to include. Paths will be resolved to project root.", + "type": "array", + "items": { + "type": "string" + }, + "default": [] + } + }, + "additionalProperties": false } }, "additionalProperties": false diff --git a/packages/angular-cli/models/webpack-build-common.ts b/packages/angular-cli/models/webpack-build-common.ts index 72c1d194ecbc..5cc5dda395b9 100644 --- a/packages/angular-cli/models/webpack-build-common.ts +++ b/packages/angular-cli/models/webpack-build-common.ts @@ -5,8 +5,10 @@ import { SuppressEntryChunksWebpackPlugin } from '../plugins/suppress-entry-chun import { packageChunkSort } from '../utilities/package-chunk-sort'; import { BaseHrefWebpackPlugin } from '@angular-cli/base-href-webpack'; import { extraEntryParser, makeCssLoaders, getOutputHashFormat } from './webpack-build-utils'; +import { CliConfig } from '../lib/config/schema.d'; const autoprefixer = require('autoprefixer'); +const postcssDiscardComments = require('postcss-discard-comments'); const ProgressPlugin = require('webpack/lib/ProgressPlugin'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const ExtractTextPlugin = require('extract-text-webpack-plugin'); @@ -28,6 +30,7 @@ export function getWebpackCommonConfig( projectRoot: string, environment: string, appConfig: any, + cliConfig: CliConfig, baseHref: string, sourcemap: boolean, vendorChunk: boolean, @@ -49,6 +52,39 @@ export function getWebpackCommonConfig( entryPoints['main'] = [path.resolve(appRoot, appConfig.main)]; } + // Configure webpack style loaders + + /** + * Base settings for webpack preprocessor loaders + * @type {Object} + */ + const basePreprocessorLoaderOptions = { + sourceMap: sourcemap, + }; + + // set default to base + let preprocessorLoaderOptions = basePreprocessorLoaderOptions; + + if (appConfig.webpackStyleLoaderOptions) { + if (appConfig.webpackStyleLoaderOptions.includePaths) { + // resolve paths relative to project root + let includePaths = appConfig.webpackStyleLoaderOptions.includePaths.map( + (includePath: string) => path.resolve(projectRoot, includePath) + ); + if (cliConfig.defaults.styleExt === 'styl' || cliConfig.defaults.styleExt === 'less') { + // stylus and less uses paths + preprocessorLoaderOptions = Object.assign({}, basePreprocessorLoaderOptions, { + paths: includePaths + }); + } else { + // sass use includePaths + preprocessorLoaderOptions = Object.assign({}, basePreprocessorLoaderOptions, { + includePaths + }); + } + } + } + // determine hashing format const hashFormat = getOutputHashFormat(outputHashing); @@ -191,11 +227,15 @@ export function getWebpackCommonConfig( new webpack.LoaderOptionsPlugin({ test: /\.(css|scss|sass|less|styl)$/, options: { - postcss: [autoprefixer()], - cssLoader: { sourceMap: sourcemap }, - sassLoader: { sourceMap: sourcemap }, - lessLoader: { sourceMap: sourcemap }, - stylusLoader: { sourceMap: sourcemap }, + postcss: [ + autoprefixer(), + // NOTE: Moved check here for prod build + ...(environment === 'prod' ? [postcssDiscardComments] : []) + ], + cssLoader: preprocessorLoaderOptions, + sassLoader: preprocessorLoaderOptions, + lessLoader: preprocessorLoaderOptions, + stylusLoader: preprocessorLoaderOptions, // context needed as a workaround https://github.com/jtangelder/sass-loader/issues/285 context: projectRoot, }, diff --git a/packages/angular-cli/models/webpack-build-production.ts b/packages/angular-cli/models/webpack-build-production.ts index ffb198cf9d41..aadaad21cb1b 100644 --- a/packages/angular-cli/models/webpack-build-production.ts +++ b/packages/angular-cli/models/webpack-build-production.ts @@ -1,8 +1,6 @@ import * as path from 'path'; import * as webpack from 'webpack'; import {CompressionPlugin} from '../lib/webpack/compression-plugin'; -const autoprefixer = require('autoprefixer'); -const postcssDiscardComments = require('postcss-discard-comments'); declare module 'webpack' { export interface LoaderOptionsPlugin {} @@ -37,22 +35,6 @@ export const getWebpackProdConfigPartial = function(projectRoot: string, test: /\.js$|\.html$|\.css$/, threshold: 10240 }), - // LoaderOptionsPlugin needs to be fully duplicated because webpackMerge will replace it. - new webpack.LoaderOptionsPlugin({ - test: /\.(css|scss|sass|less|styl)$/, - options: { - postcss: [ - autoprefixer(), - postcssDiscardComments - ], - cssLoader: { sourceMap: sourcemap }, - sassLoader: { sourceMap: sourcemap }, - lessLoader: { sourceMap: sourcemap }, - stylusLoader: { sourceMap: sourcemap }, - // context needed as a workaround https://github.com/jtangelder/sass-loader/issues/285 - context: projectRoot, - } - }) ] }; }; diff --git a/packages/angular-cli/models/webpack-config.ts b/packages/angular-cli/models/webpack-config.ts index 52929f5b1f8d..9b402545d17d 100644 --- a/packages/angular-cli/models/webpack-config.ts +++ b/packages/angular-cli/models/webpack-config.ts @@ -35,7 +35,8 @@ export class NgCliWebpackConfig { deployUrl?: string, outputHashing?: string ) { - const appConfig = CliConfig.fromProject().config.apps[0]; + const cliConfig = CliConfig.fromProject().config; + const appConfig = cliConfig.apps[0]; const projectRoot = this.ngCliProject.root; appConfig.outDir = outputDir || appConfig.outDir; @@ -45,6 +46,7 @@ export class NgCliWebpackConfig { projectRoot, environment, appConfig, + cliConfig, baseHref, sourcemap, vendorChunk,