bunjeeb
bunjeeb

Reputation: 1155

How to compile angular 2 webpack by keeping 'templateurl' as is

Webpack is compiling 'typescript' files by generating 'js' in dist folder. I found that webpack is changing all 'templateurl' to 'template' like this:

My Typescript Component:

@Component({
selector: 'app',
encapsulation: ViewEncapsulation.None,
templateUrl: 'app.html', // <----------------------
directives: [HeaderComponent, SideBar],
})

Here the auto generated compiled JS Component

App = __decorate([
        core_1.Component({
            selector: 'app',
            encapsulation: core_1.ViewEncapsulation.None,
            template: __webpack_require__(718),// <----------
            directives: [header_component_1.HeaderComponent, sidebar_component_1.SideBar],
        }), 
        __metadata('design:paramtypes', [(typeof (_a = typeof app_service_1.AppState !== 'undefined' && app_service_1.AppState) === 'function' && _a) || Object])
    ], App);

What I want to do is just to keep using 'templateUrl' even in the generated file.

I'm using asp.net mvc, I have a lot of CSHTML files and I want to keep using it. I want to change how webpack is compiling the 'ts' and ignore the idea of 'taking the content of that html'. So I'm expecting:

App = __decorate([
        core_1.Component({
            selector: 'app',
            encapsulation: core_1.ViewEncapsulation.None,
            templateUrl: 'app.html', // <----------------------
            directives: [header_component_1.HeaderComponent, sidebar_component_1.SideBar],
        }), 
        __metadata('design:paramtypes', [(typeof (_a = typeof app_service_1.AppState !== 'undefined' && app_service_1.AppState) === 'function' && _a) || Object])
    ], App);

I tried to change the auto generated file manually like this. and it works. I want to keep templateUrl.

Upvotes: 4

Views: 1164

Answers (1)

Shlomi Assaf
Shlomi Assaf

Reputation: 2236

Webpack is not doing that. If such a thing is done, you probably have a loader that does that.

You are probably using a starter kit with pre-configured webpack configuration. My best bet is that you are using angular2-webpack-starter.

In angular2-webpack-starter there is a plugin called angular2-template-loader that is used to convert Component.templateUrl to Component.template by changing the literal string (i.e: path to html) into a require statement.

This process inlines all html and style's, so it's not only for html templates but for styleUrls as well.

To remove this feature, in you webpack configuration file change this:

  module: {
    loaders: [
      {
        test: /\.ts$/,
        loaders: ['awesome-typescript-loader', 'angular2-template-loader'],
        exclude: [/\.(spec|e2e)\.ts$/]
      }
    ]
  }

To this:

  module: {
    loaders: [
      {
        test: /\.ts$/,
        loaders: ['awesome-typescript-loader'],
        exclude: [/\.(spec|e2e)\.ts$/]
      }
    ]
  }

That is, remove the loader that does the inlining (angular2-template-loader)

If you want to get deeper, here is the part of the code of angular2-template-loader:

  var newSource = source.replace(templateUrlRegex, function (match, url) {
                 // replace: templateUrl: './path/to/template.html'
                 // with: template: require('./path/to/template.html')
                 return "template:" + replaceStringsWithRequires(url);
               })
               .replace(stylesRegex, function (match, urls) {
                 // replace: stylesUrl: ['./foo.css', "./baz.css", "./index.component.css"]
                 // with: styles: [require('./foo.css'), require("./baz.css"), require("./index.component.css")]
                 return "styles:" + replaceStringsWithRequires(urls);
               });

  // Support for tests
  if (this.callback) {
    this.callback(null, newSource, sourcemap)
  } else {
    return newSource;
  }
};

You can see in the comments that this is exactly the issue you have. You can also view the source code

It should be noted that opting-out of inlining will result in a performance hit. Your app will have to perform more http requests and your HTML markup (template) will stay at it's raw form. In other words, the HTML code you write will not get the optimizations provided by webpack. I do not recommend opting-out of this loader

Upvotes: 5

Related Questions