diff --git a/package-lock.json b/package-lock.json index b610e9764283..7b749a2d4fc4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6053,14 +6053,12 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -6075,20 +6073,17 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -6205,8 +6200,7 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "ini": { "version": "1.3.5", @@ -6218,7 +6212,6 @@ "version": "1.0.0", "bundled": true, "dev": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -6233,7 +6226,6 @@ "version": "3.0.4", "bundled": true, "dev": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -6241,14 +6233,12 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "minipass": { "version": "2.2.4", "bundled": true, "dev": true, - "optional": true, "requires": { "safe-buffer": "^5.1.1", "yallist": "^3.0.0" @@ -6267,7 +6257,6 @@ "version": "0.5.1", "bundled": true, "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -6348,8 +6337,7 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -6361,7 +6349,6 @@ "version": "1.4.0", "bundled": true, "dev": true, - "optional": true, "requires": { "wrappy": "1" } @@ -6483,7 +6470,6 @@ "version": "1.0.2", "bundled": true, "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -9092,74 +9078,6 @@ "through2": "^2.0.0" } }, - "gulp-dart-sass": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/gulp-dart-sass/-/gulp-dart-sass-0.9.0.tgz", - "integrity": "sha512-WlWU9nm0ZIOedXDapeFPAIzAdb1I2ShsI/jve4WzXD4yvWy94kYm42wuD8sqPpe3TeixKzqKzg1YwesTPTU/UA==", - "dev": true, - "requires": { - "chalk": "^2.3.0", - "lodash.clonedeep": "^4.3.2", - "plugin-error": "^1.0.1", - "replace-ext": "^1.0.0", - "sass": "^1.3.2", - "strip-ansi": "^4.0.0", - "through2": "^2.0.0", - "vinyl-sourcemaps-apply": "^0.2.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, "gulp-dom": { "version": "0.9.17", "resolved": "https://registry.npmjs.org/gulp-dom/-/gulp-dom-0.9.17.tgz", @@ -9507,6 +9425,19 @@ "integrity": "sha512-nEuZB7/9i0IZ8AXORTizl2QLP9tcC9uWc/s329zElBLJw1CfOhmMXBxwVlCRKjDyrWuhVP0uBKl61KeQ32TiCg==", "dev": true }, + "gulp-sass": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/gulp-sass/-/gulp-sass-3.2.1.tgz", + "integrity": "sha512-UATbRpSDsyXCnpYSPBUEvdvtSEzksJs7/oQ0CujIpzKqKrO6vlnYwhX2UTsGrf4rNLwqlSSaM271It0uHYvJ3Q==", + "dev": true, + "requires": { + "gulp-util": "^3.0", + "lodash.clonedeep": "^4.3.2", + "node-sass": "^4.8.3", + "through2": "^2.0.0", + "vinyl-sourcemaps-apply": "^0.2.0" + } + }, "gulp-transform": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/gulp-transform/-/gulp-transform-2.0.0.tgz", @@ -16198,15 +16129,6 @@ } } }, - "sass": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.10.1.tgz", - "integrity": "sha512-tmDf4uHAifn3WHydSn7BZY1Q39zdXdfjDlzYYgN/CuwwYWVVOBhFCKeF3QUdJNP9LvSXl6lSft0YRhYSRLc5dA==", - "dev": true, - "requires": { - "chokidar": "^2.0.0" - } - }, "sass-graph": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.4.tgz", diff --git a/package.json b/package.json index 85d8f9a57733..19f107b55def 100644 --- a/package.json +++ b/package.json @@ -84,7 +84,6 @@ "gulp-cli": "^1.3.0", "gulp-connect": "^5.0.0", "gulp-conventional-changelog": "^1.1.3", - "gulp-dart-sass": "^0.9.0", "gulp-dom": "^0.9.17", "gulp-flatten": "^0.3.1", "gulp-highlight-files": "^0.0.5", @@ -92,6 +91,7 @@ "gulp-if": "^2.0.2", "gulp-markdown": "^1.2.0", "gulp-rename": "^1.2.2", + "gulp-sass": "^3.1.0", "gulp-transform": "^2.0.0", "gulp-util": "^3.0.8", "hammerjs": "^2.0.8", @@ -111,6 +111,7 @@ "minimatch": "^3.0.4", "minimist": "^1.2.0", "moment": "^2.18.1", + "node-sass": "^4.5.3", "parse5": "^5.0.0", "protractor": "^5.2.0", "request": "^2.83.0", @@ -119,7 +120,6 @@ "rollup-plugin-alias": "^1.4.0", "rollup-plugin-node-resolve": "^3.0.3", "run-sequence": "^1.2.2", - "sass": "^1.10.1", "scss-bundle": "^2.0.1-beta.7", "selenium-webdriver": "^3.6.0", "sorcery": "^0.10.0", diff --git a/src/demo-app/theme.scss b/src/demo-app/theme.scss index 27e33ea43a0d..7ac9474e574e 100644 --- a/src/demo-app/theme.scss +++ b/src/demo-app/theme.scss @@ -1,4 +1,5 @@ -@import '../../dist/packages/material/core/theming/all-theme'; +@import '../lib/core/theming/all-theme'; + // Plus imports for other components in your app. // Include the common styles for Angular Material. We include this here so that you only diff --git a/tools/gulp/tasks/development.ts b/tools/gulp/tasks/development.ts index ef8cd66d2365..c945e19d284c 100644 --- a/tools/gulp/tasks/development.ts +++ b/tools/gulp/tasks/development.ts @@ -1,8 +1,8 @@ -import {task} from 'gulp'; +import {task, dest} from 'gulp'; import {tsBuildTask, copyTask, serverTask} from '../util/task_helpers'; import {join} from 'path'; import { - buildConfig, copyFiles, buildScssTask, sequenceTask, watchFiles + buildConfig, copyFiles, buildScssPipeline, sequenceTask, watchFiles } from 'material2-build-tools'; import { cdkPackage, @@ -43,53 +43,35 @@ const vendorGlob = `+(${appVendors.join('|')})/**/*.+(html|css|js|map)`; /** Glob that matches all assets that need to be copied to the output. */ const assetsGlob = join(appDir, `**/*.+(html|css|svg|ico)`); -task(':watch:devapp', () => { - watchFiles(join(appDir, '**/*.ts'), [':build:devapp:ts']); - watchFiles(join(appDir, '**/*.scss'), [':build:devapp:scss']); - watchFiles(join(appDir, '**/*.html'), [':build:devapp:assets']); - - // Custom watchers for all packages that are used inside of the demo-app. This is necessary - // because we only want to build the changed package (using the build-no-bundles task). - watchFiles(join(cdkPackage.sourceDir, '**/*'), ['cdk:build-no-bundles']); - watchFiles(join(materialPackage.sourceDir, '**/!(*.scss)'), ['material:build-no-bundles']); - watchFiles(join(materialPackage.sourceDir, '**/*.scss'), [':build:devapp:material-with-styles']); - watchFiles(join(momentAdapterPackage.sourceDir, '**/*'), - ['material-moment-adapter:build-no-bundles']); - watchFiles(join(materialExperimentalPackage.sourceDir, '**/*'), - ['material-experimental:build-no-bundles']); - watchFiles(join(cdkExperimentalPackage.sourceDir, '**/*'), - ['cdk-experimental:build-no-bundles']); - watchFiles(join(examplesPackage.sourceDir, '**/*'), ['material-examples:build-no-bundles']); -}); - /** Path to the demo-app tsconfig file. */ const tsconfigPath = join(appDir, 'tsconfig-build.json'); task(':build:devapp:ts', tsBuildTask(tsconfigPath)); -task(':build:devapp:scss', buildScssTask(outDir, appDir)); task(':build:devapp:assets', copyTask(assetsGlob, outDir)); +task(':build:devapp:scss', () => buildScssPipeline(appDir).pipe(dest(outDir))); task(':serve:devapp', serverTask(outDir, true)); -// The themes for the demo-app are built by using the SCSS mixins from Material. -// Therefore when SCSS files have been changed, the custom theme needs to be rebuilt. -task(':build:devapp:material-with-styles', sequenceTask( - 'material:build-no-bundles', ':build:devapp:scss' -)); - task('build:devapp', sequenceTask( 'cdk:build-no-bundles', 'material:build-no-bundles', 'cdk-experimental:build-no-bundles', 'material-experimental:build-no-bundles', 'material-moment-adapter:build-no-bundles', - 'build-examples-module', // The examples module needs to be built before building examples package + 'build-examples-module', + // The examples module needs to be manually built before building examples package because + // when using the `no-bundles` task, the package-specific pre-build tasks won't be executed. 'material-examples:build-no-bundles', [':build:devapp:assets', ':build:devapp:scss', ':build:devapp:ts'] )); task('serve:devapp', ['build:devapp'], sequenceTask([':serve:devapp', ':watch:devapp'])); +/* + * Development App deployment tasks. These can be used to run the dev-app outside of our + * serve task with a middleware. e.g. on Firebase hosting. + */ + /** Task that copies all vendors into the demo-app package. Allows hosting the app on firebase. */ task('stage-deploy:devapp', ['build:devapp'], () => { copyFiles(join(projectDir, 'node_modules'), vendorGlob, join(outDir, 'node_modules')); @@ -118,3 +100,40 @@ task('deploy:devapp', ['stage-deploy:devapp'], () => { .then(() => { console.log('Successfully deployed the demo-app to firebase'); process.exit(0); }) .catch((err: any) => { console.log(err); process.exit(1); }); }); + +/* + * Development app watch task. This task ensures that only the packages that have been affected + * by a file-change are being rebuilt. This speeds-up development and makes working on Material + * easier. + */ + +task(':watch:devapp', () => { + watchFiles(join(appDir, '**/*.ts'), [':build:devapp:ts']); + watchFiles(join(appDir, '**/*.scss'), [':build:devapp:scss']); + watchFiles(join(appDir, '**/*.html'), [':build:devapp:assets']); + + // Custom watchers for all packages that are used inside of the demo-app. This is necessary + // because we only want to build the changed package (using the build-no-bundles task). + + // CDK package watchers. + watchFiles(join(cdkPackage.sourceDir, '**/*'), ['cdk:build-no-bundles']); + + // Material package watchers. + watchFiles(join(materialPackage.sourceDir, '**/!(*-theme).scss'), ['material:build-no-bundles']); + watchFiles(join(materialPackage.sourceDir, '**/*-theme.scss'), [':build:devapp:scss']); + + // Moment adapter package watchers + watchFiles(join(momentAdapterPackage.sourceDir, '**/*'), + ['material-moment-adapter:build-no-bundles']); + + // Material experimental package watchers + watchFiles(join(materialExperimentalPackage.sourceDir, '**/*'), + ['material-experimental:build-no-bundles']); + + // CDK experimental package watchers + watchFiles(join(cdkExperimentalPackage.sourceDir, '**/*'), + ['cdk-experimental:build-no-bundles']); + + // Example package watchers. + watchFiles(join(examplesPackage.sourceDir, '**/*'), ['material-examples:build-no-bundles']); +}); diff --git a/tools/gulp/tasks/material-release.ts b/tools/gulp/tasks/material-release.ts index d1d5595c30a7..331b97988c48 100644 --- a/tools/gulp/tasks/material-release.ts +++ b/tools/gulp/tasks/material-release.ts @@ -19,14 +19,19 @@ const releasesDir = join(distDir, 'releases'); // Path to the release output of material. const releasePath = join(releasesDir, 'material'); + // The entry-point for the scss theming bundle. const themingEntryPointPath = join(sourceDir, 'core', 'theming', '_all-theme.scss'); + // Output path for the scss theming bundle. const themingBundlePath = join(releasePath, '_theming.scss'); + // Matches all pre-built theme css files const prebuiltThemeGlob = join(outputDir, '**/theming/prebuilt/*.css?(.map)'); -// Matches all SCSS files in the different packages. -const allScssGlob = join(buildConfig.packagesDir, '**/*.scss'); + +// Matches all SCSS files in the different packages. Note that this glob is not used to build +// the bundle. It's used to identify Sass files that shouldn't be included multiple times. +const allScssDedupeGlob = join(buildConfig.packagesDir, '**/*.scss'); // Pattern matching schematics files to be copied into the @angular/material package. const schematicsGlobs = [ @@ -74,7 +79,7 @@ task('material:bundle-theming-scss', () => { // Instantiates the SCSS bundler and bundles all imports of the specified entry point SCSS file. // A glob of all SCSS files in the library will be passed to the bundler. The bundler takes an // array of globs, which will match SCSS files that will be only included once in the bundle. - return new Bundler().Bundle(themingEntryPointPath, [allScssGlob]).then(result => { + return new Bundler().Bundle(themingEntryPointPath, [allScssDedupeGlob]).then(result => { // The release directory is not created yet because the composing of the release happens when // this task finishes. mkdirpSync(releasePath); diff --git a/tools/package-tools/gulp/build-scss-pipeline.ts b/tools/package-tools/gulp/build-scss-pipeline.ts new file mode 100644 index 000000000000..13922bb62117 --- /dev/null +++ b/tools/package-tools/gulp/build-scss-pipeline.ts @@ -0,0 +1,14 @@ +import {src} from 'gulp'; +import {join} from 'path'; + +// These imports lack of type definitions. +const gulpSass = require('gulp-sass'); +const gulpIf = require('gulp-if'); +const gulpCleanCss = require('gulp-clean-css'); + +/** Create a gulp task that builds SCSS files. */ +export function buildScssPipeline(sourceDir: string, minifyOutput = false) { + return src(join(sourceDir, '**/*.scss')) + .pipe(gulpSass().on('error', gulpSass.logError)) + .pipe(gulpIf(minifyOutput, gulpCleanCss())); +} diff --git a/tools/package-tools/gulp/build-scss-task.ts b/tools/package-tools/gulp/build-scss-task.ts deleted file mode 100644 index 3f4d9c611f15..000000000000 --- a/tools/package-tools/gulp/build-scss-task.ts +++ /dev/null @@ -1,17 +0,0 @@ -import {src, dest} from 'gulp'; -import {join} from 'path'; - -// These imports lack of type definitions. -const gulpDartSass = require('gulp-dart-sass'); -const gulpIf = require('gulp-if'); -const gulpCleanCss = require('gulp-clean-css'); - -/** Create a gulp task that builds SCSS files. */ -export function buildScssTask(outputDir: string, sourceDir: string, minifyOutput = false) { - return () => { - return src(join(sourceDir, '**/*.scss')) - .pipe(gulpDartSass.sync().on('error', gulpDartSass.logError)) - .pipe(gulpIf(minifyOutput, gulpCleanCss())) - .pipe(dest(outputDir)); - }; -} diff --git a/tools/package-tools/gulp/build-tasks-gulp.ts b/tools/package-tools/gulp/build-tasks-gulp.ts index 924fe52ad369..2a3fd7ac486e 100644 --- a/tools/package-tools/gulp/build-tasks-gulp.ts +++ b/tools/package-tools/gulp/build-tasks-gulp.ts @@ -2,12 +2,11 @@ import {dest, src, task} from 'gulp'; import {join} from 'path'; import {composeRelease} from '../build-release'; import {inlineResourcesForDirectory} from '../inline-resources'; -import {buildScssTask} from './build-scss-task'; +import {buildScssPipeline} from './build-scss-pipeline'; import {sequenceTask} from './sequence-task'; import {watchFiles} from './watch-files'; import {BuildPackage} from '../build-package'; - // There are no type definitions available for these imports. const htmlmin = require('gulp-htmlmin'); @@ -31,7 +30,7 @@ export function createPackageBuildTasks(buildPackage: BuildPackage, preBuildTask const dependencyNames = buildPackage.dependencies.map(p => p.name); // Glob that matches all style files that need to be copied to the package output. - const stylesGlob = join(buildPackage.sourceDir, '**/*.+(scss|css)'); + const stylesGlob = join(buildPackage.sourceDir, '**/*.css'); // Glob that matches every HTML file in the current package. const htmlGlob = join(buildPackage.sourceDir, '**/*.html'); @@ -90,17 +89,15 @@ export function createPackageBuildTasks(buildPackage: BuildPackage, preBuildTask */ task(`${taskName}:assets`, [ `${taskName}:assets:scss`, - `${taskName}:assets:es5-scss`, `${taskName}:assets:copy-styles`, `${taskName}:assets:html` ]); - task(`${taskName}:assets:scss`, buildScssTask( - buildPackage.outputDir, buildPackage.sourceDir, true) - ); - - task(`${taskName}:assets:es5-scss`, buildScssTask( - buildPackage.esm5OutputDir, buildPackage.sourceDir, true) + task(`${taskName}:assets:scss`, () => { + buildScssPipeline(buildPackage.sourceDir, true) + .pipe(dest(buildPackage.outputDir)) + .pipe(dest(buildPackage.esm5OutputDir)); + } ); task(`${taskName}:assets:copy-styles`, () => { @@ -108,6 +105,7 @@ export function createPackageBuildTasks(buildPackage: BuildPackage, preBuildTask .pipe(dest(buildPackage.outputDir)) .pipe(dest(buildPackage.esm5OutputDir)); }); + task(`${taskName}:assets:html`, () => { return src(htmlGlob).pipe(htmlmin(htmlMinifierOptions)) .pipe(dest(buildPackage.outputDir)) diff --git a/tools/package-tools/index.ts b/tools/package-tools/index.ts index dec848ca5b8a..840eb0ee1665 100644 --- a/tools/package-tools/index.ts +++ b/tools/package-tools/index.ts @@ -7,7 +7,7 @@ export * from './copy-files'; // Expose gulp utilities. export * from './gulp/build-tasks-gulp'; -export * from './gulp/build-scss-task'; +export * from './gulp/build-scss-pipeline'; export * from './gulp/sequence-task'; export * from './gulp/trigger-livereload'; export * from './gulp/watch-files';