From 4d99072876e949b83b7cec81b62289349e2de165 Mon Sep 17 00:00:00 2001 From: Seth Davenport Date: Sun, 23 Oct 2016 22:21:21 -0400 Subject: [PATCH] feat(autoprefixer) Hook up autoprefixer for less, scss, and css. [Autoprefixer](https://github.com/postcss/autoprefixer) is a tool that uses data from caniuse.com to add vendor prefixes for styles that need them. It saves developers from having to manually prefix things, and is widely used these days. Since it's available as a postcss plugin, it makes sense to inlcude it in the angular-cli build step by default. This implementation uses the default browser targeting settings: last two versions, or whatever's in the user's project's [browserslist](https://github.com/ai/browserslist). Closes #1512. --- packages/angular-cli/models/webpack-build-common.ts | 9 ++++++++- tests/e2e/tests/build/styles/css.ts | 7 ++++++- tests/e2e/tests/build/styles/less.ts | 8 ++++++++ tests/e2e/tests/build/styles/scss.ts | 8 ++++++++ 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/packages/angular-cli/models/webpack-build-common.ts b/packages/angular-cli/models/webpack-build-common.ts index aae14af6663c..2726873ff888 100644 --- a/packages/angular-cli/models/webpack-build-common.ts +++ b/packages/angular-cli/models/webpack-build-common.ts @@ -4,6 +4,7 @@ import {GlobCopyWebpackPlugin} from '../plugins/glob-copy-webpack-plugin'; import {BaseHrefWebpackPlugin} from '@angular-cli/base-href-webpack'; const HtmlWebpackPlugin = require('html-webpack-plugin'); +const autoprefixer = require('autoprefixer'); export function getWebpackCommonConfig( @@ -131,7 +132,13 @@ export function getWebpackCommonConfig( new GlobCopyWebpackPlugin({ patterns: appConfig.assets, globOptions: {cwd: appRoot, dot: true, ignore: '**/.gitkeep'} - }) + }), + new webpack.LoaderOptionsPlugin({ + test: /\.(css|scss|sass|less|styl)$/, + options: { + postcss: [ autoprefixer() ] + }, + }), ], node: { fs: 'empty', diff --git a/tests/e2e/tests/build/styles/css.ts b/tests/e2e/tests/build/styles/css.ts index aa081ef1f45c..7d49e5e94ba9 100644 --- a/tests/e2e/tests/build/styles/css.ts +++ b/tests/e2e/tests/build/styles/css.ts @@ -8,6 +8,8 @@ export default function() { @import './imported-styles.css'; body { background-color: blue; } + + div { flex: 1 } `, 'src/imported-styles.css': ` p { background-color: red; } @@ -15,5 +17,8 @@ export default function() { }) .then(() => ng('build')) .then(() => expectFileToMatch('dist/styles.bundle.js', 'body { background-color: blue; }')) - .then(() => expectFileToMatch('dist/styles.bundle.js', 'p { background-color: red; }')); + .then(() => expectFileToMatch('dist/styles.bundle.js', 'p { background-color: red; }')) + .then(() => expectFileToMatch( + 'dist/styles.bundle.js', + 'div { -webkit-box-flex: 1; -ms-flex: 1; flex: 1 }')); } diff --git a/tests/e2e/tests/build/styles/less.ts b/tests/e2e/tests/build/styles/less.ts index 279742be2ceb..13df8375f962 100644 --- a/tests/e2e/tests/build/styles/less.ts +++ b/tests/e2e/tests/build/styles/less.ts @@ -22,6 +22,8 @@ export default function() { background: #fff; } } + + div { flex: 1 } ` }) .then(() => deleteFile('src/app/app.component.css')) @@ -29,5 +31,11 @@ export default function() { './app.component.css', './app.component.less')) .then(() => ng('build')) .then(() => expectFileToMatch('dist/main.bundle.js', /.outer.*.inner.*background:\s*#[fF]+/)) + .then(() => expectFileToMatch( + 'dist/main.bundle.js', + '-webkit-box-flex: 1')) + .then(() => expectFileToMatch( + 'dist/main.bundle.js', + '-ms-flex: 1')) .then(() => moveFile('src/app/app.component.less', 'src/app/app.component.css')); } diff --git a/tests/e2e/tests/build/styles/scss.ts b/tests/e2e/tests/build/styles/scss.ts index 52d7d46fbd42..f8770edcf2af 100644 --- a/tests/e2e/tests/build/styles/scss.ts +++ b/tests/e2e/tests/build/styles/scss.ts @@ -24,6 +24,8 @@ export default function() { background: #def; } } + + div { flex: 1 } `, 'src/app/app.component.partial.scss': stripIndents` .partial { @@ -37,5 +39,11 @@ export default function() { .then(() => ng('build')) .then(() => expectFileToMatch('dist/main.bundle.js', /\.outer.*\.inner.*background.*#def/)) .then(() => expectFileToMatch('dist/main.bundle.js', /\.partial.*\.inner.*background.*#def/)) + .then(() => expectFileToMatch( + 'dist/main.bundle.js', + '-webkit-box-flex: 1')) + .then(() => expectFileToMatch( + 'dist/main.bundle.js', + '-ms-flex: 1')) .then(() => moveFile('src/app/app.component.scss', 'src/app/app.component.css')); }