.Net Core 2 Spa Template with Angular Material
Asked Answered
E

2

6

Struggling trying to get Angular Material , or any 3rd party control set really, to work with this new template. In this new template, the webpack is broken into TreeShakable and NonTreeShakable. In addition the app.module is now app.module.shared, app.module.browser, app.module.server.

As I have attempted to get this to work, the app will only run with modules configured in app.module.browser, but the material tags are not getting processed. Trying something simple and trying the button. I don't get any errors but not does it work. I went to their example in Plunker, copied what it generated, and it displays right telling me I got the css in right, at least.

Including the webpack vendor configuration as a starting point, as this seems to be key because how it bundles the css and js.

TIA

Webpack.vendor
const path = require('path');
const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const merge = require('webpack-merge');
const treeShakableModules = [
    '@angular/animations',
    '@angular/common',
    '@angular/compiler',
    '@angular/core',
    '@angular/forms',
    '@angular/http',
    '@angular/platform-browser',
    '@angular/platform-browser-dynamic',
    '@angular/router',
    '@angular/material',
    '@angular/cdk',
    'zone.js'

];
const nonTreeShakableModules = [
    'bootstrap',
    'jqwidgets-framework',
    "@angular/material/prebuilt-themes/indigo-pink.css",
    'bootstrap/dist/css/bootstrap.css',
    'font-awesome/css/font-awesome.css',
    'es6-promise',
    'es6-shim',
    'event-source-polyfill',
    'jquery',
];
const allModules = treeShakableModules.concat(nonTreeShakableModules);

module.exports = (env) => {
    const extractCSS = new ExtractTextPlugin('vendor.css');
    const isDevBuild = !(env && env.prod);
    const sharedConfig = {
        stats: { modules: false },
        resolve: { extensions: [ '.js' ] },
        module: {
            rules: [
                { test: /\.(png|woff|woff2|eot|ttf|svg)(\?|$)/, use: 'url-loader?limit=100000' }
            ]
        },
        output: {
            publicPath: 'dist/',
            filename: '[name].js',
            library: '[name]_[hash]'
        },
        plugins: [
            new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery' }), // Maps these identifiers to the jQuery package (because Bootstrap expects it to be a global variable)
            new webpack.ContextReplacementPlugin(/\@angular\b.*\b(bundles|linker)/, path.join(__dirname, './ClientApp')), // Workaround for https://github.com/angular/angular/issues/11580
            new webpack.ContextReplacementPlugin(/angular(\\|\/)core(\\|\/)@angular/, path.join(__dirname, './ClientApp')), // Workaround for https://github.com/angular/angular/issues/14898
            new webpack.IgnorePlugin(/^vertx$/) // Workaround for https://github.com/stefanpenner/es6-promise/issues/100
        ]
    };

    const clientBundleConfig = merge(sharedConfig, {
        entry: {
            // To keep development builds fast, include all vendor dependencies in the vendor bundle.
            // But for production builds, leave the tree-shakable ones out so the AOT compiler can produce a smaller bundle.
            vendor: isDevBuild ? allModules : nonTreeShakableModules
        },
        output: { path: path.join(__dirname, 'wwwroot', 'dist') },
        module: {
            rules: [
                { test: /\.css(\?|$)/, use: extractCSS.extract({ use: isDevBuild ? 'css-loader' : 'css-loader?minimize' }) }
            ]
        },
        plugins: [
            extractCSS,
            new webpack.DllPlugin({
                path: path.join(__dirname, 'wwwroot', 'dist', '[name]-manifest.json'),
                name: '[name]_[hash]'
            })
        ].concat(isDevBuild ? [] : [
            new webpack.optimize.UglifyJsPlugin()
        ])
    });

    const serverBundleConfig = merge(sharedConfig, {
        target: 'node',
        resolve: { mainFields: ['main'] },
        entry: { vendor: allModules.concat(['aspnet-prerendering']) },
        output: {
            path: path.join(__dirname, 'ClientApp', 'dist'),
            libraryTarget: 'commonjs2',
        },
        module: {
            rules: [ { test: /\.css(\?|$)/, use: ['to-string-loader', isDevBuild ? 'css-loader' : 'css-loader?minimize' ] } ]
        },
        plugins: [
            new webpack.DllPlugin({
                path: path.join(__dirname, 'ClientApp', 'dist', '[name]-manifest.json'),
                name: '[name]_[hash]'
            })
        ]
    });

    return [clientBundleConfig, serverBundleConfig];
}
Earwax answered 20/8, 2017 at 18:22 Comment(0)
S
8

You need to include angular material and cdk in nonTreeShakableModules like:

const treeShakableModules = [
    '@angular/animations',
    '@angular/common',
    '@angular/compiler',
    '@angular/core',
    '@angular/forms',
    '@angular/http',
    '@angular/platform-browser',
    '@angular/platform-browser-dynamic',
    '@angular/router',
    'zone.js',
];
const nonTreeShakableModules = [
    'bootstrap',
    'bootstrap/dist/css/bootstrap.css',
    '@angular/material',
    '@angular/material/prebuilt-themes/indigo-pink.css',
    '@angular/cdk',
    'es6-promise',
    'es6-shim',
    'event-source-polyfill',
    'jquery',
];

Make sure you have installed both angular material and cdk modules from npm with the following 2 commands (animations module is optional):

npm install --save @angular/material @angular/cdk
npm install --save @angular/animations

This should add the following lines in package.json:

"@angular/animations": "https://registry.npmjs.org/@angular/animations/-/animations-4.2.5.tgz",
"@angular/cdk": "^2.0.0-beta.8",
"@angular/material": "^2.0.0-beta.8",

You now should try executing webpack build with following command in cmd or PowerShell:

webpack --config webpack.config.vendor.js

If there are no errors you can include the components you want to use in app.module.shared.ts:

// angular material modules
import {
    MdAutocompleteModule,
    MdButtonModule,
    MdButtonToggleModule,
    MdCardModule,
    MdCheckboxModule,
    MdChipsModule,
    MdCoreModule,
    MdDatepickerModule,
    MdDialogModule,
    MdExpansionModule,
    MdGridListModule,
    MdIconModule,
    MdInputModule,
    MdListModule,
    MdMenuModule,
    MdNativeDateModule,
    MdPaginatorModule,
    MdProgressBarModule,
    MdProgressSpinnerModule,
    MdRadioModule,
    MdRippleModule,
    MdSelectModule,
    MdSidenavModule,
    MdSliderModule,
    MdSlideToggleModule,
    MdSnackBarModule,
    MdSortModule,
    MdTableModule,
    MdTabsModule,
    MdToolbarModule,
    MdTooltipModule,
} from '@angular/material';
import { CdkTableModule } from '@angular/cdk';

and add them to imports in @NgModule

There are still some components that are bugged until next fixes. Like the checkbox component which breaks server-side rendering when you refresh page. But it will be fixed in the next release (it has been already on master branch).

Spanjian answered 22/8, 2017 at 9:42 Comment(0)
P
0

Using latest Angular Material in ASP.net Core 2.0 with default installed node packages is more difficult and time consuming for resolving package dependencies.

Use below version of angular material in package.json

"@angular/cdk": "^2.0.0-beta.12"

"@angular/material": "^2.0.0-beta.12"

followed by run below command to install it.

npm install --save

Phil answered 23/3, 2018 at 10:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.