Skip to content

Instantly share code, notes, and snippets.

@romelgomez
Last active June 27, 2019 14:04
Show Gist options
  • Save romelgomez/106625de08bbf68a2ca2b5c8aa93dcc8 to your computer and use it in GitHub Desktop.
Save romelgomez/106625de08bbf68a2ca2b5c8aa93dcc8 to your computer and use it in GitHub Desktop.

Add material to angular2-webpack-starter in three steps:

a) Add material

  • Step 1

npm install --save @angular/material material hammerjs

  • Step 2

In the file /config/head-config.common.js, Add to the link array:

    /** <link> tags for a fonts **/
    { rel: 'stylesheet', href: 'https://fonts.googleapis.com/icon?family=Material+Icons' }
  • Step 3

In the app Module /src/app/app.module.ts or in the Module where material will work add:

// Material 2
import { MaterialModule } from '@angular/material';
import 'hammerjs';
  imports: [ 
    MaterialModule.forRoot()
  ],

Resources:

  1. https://github.com/angular/material2

  2. Code examples

b) Add sass support

  • Step 1

npm install --save-dev node-sass sass-loader

  • Step 2

In the file /config/webpack.common.js, Add to return object of Webpack configuration function, to module.rules array

        /*
         * To support for *.scss files
         *
         */         
        {
          test: /\.scss$/,
          exclude: /node_modules/,
          loaders: ['raw-loader', 'sass-loader']
        }         
  • Step 3

Replace in the component decorator declaration the .css files for .scss

Before:

  styleUrls: [
    './app.component.css'
  ]

After:

  styleUrls: [
    './app.component.scss'
  ]
  • Step 4

Create the file app.compoent.scss file add the next code:

@import '~@angular/material/core/theming/all-theme';

// NOTE: Theming is currently experimental and not yet publically released!

@include md-core();

$primary: md-palette($md-deep-purple);
$accent:  md-palette($md-amber, A200, A100, A400);

$theme: md-light-theme($primary, $accent);

@include angular-material-theme($theme);

.m2app-dark {
  $dark-primary: md-palette($md-pink, 700, 500, 900);
  $dark-accent:  md-palette($md-blue-grey, A200, A100, A400);
  $dark-warn:    md-palette($md-deep-orange);

  $dark-theme: md-dark-theme($dark-primary, $dark-accent, $dark-warn);

  @include angular-material-theme($dark-theme);
}

body {
  font-family: Roboto, 'Helvetica Neue', sans-serif;

  // Helps fonts on OSX looks more consistent with other systems
  // Isn't currently in button styles due to performance concerns
  * {
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
  }

  md-sidenav {
    min-width: 15%;

    [md-button] {
      width: 100%;
      position: relative;
      bottom: 0;
      margin: 24px 0;
    }
  }

  .demo-content {
    padding: 32px;
  }

  md-toolbar {
    md-icon {
      cursor: pointer;
    }

    .demo-toolbar {
      display: flex;
      justify-content: space-between;
      width: 100%;
    }
  }

  h1 {
    font-size: 20px;
  }
}

Ref:

  1. https://github.com/AngularClass/angular2-webpack-starter/wiki/How-to-include-SCSS-in-components

c) Restart the server

Restart the server npm start

@import '~@angular/material/core/theming/all-theme';
// NOTE: Theming is currently experimental and not yet publically released!
@include md-core();
$primary: md-palette($md-deep-purple);
$accent: md-palette($md-amber, A200, A100, A400);
$theme: md-light-theme($primary, $accent);
@include angular-material-theme($theme);
.m2app-dark {
$dark-primary: md-palette($md-pink, 700, 500, 900);
$dark-accent: md-palette($md-blue-grey, A200, A100, A400);
$dark-warn: md-palette($md-deep-orange);
$dark-theme: md-dark-theme($dark-primary, $dark-accent, $dark-warn);
@include angular-material-theme($dark-theme);
}
body {
font-family: Roboto, 'Helvetica Neue', sans-serif;
// Helps fonts on OSX looks more consistent with other systems
// Isn't currently in button styles due to performance concerns
* {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
md-sidenav {
min-width: 15%;
[md-button] {
width: 100%;
position: relative;
bottom: 0;
margin: 24px 0;
}
}
.demo-content {
padding: 32px;
}
md-toolbar {
md-icon {
cursor: pointer;
}
.demo-toolbar {
display: flex;
justify-content: space-between;
width: 100%;
}
}
h1 {
font-size: 20px;
}
}
/*
* Angular 2 decorators and services
*/
import { Component, ViewEncapsulation } from '@angular/core';
import { AppState } from './app.service';
/*
* App Component
* Top Level Component
*/
@Component({
selector: 'app',
encapsulation: ViewEncapsulation.None,
styleUrls: [
'./app.component.scss'
],
template: `
<nav>
<span>
<a [routerLink]=" ['./'] ">
Index
</a>
</span>
|
<span>
<a [routerLink]=" ['./home'] ">
Home
</a>
</span>
|
<span>
<a [routerLink]=" ['./detail'] ">
Detail
</a>
</span>
|
<span>
<a [routerLink]=" ['./about'] ">
About
</a>
</span>
</nav>
<main>
<router-outlet></router-outlet>
</main>
<pre class="app-state">this.appState.state = {{ appState.state | json }}</pre>
<footer>
<span>WebPack Angular 2 Starter by <a [href]="url">@AngularClass</a></span>
<div>
<a [href]="url">
<img [src]="angularclassLogo" width="25%">
</a>
</div>
</footer>
`
})
export class AppComponent {
angularclassLogo = 'assets/img/angularclass-avatar.png';
name = 'Angular 2 Webpack Starter';
url = 'https://twitter.com/AngularClass';
constructor(
public appState: AppState) {
}
ngOnInit() {
console.log('Initial App State', this.appState.state);
}
}
/*
* Please review the https://github.com/AngularClass/angular2-examples/ repo for
* more angular app examples that you may copy/paste
* (The examples may not be updated as quickly. Please open an issue on github for us to update it)
* For help or questions please contact us at @AngularClass on twitter
* or our chat on Slack at https://AngularClass.com/slack-join
*/
import { NgModule, ApplicationRef } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import { RouterModule, PreloadAllModules } from '@angular/router';
import { removeNgStyles, createNewHosts, createInputTransfer } from '@angularclass/hmr';
import { MaterialModule } from '@angular/material';
import 'hammerjs';
/*
* Platform and Environment providers/directives/pipes
*/
import { ENV_PROVIDERS } from './environment';
import { ROUTES } from './app.routes';
// App is our top level component
import { AppComponent } from './app.component';
import { APP_RESOLVER_PROVIDERS } from './app.resolver';
import { AppState, InternalStateType } from './app.service';
import { HomeComponent } from './home';
import { AboutComponent } from './about';
import { NoContentComponent } from './no-content';
import { XLarge } from './home/x-large';
// Application wide providers
const APP_PROVIDERS = [
...APP_RESOLVER_PROVIDERS,
AppState
];
type StoreType = {
state: InternalStateType,
restoreInputValues: () => void,
disposeOldHosts: () => void
};
/**
* `AppModule` is the main entry point into Angular2's bootstraping process
*/
@NgModule({
bootstrap: [ AppComponent ],
declarations: [
AppComponent,
AboutComponent,
HomeComponent,
NoContentComponent,
XLarge
],
imports: [ // import Angular's modules
BrowserModule,
FormsModule,
HttpModule,
RouterModule.forRoot(ROUTES, { useHash: true, preloadingStrategy: PreloadAllModules }),
MaterialModule.forRoot()
],
providers: [ // expose our Services and Providers into Angular's dependency injection
ENV_PROVIDERS,
APP_PROVIDERS
]
})
export class AppModule {
constructor(public appRef: ApplicationRef, public appState: AppState) {}
hmrOnInit(store: StoreType) {
if (!store || !store.state) return;
console.log('HMR store', JSON.stringify(store, null, 2));
// set state
this.appState._state = store.state;
// set input values
if ('restoreInputValues' in store) {
let restoreInputValues = store.restoreInputValues;
setTimeout(restoreInputValues);
}
this.appRef.tick();
delete store.state;
delete store.restoreInputValues;
}
hmrOnDestroy(store: StoreType) {
const cmpLocation = this.appRef.components.map(cmp => cmp.location.nativeElement);
// save state
const state = this.appState._state;
store.state = state;
// recreate root elements
store.disposeOldHosts = createNewHosts(cmpLocation);
// save input values
store.restoreInputValues = createInputTransfer();
// remove styles
removeNgStyles();
}
hmrAfterDestroy(store: StoreType) {
// display new elements
store.disposeOldHosts();
delete store.disposeOldHosts;
}
}
/**
* Configuration for head elements added during the creation of index.html.
*
* All href attributes are added the publicPath (if exists) by default.
* You can explicitly hint to prefix a publicPath by setting a boolean value to a key that has
* the same name as the attribute you want to operate on, but prefix with =
*
* Example:
* { name: 'msapplication-TileImage', content: '/assets/icon/ms-icon-144x144.png', '=content': true },
* Will prefix the publicPath to content.
*
* { rel: 'apple-touch-icon', sizes: '57x57', href: '/assets/icon/apple-icon-57x57.png', '=href': false },
* Will not prefix the publicPath on href (href attributes are added by default
*
*/
module.exports = {
link: [
/** <link> tags for 'apple-touch-icon' (AKA Web Clips). **/
{ rel: 'apple-touch-icon', sizes: '57x57', href: '/assets/icon/apple-icon-57x57.png' },
{ rel: 'apple-touch-icon', sizes: '60x60', href: '/assets/icon/apple-icon-60x60.png' },
{ rel: 'apple-touch-icon', sizes: '72x72', href: '/assets/icon/apple-icon-72x72.png' },
{ rel: 'apple-touch-icon', sizes: '76x76', href: '/assets/icon/apple-icon-76x76.png' },
{ rel: 'apple-touch-icon', sizes: '114x114', href: '/assets/icon/apple-icon-114x114.png' },
{ rel: 'apple-touch-icon', sizes: '120x120', href: '/assets/icon/apple-icon-120x120.png' },
{ rel: 'apple-touch-icon', sizes: '144x144', href: '/assets/icon/apple-icon-144x144.png' },
{ rel: 'apple-touch-icon', sizes: '152x152', href: '/assets/icon/apple-icon-152x152.png' },
{ rel: 'apple-touch-icon', sizes: '180x180', href: '/assets/icon/apple-icon-180x180.png' },
/** <link> tags for android web app icons **/
{ rel: 'icon', type: 'image/png', sizes: '192x192', href: '/assets/icon/android-icon-192x192.png' },
/** <link> tags for favicons **/
{ rel: 'icon', type: 'image/png', sizes: '32x32', href: '/assets/icon/favicon-32x32.png' },
{ rel: 'icon', type: 'image/png', sizes: '96x96', href: '/assets/icon/favicon-96x96.png' },
{ rel: 'icon', type: 'image/png', sizes: '16x16', href: '/assets/icon/favicon-16x16.png' },
/** <link> tags for a Web App Manifest **/
{ rel: 'manifest', href: '/assets/manifest.json' },
/** <link> tags for a fonts **/
{ rel: 'stylesheet', href: 'https://fonts.googleapis.com/icon?family=Material+Icons' }
],
meta: [
{ name: 'msapplication-TileColor', content: '#00bcd4' },
{ name: 'msapplication-TileImage', content: '/assets/icon/ms-icon-144x144.png', '=content': true },
{ name: 'theme-color', content: '#00bcd4' }
]
};
{
"name": "angular2-webpack-starter",
"version": "5.1.1",
"description": "An Angular 2 Webpack Starter kit featuring Angular 2 (Router, Http, Forms, Services, Tests, E2E, Coverage), Karma, Protractor, Jasmine, Istanbul, TypeScript, and Webpack by AngularClass",
"keywords": [
"angular2",
"webpack",
"typescript"
],
"author": "Patrick Stapleton <patrick@angularclass.com>",
"homepage": "https://github.com/angularclass/angular2-webpack-starter",
"license": "MIT",
"scripts": {
"build:dev": "webpack --config config/webpack.dev.js --progress --profile",
"build:docker": "npm run build:prod && docker build -t angular2-webpack-start:latest .",
"build:prod": "webpack --config config/webpack.prod.js --progress --profile --bail",
"build": "npm run build:dev",
"ci": "npm run lint && npm test && npm run e2e",
"clean:dist": "npm run rimraf -- dist",
"clean:install": "npm set progress=false && npm install",
"clean:start": "npm start",
"clean": "npm cache clean && npm run rimraf -- node_modules doc coverage dist",
"docker": "docker",
"docs": "npm run typedoc -- --options typedoc.json --exclude '**/*.spec.ts' ./src/",
"e2e:live": "npm run e2e -- --elementExplorer",
"e2e": "npm run protractor",
"github-deploy:dev": "webpack --config config/webpack.github-deploy.js --progress --profile --env.githubDev",
"github-deploy:prod": "webpack --config config/webpack.github-deploy.js --progress --profile --env.githubProd",
"github-deploy": "npm run github-deploy:dev",
"lint": "npm run tslint \"src/**/*.ts\"",
"postversion": "git push && git push --tags",
"prebuild:dev": "npm run clean:dist",
"prebuild:prod": "npm run clean:dist",
"preclean:install": "npm run clean",
"preclean:start": "npm run clean",
"pree2e": "npm run webdriver:update -- --standalone",
"preversion": "npm test",
"protractor": "protractor",
"rimraf": "rimraf",
"server:dev:hmr": "npm run server:dev -- --inline --hot",
"server:dev": "webpack-dev-server --config config/webpack.dev.js --progress --profile --watch --content-base src/",
"server:prod": "http-server dist --cors",
"server:prod:ci": "http-server dist -p 3000 --cors",
"server": "npm run server:dev",
"start:hmr": "npm run server:dev:hmr",
"start": "npm run server:dev",
"test": "karma start",
"tslint": "tslint",
"typedoc": "typedoc",
"version": "npm run build",
"watch:dev:hmr": "npm run watch:dev -- --hot",
"watch:dev": "npm run build:dev -- --watch",
"watch:prod": "npm run build:prod -- --watch",
"watch:test": "npm run test -- --auto-watch --no-single-run",
"watch": "npm run watch:dev",
"webdriver-manager": "webdriver-manager",
"webdriver:start": "npm run webdriver-manager start",
"webdriver:update": "npm run webdriver-manager update",
"webpack-dev-server": "webpack-dev-server",
"webpack": "webpack"
},
"dependencies": {
"@angular/common": "2.2.1",
"@angular/compiler": "2.2.1",
"@angular/core": "2.2.1",
"@angular/forms": "2.2.1",
"@angular/http": "2.2.1",
"@angular/material": "^2.0.0-alpha.11-3",
"@angular/platform-browser": "2.2.1",
"@angular/platform-browser-dynamic": "2.2.1",
"@angular/platform-server": "2.2.1",
"@angular/router": "3.2.1",
"@angularclass/conventions-loader": "^1.0.2",
"@angularclass/hmr": "~1.2.2",
"@angularclass/hmr-loader": "~3.0.2",
"assets-webpack-plugin": "^3.4.0",
"core-js": "^2.4.1",
"hammerjs": "^2.0.8",
"http-server": "^0.9.0",
"ie-shim": "^0.1.0",
"material": "^0.1.1",
"rxjs": "5.0.0-beta.12",
"zone.js": "~0.6.26"
},
"devDependencies": {
"@types/hammerjs": "^2.0.33",
"@types/jasmine": "^2.2.34",
"@types/node": "^6.0.38",
"@types/selenium-webdriver": "2.53.33",
"@types/source-map": "^0.1.27",
"@types/uglify-js": "^2.0.27",
"@types/webpack": "^1.12.34",
"angular-router-loader": "^0.4.0",
"angular2-template-loader": "^0.6.0",
"awesome-typescript-loader": "^2.2.1",
"codelyzer": "~1.0.0-beta.4",
"copy-webpack-plugin": "^4.0.0",
"css-loader": "^0.26.0",
"exports-loader": "^0.6.3",
"expose-loader": "^0.7.1",
"file-loader": "^0.9.0",
"gh-pages": "^0.12.0",
"html-webpack-plugin": "^2.21.0",
"imports-loader": "^0.6.5",
"istanbul-instrumenter-loader": "0.2.0",
"json-loader": "^0.5.4",
"karma": "^1.2.0",
"karma-chrome-launcher": "^2.0.0",
"karma-coverage": "^1.1.1",
"karma-jasmine": "^1.0.2",
"karma-mocha-reporter": "^2.0.0",
"karma-remap-coverage": "^0.1.1",
"karma-sourcemap-loader": "^0.3.7",
"karma-webpack": "1.8.0",
"node-sass": "^4.0.0",
"parse5": "^2.2.2",
"protractor": "^4.0.10",
"raw-loader": "0.5.1",
"rimraf": "~2.5.4",
"sass-loader": "^4.0.2",
"script-ext-html-webpack-plugin": "^1.3.2",
"source-map-loader": "^0.1.5",
"string-replace-loader": "1.0.5",
"style-loader": "^0.13.1",
"to-string-loader": "^1.1.4",
"ts-helpers": "1.1.2",
"ts-node": "^1.7.0",
"tslint": "~3.15.1",
"tslint-loader": "^2.1.5",
"typedoc": "^0.5.0",
"typescript": "2.1.1",
"url-loader": "^0.5.7",
"v8-lazy-parse-webpack-plugin": "^0.3.0",
"webpack": "2.1.0-beta.27",
"webpack-dev-middleware": "^1.6.1",
"webpack-dev-server": "2.1.0-beta.11",
"webpack-md5-hash": "^0.0.5",
"webpack-merge": "~1.0.1"
},
"repository": {
"type": "git",
"url": "https://github.com/angularclass/angular2-webpack-starter.git"
},
"bugs": {
"url": "https://github.com/angularclass/angular2-webpack-starter/issues"
},
"engines": {
"node": ">= 4.2.1",
"npm": ">= 3"
}
}
/**
* @author: @AngularClass
*/
const webpack = require('webpack');
const helpers = require('./helpers');
/*
* Webpack Plugins
*/
// problem with copy-webpack-plugin
const AssetsPlugin = require('assets-webpack-plugin');
const NormalModuleReplacementPlugin = require('webpack/lib/NormalModuleReplacementPlugin');
const ContextReplacementPlugin = require('webpack/lib/ContextReplacementPlugin');
const CommonsChunkPlugin = require('webpack/lib/optimize/CommonsChunkPlugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const ForkCheckerPlugin = require('awesome-typescript-loader').ForkCheckerPlugin;
const HtmlElementsPlugin = require('./html-elements-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const LoaderOptionsPlugin = require('webpack/lib/LoaderOptionsPlugin');
const ScriptExtHtmlWebpackPlugin = require('script-ext-html-webpack-plugin');
/*
* Webpack Constants
*/
const HMR = helpers.hasProcessFlag('hot');
const METADATA = {
title: 'Angular2 Webpack Starter by @gdi2290 from @AngularClass',
baseUrl: '/',
isDevServer: helpers.isWebpackDevServer()
};
/*
* Webpack configuration
*
* See: http://webpack.github.io/docs/configuration.html#cli
*/
module.exports = function (options) {
isProd = options.env === 'production';
return {
/*
* Cache generated modules and chunks to improve performance for multiple incremental builds.
* This is enabled by default in watch mode.
* You can pass false to disable it.
*
* See: http://webpack.github.io/docs/configuration.html#cache
*/
//cache: false,
/*
* The entry point for the bundle
* Our Angular.js app
*
* See: http://webpack.github.io/docs/configuration.html#entry
*/
entry: {
'polyfills': './src/polyfills.browser.ts',
'vendor': './src/vendor.browser.ts',
'main': './src/main.browser.ts'
},
/*
* Options affecting the resolving of modules.
*
* See: http://webpack.github.io/docs/configuration.html#resolve
*/
resolve: {
/*
* An array of extensions that should be used to resolve modules.
*
* See: http://webpack.github.io/docs/configuration.html#resolve-extensions
*/
extensions: ['.ts', '.js', '.json'],
// An array of directory names to be resolved to the current directory
modules: [helpers.root('src'), helpers.root('node_modules')],
},
/*
* Options affecting the normal modules.
*
* See: http://webpack.github.io/docs/configuration.html#module
*/
module: {
rules: [
/*
* Typescript loader support for .ts and Angular 2 async routes via .async.ts
* Replace templateUrl and stylesUrl with require()
*
* See: https://github.com/s-panferov/awesome-typescript-loader
* See: https://github.com/TheLarkInn/angular2-template-loader
*/
{
test: /\.ts$/,
use: [
'@angularclass/hmr-loader?pretty=' + !isProd + '&prod=' + isProd,
'awesome-typescript-loader',
'angular2-template-loader',
'angular-router-loader'
],
exclude: [/\.(spec|e2e)\.ts$/]
},
/*
* Json loader support for *.json files.
*
* See: https://github.com/webpack/json-loader
*/
{
test: /\.json$/,
use: 'json-loader'
},
/*
* to string and css loader support for *.css files
* Returns file content as string
*
*/
{
test: /\.css$/,
use: ['to-string-loader', 'css-loader']
},
/*
* To support for *.scss files
*
*/
{
test: /\.scss$/,
exclude: /node_modules/,
loaders: ['raw-loader', 'sass-loader']
},
/* Raw loader support for *.html
* Returns file content as string
*
* See: https://github.com/webpack/raw-loader
*/
{
test: /\.html$/,
use: 'raw-loader',
exclude: [helpers.root('src/index.html')]
},
/* File loader for supporting images, for example, in CSS files.
*/
{
test: /\.(jpg|png|gif)$/,
use: 'file-loader'
},
],
},
/*
* Add additional plugins to the compiler.
*
* See: http://webpack.github.io/docs/configuration.html#plugins
*/
plugins: [
new AssetsPlugin({
path: helpers.root('dist'),
filename: 'webpack-assets.json',
prettyPrint: true
}),
/*
* Plugin: ForkCheckerPlugin
* Description: Do type checking in a separate process, so webpack don't need to wait.
*
* See: https://github.com/s-panferov/awesome-typescript-loader#forkchecker-boolean-defaultfalse
*/
new ForkCheckerPlugin(),
/*
* Plugin: CommonsChunkPlugin
* Description: Shares common code between the pages.
* It identifies common modules and put them into a commons chunk.
*
* See: https://webpack.github.io/docs/list-of-plugins.html#commonschunkplugin
* See: https://github.com/webpack/docs/wiki/optimization#multi-page-app
*/
new CommonsChunkPlugin({
name: ['polyfills', 'vendor'].reverse()
}),
/**
* Plugin: ContextReplacementPlugin
* Description: Provides context to Angular's use of System.import
*
* See: https://webpack.github.io/docs/list-of-plugins.html#contextreplacementplugin
* See: https://github.com/angular/angular/issues/11580
*/
new ContextReplacementPlugin(
// The (\\|\/) piece accounts for path separators in *nix and Windows
/angular(\\|\/)core(\\|\/)src(\\|\/)linker/,
helpers.root('src'), // location of your src
{
// your Angular Async Route paths relative to this root directory
}
),
/*
* Plugin: CopyWebpackPlugin
* Description: Copy files and directories in webpack.
*
* Copies project static assets.
*
* See: https://www.npmjs.com/package/copy-webpack-plugin
*/
new CopyWebpackPlugin([
{ from: 'src/assets', to: 'assets' },
{ from: 'src/meta'}
]),
/*
* Plugin: HtmlWebpackPlugin
* Description: Simplifies creation of HTML files to serve your webpack bundles.
* This is especially useful for webpack bundles that include a hash in the filename
* which changes every compilation.
*
* See: https://github.com/ampedandwired/html-webpack-plugin
*/
new HtmlWebpackPlugin({
template: 'src/index.html',
title: METADATA.title,
chunksSortMode: 'dependency',
metadata: METADATA,
inject: 'head'
}),
/*
* Plugin: ScriptExtHtmlWebpackPlugin
* Description: Enhances html-webpack-plugin functionality
* with different deployment options for your scripts including:
*
* See: https://github.com/numical/script-ext-html-webpack-plugin
*/
new ScriptExtHtmlWebpackPlugin({
defaultAttribute: 'defer'
}),
/*
* Plugin: HtmlElementsPlugin
* Description: Generate html tags based on javascript maps.
*
* If a publicPath is set in the webpack output configuration, it will be automatically added to
* href attributes, you can disable that by adding a "=href": false property.
* You can also enable it to other attribute by settings "=attName": true.
*
* The configuration supplied is map between a location (key) and an element definition object (value)
* The location (key) is then exported to the template under then htmlElements property in webpack configuration.
*
* Example:
* Adding this plugin configuration
* new HtmlElementsPlugin({
* headTags: { ... }
* })
*
* Means we can use it in the template like this:
* <%= webpackConfig.htmlElements.headTags %>
*
* Dependencies: HtmlWebpackPlugin
*/
new HtmlElementsPlugin({
headTags: require('./head-config.common')
}),
/**
* Plugin LoaderOptionsPlugin (experimental)
*
* See: https://gist.github.com/sokra/27b24881210b56bbaff7
*/
new LoaderOptionsPlugin({}),
// Fix Angular 2
new NormalModuleReplacementPlugin(
/facade(\\|\/)async/,
helpers.root('node_modules/@angular/core/src/facade/async.js')
),
new NormalModuleReplacementPlugin(
/facade(\\|\/)collection/,
helpers.root('node_modules/@angular/core/src/facade/collection.js')
),
new NormalModuleReplacementPlugin(
/facade(\\|\/)errors/,
helpers.root('node_modules/@angular/core/src/facade/errors.js')
),
new NormalModuleReplacementPlugin(
/facade(\\|\/)lang/,
helpers.root('node_modules/@angular/core/src/facade/lang.js')
),
new NormalModuleReplacementPlugin(
/facade(\\|\/)math/,
helpers.root('node_modules/@angular/core/src/facade/math.js')
),
],
/*
* Include polyfills or mocks for various node stuff
* Description: Node configuration
*
* See: https://webpack.github.io/docs/configuration.html#node
*/
node: {
global: true,
crypto: 'empty',
process: true,
module: false,
clearImmediate: false,
setImmediate: false
}
};
}
@holms
Copy link

holms commented Dec 11, 2016

In theming.md it says to import css from node_modules:

<link href="node_modules/@angular/material/core/theming/prebuilt/indigo-pink.css" rel="stylesheet">

How can I do that? Directory node_modules is not served by webstarter...?
Without this css materials doesn't even work..

Regarding step3.. in which file this content is?

update: oh ok it's ./app/app.component.ts

@holms
Copy link

holms commented Dec 11, 2016

All modules is installed exactly as you've instructed. Everything modified exactly as you've instructed and it's doesn't work. Make a repo yourself and you'll see it doesn't work anymore. I've had this problem with hammerjs before, and it was the same mistake:

[HMR] Waiting for update signal from WDS... polyfills.bundle.js:3608:2
Error: Cannot find module "hammerjs"
 main.bundle.js:15062:65
[WDS] Hot Module Replacement enabled. polyfills.bundle.js:3438:1
[WDS] Errors while compiling. Reload prevented. polyfills.bundle.js:3438:1
./src/app/app.module.ts
Module not found: Error: Can't resolve 'hammerjs' in '/frontend/src/app'
 @ ./src/app/app.module.ts 9:0-19
 @ ./src/app/index.ts
 @ ./src/main.browser.ts
 @ multi main polyfills.bundle.js:3499:4

./src/app/app.component.ts
Module not found: Error: Can't resolve './app.component.scss' in '/frontend/src/app'
 @ ./src/app/app.component.ts 26:16-47
 @ ./src/app/app.module.ts
 @ ./src/app/index.ts
 @ ./src/main.browser.ts
 @ multi main

@romelgomez
Copy link
Author

Please check again, I rewrote the manual, based on a new installation of angular2-webpack-starter

@Silthus
Copy link

Silthus commented Dec 29, 2016

When following your guide with the latest angular2-webpack-starter clone, I get the following error: TypeError: Cannot read property 'forRoot' of undefined.

The app does not seem to find the MaterialModule. I ran npm run build:dev and after that npm start. Do I need to reference the MaterialModule somewhere else for it to be compiled into the bundle?

What I noticed is that the vendor bundle is missing in the latest clone but you have it in your webpack.common.js config.

@rehannawab
Copy link

I ran into a similar issue. Webpack 2.2.0-rc.3 fixes this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment