diff --git a/gulpfile.ts b/gulpfile.ts index c855b00f1..3257badf1 100644 --- a/gulpfile.ts +++ b/gulpfile.ts @@ -17,6 +17,7 @@ gulp.task('build.dev', done => runSequence('clean.dev', 'tslint', 'build.assets.dev', + 'build.html_css', 'build.js.dev', 'build.index.dev', done)); @@ -44,7 +45,8 @@ gulp.task('build.prod', done => runSequence('clean.prod', 'tslint', 'build.assets.prod', - 'build.html_css.prod', + 'build.html_css', + 'copy.js.prod', 'build.js.prod', 'build.bundles', 'build.bundles.app', diff --git a/package.json b/package.json index 1fc454d9e..015583ff0 100644 --- a/package.json +++ b/package.json @@ -34,23 +34,26 @@ "license": "MIT", "devDependencies": { "async": "^1.4.2", + "autoprefixer": "^6.3.3", "browser-sync": "^2.11.1", "chalk": "^1.1.1", "connect": "^3.4.1", "connect-history-api-fallback": "^1.1.0", "connect-livereload": "^0.5.3", + "cssnano": "^3.5.2", "del": "^2.2.0", "event-stream": "^3.3.2", "express": "~4.13.1", "extend": "^3.0.0", "gulp": "^3.9.0", + "gulp-cached": "^1.1.0", "gulp-concat": "^2.5.2", - "gulp-cssnano": "^2.0.0", "gulp-filter": "^2.0.2", "gulp-inject": "^1.3.1", "gulp-inline-ng2-template": "^1.1.0", "gulp-load-plugins": "^0.10.0", "gulp-plumber": "~1.0.1", + "gulp-postcss": "^6.1.0", "gulp-shell": "~0.4.3", "gulp-sourcemaps": "~1.6.0", "gulp-template": "^3.0.0", @@ -74,6 +77,7 @@ "ng2lint": "0.0.9", "open": "0.0.5", "phantomjs-prebuilt": "^2.1.4", + "postcss-assets": "^4.0.1", "protractor": "^3.0.0", "remap-istanbul": "^0.5.1", "rimraf": "^2.5.2", diff --git a/src/app/components/toolbar.component.css b/src/app/components/toolbar.component.css index ce098ac81..39e7fef10 100644 --- a/src/app/components/toolbar.component.css +++ b/src/app/components/toolbar.component.css @@ -16,7 +16,7 @@ h1 { } more { - background: url("./assets/svg/more.svg"); + background: resolve("more.svg"); float: right; height: 24px; margin-top: 12px; diff --git a/tools/config.ts b/tools/config.ts index 8a91d66a7..f5d90b6a3 100644 --- a/tools/config.ts +++ b/tools/config.ts @@ -119,6 +119,20 @@ export const SYSTEM_BUILDER_CONFIG = { } }; +// ---------------- +// Autoprefixer configuration. +export const BROWSER_LIST = [ + 'ie >= 10', + 'ie_mob >= 10', + 'ff >= 30', + 'chrome >= 34', + 'safari >= 7', + 'opera >= 23', + 'ios >= 7', + 'android >= 4.4', + 'bb >= 10' +]; + // -------------- // Private. diff --git a/tools/manual_typings/autoprefixer.d.ts b/tools/manual_typings/autoprefixer.d.ts new file mode 100644 index 000000000..0daa68f43 --- /dev/null +++ b/tools/manual_typings/autoprefixer.d.ts @@ -0,0 +1,8 @@ +declare module 'autoprefixer' { + interface Options { + browsers?: string | string[] + } + function autoprefixer(options: Options): NodeJS.ReadWriteStream; + module autoprefixer {} + export = autoprefixer; +} diff --git a/tools/manual_typings/cssnano.d.ts b/tools/manual_typings/cssnano.d.ts new file mode 100644 index 000000000..552b04d14 --- /dev/null +++ b/tools/manual_typings/cssnano.d.ts @@ -0,0 +1,8 @@ +declare module 'cssnano' { + interface Options { + discardComments?: Object + } + function cssnano(options: Options): NodeJS.ReadWriteStream; + module cssnano {} + export = cssnano; +} diff --git a/tools/manual_typings/postcss-assets.d.ts b/tools/manual_typings/postcss-assets.d.ts new file mode 100644 index 000000000..f46e22271 --- /dev/null +++ b/tools/manual_typings/postcss-assets.d.ts @@ -0,0 +1,12 @@ +declare module 'postcss-assets' { + interface Options { + relative?: boolean, + cachebuster?: boolean | Function, + basePath?: string, + baseUrl?: string, + loadPaths: string[] + } + function postCSSAssets(options: Options): NodeJS.ReadWriteStream; + module postCSSAssets {} + export = postCSSAssets; +} diff --git a/tools/tasks/build.html_css.prod.ts b/tools/tasks/build.html_css.prod.ts deleted file mode 100644 index b1f0f0d8e..000000000 --- a/tools/tasks/build.html_css.prod.ts +++ /dev/null @@ -1,41 +0,0 @@ -import * as merge from 'merge-stream'; -import {join} from 'path'; -import { - APP_SRC, - TMP_DIR, - PROD_DEPENDENCIES, - CSS_PROD_BUNDLE, - CSS_DEST -} from '../config'; - -export = function buildJSDev(gulp, plugins) { - return function () { - - return merge(minifyComponentCss(), prepareTemplates(), processExternalCss()); - - function prepareTemplates() { - return gulp.src(join(APP_SRC, '**', '*.html')) - .pipe(gulp.dest(TMP_DIR)); - } - - function minifyComponentCss() { - return gulp.src([ - join(APP_SRC, '**', '*.css'), - '!' + join(APP_SRC, 'assets', '**', '*.css') - ]) - .pipe(plugins.cssnano()) - .pipe(gulp.dest(TMP_DIR)); - } - - function processExternalCss() { - return gulp.src(getExternalCss().map(r => r.src)) - .pipe(plugins.cssnano()) - .pipe(plugins.concat(CSS_PROD_BUNDLE)) - .pipe(gulp.dest(CSS_DEST)); - } - - function getExternalCss() { - return PROD_DEPENDENCIES.filter(d => /\.css$/.test(d.src)); - } - }; -}; diff --git a/tools/tasks/build.html_css.ts b/tools/tasks/build.html_css.ts new file mode 100644 index 000000000..08e8619de --- /dev/null +++ b/tools/tasks/build.html_css.ts @@ -0,0 +1,69 @@ +import * as merge from 'merge-stream'; +import * as autoprefixer from 'autoprefixer'; +import * as assets from 'postcss-assets'; +import * as cssnano from 'cssnano'; +import {join} from 'path'; +import { + APP_SRC, + TMP_DIR, + APP_ASSETS, + CSS_PROD_BUNDLE, + CSS_DEST, + APP_DEST, + BROWSER_LIST, + ENV +} from '../config'; + +const processors = [ + autoprefixer({ + browsers: BROWSER_LIST + }), + assets({ + basePath: APP_DEST, + loadPaths: [join('assets', '**', '*')] + }) +]; + +const isProd = ENV === 'prod'; + +if (isProd) { + processors.push( + cssnano({ + discardComments: {removeAll: true} + }) + ); +} + +export = function buildHTMLCSS(gulp, plugins) { + return function () { + + return merge(processComponentCss(), prepareTemplates(), processExternalCss()); + + function prepareTemplates() { + return gulp.src(join(APP_SRC, '**', '*.html')) + .pipe(gulp.dest(TMP_DIR)); + } + + function processComponentCss() { + return gulp.src([ + join(APP_SRC, '**', '*.css'), + '!' + join(APP_SRC, 'assets', '**', '*.css') + ]) + .pipe(isProd ? plugins.cached('process-component-css') : plugins.util.noop()) + .pipe(plugins.postcss(processors)) + .pipe(gulp.dest(isProd ? TMP_DIR: APP_DEST)); + } + + function processExternalCss() { + return gulp.src(getExternalCss().map(r => r.src)) + .pipe(isProd ? plugins.cached('process-external-css') : plugins.util.noop()) + .pipe(plugins.postcss(processors)) + .pipe(isProd ? plugins.concat(CSS_PROD_BUNDLE) : plugins.util.noop()) + .pipe(gulp.dest(CSS_DEST)); + } + + function getExternalCss() { + return APP_ASSETS.filter(d => /\.css$/.test(d.src)); + } + }; +}; diff --git a/tools/tasks/build.js.prod.ts b/tools/tasks/build.js.prod.ts index 12a79186f..0603eee0e 100644 --- a/tools/tasks/build.js.prod.ts +++ b/tools/tasks/build.js.prod.ts @@ -1,5 +1,5 @@ import {join} from 'path'; -import {APP_SRC, TMP_DIR} from '../config'; +import {TMP_DIR} from '../config'; import {templateLocals, tsProjectFn} from '../utils'; const INLINE_OPTIONS = { @@ -14,9 +14,7 @@ export = function buildJSProd(gulp, plugins) { let src = [ 'typings/browser.d.ts', 'tools/manual_typings/**/*.d.ts', - join(APP_SRC, '**/*.ts'), - '!' + join(APP_SRC, '**/*.spec.ts'), - '!' + join(APP_SRC, '**/*.e2e.ts') + join(TMP_DIR, '**/*.ts') ]; let result = gulp.src(src) .pipe(plugins.plumber()) diff --git a/tools/tasks/copy.js.prod.ts b/tools/tasks/copy.js.prod.ts new file mode 100644 index 000000000..18d921625 --- /dev/null +++ b/tools/tasks/copy.js.prod.ts @@ -0,0 +1,18 @@ +import {join} from 'path'; +import { + APP_SRC, + TMP_DIR +} from '../config'; + +export = function copyJSProd(gulp, plugins) { + return function () { + + let src = [ + join(APP_SRC, '**/*.ts'), + '!' + join(APP_SRC, '**/*.spec.ts'), + '!' + join(APP_SRC, '**/*.e2e.ts') + ]; + return gulp.src(src) + .pipe(gulp.dest(TMP_DIR)); + }; +};