Duke Cyrillus
Duke Cyrillus

Reputation: 1237

Using Webpack in an MVC 5 Angular 2 application

I created a very basic MVC 5 Angular 2 app which works fine if I use SystemJS. However, I wanted to be able to bundle my code so I could add it to my BundleConfig file and decided to look into Webpack. I've got it to a point where I can generate the bundles and save them to disk (using webpack --watch) but when I include them in my BundleConfig it doesn't work because it's unable to find the templates for the component.

So the question is: Is there a better way to do this? What I mean is - I want to stick with MVC 5, use Visual Studio (which means using the VS Typescript compiler) and be able to bundle my js/css files.

I'm quite new to this framework (Angular 2/ Webpack etc.) so please let me know if you need more information.

Thanks!

Not sure how helpful this would be but here is the webpack config:

webpack.config.js

module.exports = require('./Config/webpack.dev.js');

webpack.dev.js

var webpack = require('webpack');
var webpackMerge = require('webpack-merge');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var commonConfig = require('./webpack.common.js');
var helpers = require('./helpers');

const ENV = process.env.NODE_ENV = process.env.ENV = 'production';

module.exports = webpackMerge(commonConfig, {
    devtool: 'source-map',

    output: {
        path: helpers.root('dist'),
        publicPath: 'http://localhost:64005',
        filename: '[name].js',
        chunkFilename: '[id].[hash].chunk.js'
    },

    plugins: [
        new webpack.NoEmitOnErrorsPlugin(),
        new ExtractTextPlugin('[name].css'),
        //new webpack.DefinePlugin({
        //    'process.env': {
        //        'ENV': JSON.stringify(ENV)
        //    }
        //})
        //new webpack.LoaderOptionsPlugin({
        //    htmlLoader: {
        //        minimize: false // workaround for ng2
        //    }
        //})
    ]
});

webpack.common.js

var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var helpers = require('./helpers');

module.exports = {
    entry: {
        'polyfills': './Config/polyfills.js',
        'vendor': './Config/vendor.js',
        'app': './App/main.js'
    },
    resolve: {
        extensions: ['.js']
    },
    module: {
        rules: [
            //{
            //    test: /\.ts$/,
            //    loaders: [
            //        {
            //            loader: 'awesome-typescript-loader',
            //            options: { configFileName: helpers.root('', 'tsconfig.json') }
            //        }, 'angular2-template-loader'
            //    ]
            //},
            {
                test: /\.html$/,
                loader: 'html-loader'
            },
            {
                test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,
                loader: 'file-loader?name=Content/[name].[hash].[ext]'
            },
            {
                test: /\.css$/,
                exclude: helpers.root('', 'App'),
                loader: ExtractTextPlugin.extract({ fallbackLoader: 'style-loader', loader: 'css-loader?sourceMap' })
            },
            {
                test: /\.css$/,
                include: helpers.root('', 'App'),
                loader: 'raw-loader'
            }
        ]
    },

    plugins: [
        // Workaround for angular/angular#11580
        //new webpack.ContextReplacementPlugin(
        //    // The (\\|\/) piece accounts for path separators in *nix and Windows
        //    /angular(\\|\/)core(\\|\/)(esm(\\|\/)src|src)(\\|\/)linker/,
        //    helpers.root('./'), // location of your src
        //    {} // a map of your routes
        //),

        new webpack.optimize.CommonsChunkPlugin({
            name: ['app', 'vendor', 'polyfills']
        })

        //new HtmlWebpackPlugin({
        //    template: 'Views/Shared/_Layout.cshtml'
        //})
    ]
};

UPDATE: Just to clarify, here's the process I want to have: 1. Visual Studio transpiles the .ts files (As far as I know there isn't an easy way to tell Visual Studio to use the Typescript compiler from node_modules instead of its own). 2. Webpack creates bundles from all the transpiled js files, which is working. 3. BundleConfig makes those bundles available.

The above process is working except that the template files aren't being served. If I use inline templates and css it works just fine.

So maybe a more specific question would be: How do I use webpack to either add the templates/styles inline (Dunno if that's even possible) or serve those files in such a way that the components can find and load them?

Upvotes: 2

Views: 3171

Answers (2)

Duke Cyrillus
Duke Cyrillus

Reputation: 1237

I was able to solve this issue by uncommenting the awesome-typescript-loader rule in the webpack.common.js file. Using that plugin allows me to load template/style URLs.

Upvotes: 1

wannadream
wannadream

Reputation: 1760

Have you tried this? https://marketplace.visualstudio.com/items?itemName=MadsKristensen.WebPackTaskRunner

I am using NPM in my current Angular project. We are using Visual Studio Team Services to implement build and deployment automation. Within build process, I added PowerShell Script by using npm command to compile Angular code.

I am studying Webpack as well for my next project with Vue.js. It's a strong tool and adopted by large companies, like Facebook. I will not draw any hasty conclusions since we already have a solid build ecosystem.

Anyway, you build process on front-end can be isolated from your MVC 5 code.In Visual Studio, you can use TypeScript compiler but I do not recommend it as in most cases, we will have other JS/CSS libraries involved. TypeScript compiler is not the tool for bundling, packaging and building.

Upvotes: 0

Related Questions