Say i have the following component. Using webpack it's bundled together. The template is required, so it is inlined.
@Component({
selector: 'date-picker',
template: require('./date-picker.html'),
})
This however means that it is tedious to change the markup as i have to go through the bundle process which takes ~5-10 seconds on my machine at best. What I'd like would be to keep the require on the template on production build, but have a template url during development so i can change the markup without having to bundle. But when the production bundle is created, all the templates are inlined into the bundle.
Is there a way to make this happen? Would the best approach be to create my own webpack plugin? Does such not exist already?
Best regards Morten
I ended up creating my own loader for Webpack that uses regex to search and replace template: require('.some.html') with templateUrl that points to the file in the same folder. Works for both mac and windows. Only requirement is that both the typescript file and the html file needs to be in the same folder. This would then only be applied to development builds where you don't want to run webpack everytime you change your markup files. For prod, the require would still inline the template in the bundle.
The content of my loader ended up looking like the code below. Hooked up as a webpack loader.Documentation for loaders in webpack
/*
This loader can replace template: require to templateUrls for angular components as long as they live inside the
same folder as the component itself. This is in particular very useful for development builds to avoid having to
run webpack everytime you change an html file.
*/
module.exports = function(source) {
//If there's no match, we're not processing a Component file.
var groups = source.match(`template: require\\('.*.html.*'\\)`);
if (groups == null)
{
return source;
}
var resourcePath = this.resourcePath;
var regex = new RegExp(/\//g);
//To support OSX and win paths we replace / which is part of OSX paths to process the same way.
resourcePath = resourcePath.replace(regex,'\\');
//Find a relative path to the resource relative to the apps folder.
var relativePathForAppsFolder = resourcePath.substr(resourcePath.indexOf('\\app\\'))
relativePathForAppsFolder = relativePathForAppsFolder.replace(/\\/g,'/');
//Get the path without the filename to support html files and js files not sharing the same name minus the extension.
var pathWithoutFolder = relativePathForAppsFolder.substr(0, relativePathForAppsFolder.lastIndexOf('/'))
//To support having different names on the file and ts file we take the content of the group in our regex which would be the html file name.
var matchedString = groups[0].split('\'');
var value = matchedString[1];
value = value.replace('./','');
var combined = pathWithoutFolder + '/' + value;
//now we're changing to template url for dev builds instead of inline inside webpack bundle.
source = source.replace(/template: require\('.*.html.*'\)/,'templateUrl: \'' + combined + '\'')
return source;
}