wearymonkey / ngtemplate-loader Goto Github PK
View Code? Open in Web Editor NEWInclude AngularJS templates in the Webpack bundle and preload the template cache.
License: MIT License
Include AngularJS templates in the Webpack bundle and preload the template cache.
License: MIT License
I'm using webpack in conjunction with oclazyload. Although I see that the html template is properly processed when running webpack, when I load the bundle file using oclazyload and execute $templatecache.get('filename.html'), it returns undefined.
Hi
For the past few days, I have been trying webpack with my current Angular/Express seed app. I got to the point where I was starting to apply production build transformations to the source, such as ngAnnotate and ngTemplates.
So, I got to this loader and installed it and, sadly, have been fighting against it for the past few hours. The loader adds correctly the template entries to the $templateCache service to the webpack bundle, and all is working expectedly.
However, thing is, my Angular app is bootstrapped manually. I need to make an initial request to the server to fetch Application-wide data, and should not be right to bootstrap my app before ensuring I do have that data.
And that's exactly the source of the problem. My manual-bootstrap script is (which is also my webpack entry):
main.coffee
'use strict'
angular = require 'angular'
Dashboard = require './javascripts/app' # Dashboard = 'dashboard'
# Great source on how to bootstrap an AngularJS app manually:
# https://blog.mariusschulz.com/2014/10/22/asynchronously-bootstrapping-angularjs-applications-with-server-side-data
angular.element(document).ready ->
app = angular.module Dashboard
console.log(app)
initInjector = angular.injector [ 'ng' ]
$http = initInjector.get '$http'
# Fetch config data
$http.get '/api/settings'
# Include data in app
.then (res) -> app.constant 'Settings', res.data
# Bootstrap app.
.then -> angular.bootstrap document, [ 'dashboard' ]
javascripts/app
creates dashboard
module, set its config and run blocks and exports its name
The console.log(app)
prints the dashboard
module object, where I can see that its _runBlocks array has only ONE element. Inspecting the element in the broswer's console I can quickly realize that its one element is the run block from javascripts/app
.
So, the run blocks added by this loader are not set at this point and the app gets bootstrapped without the templates cache entries. This run blocks are actually set after the app has bootstrapped but they will never be run by that point.
And that's it. I don't know of any hack to make this work without coding any fix. My only suggestion is to augment the loader configuration with a "create" boolean flag that, if set, exposes a new module named %module=% with the cache entries. That way, I can include the module into my app and ensure that the entries are loaded when I need them.
I wanted to discuss this with you before starting to code a PR, so if you have another ideas, here I am ;)
I'm trying to make my code more pretty by replacing this -
templateUrl: 'foo/bar.template.jade'
with this
templateUrl: 'foo/bar'
Something similar was implemented in PR #35 which was dismissed by @WearyMonkey who said
The same effect can now be achieved with parameter interpolation in 2.0.0.
But even after reading Parameter Interpolation, and subsequently Webpack's standard interpolation rules, I still can't wrap my head around this.
Could anyone please provide some example how this can be achieved?
I'm new into webpack and trying move gulp to webpack. facing issue in "ngtemplate-loader". Below is my webpack config.
const path = require('path');
const webpack = require("webpack");
const optimize = webpack.optimize;
const htmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const config = require('./webpack/config');
var webpackConfig = {
entry: {
vendor: vendorResources,
app: ["./src/app/index.module.ts"]
},
output: {
path: path.resolve(__dirname, "dist"),
filename: "scripts/[name].js",
},
devtool: "source-map",
module: {
rules: [{
test: /\.html$/,
use: [
{ loader: 'ngtemplate-loader?relativeTo=' + (path.resolve(__dirname, './src/app')) },
{ loader: 'html-loader' }
]
},
{
test: /\.ts?$/,
use: [{
loader: 'awesome-typescript-loader'
}, {
loader: 'tslint-loader'
}],
exclude: /node_modules/
}
],
},
resolve: {
extensions: [".ts", ".tsx", ".js", ".json", ".jsx", ".css", ".scss", ".sass"]
},
externals: {},
plugins: [
new ExtractTextPlugin({
filename: (getPath) => {
return getPath('styles/[name].css').replace('js', 'css');
},
allChunks: false
}),
]
}
module.exports = webpackConfig;
Is this MIT ?
I'm trying to get the ngtemplate-loader and baggage working together but keep getting this error:
Module not found: Error: Cannot resolve module 'html' in /app-name/src/directives/directive_name
My folder structure is the same as your README example. Bit stumped!
Hello,
I have a project which one I have different paths from I want to load my templates.
My question is, is there any way to specify different "&relativeTo=" in the config?
A solution for this could be super useful.
Thanks in advance!
We've been using angular for quite a while now, and have always included templates from the app/root director like this
file is at app/pages/page/template.html
templateUrl: 'pages/page/template.html'
your plugin however adds a / infront of it.
Now with the default require, that is not an issue, because we use it like
var templateUrl = require("pages/page/template.html")
templateUrl: templateUrl.
However in case of ng-include
we do require("path/file.html");
ng-include src="'path/file.html'" (does not support an angular variable...
and then it says template not found, for the template suddenly has been registered with a prefixed /
the template loader is included as:
'ngtemplate-loader?relativeTo=' + (path.resolve(__dirname, './app')),
how do we remove this prefixed /??
This is a great loader, I have a strange issue though. I got this to work fine, until I tried moving it to a ES6 modules.
It throws an error that it doesn't know what 'angular.module' is. Offending error is:
'Uncaught TypeError: Cannot read property 'module' of undefined'
from my bundle: 'window.angular.module('ng').run(['$templateCache', function(c) { c.put(path, html) }])'
app.js
require('angular');
require('angular-ui-router');
var app = angular.module('app', ['ui.router']);
app.config(AppConfig);
import AppConfig from './app-config.js';
app-config.js
AppConfig.$inject = ['$stateProvider', '$urlRouterProvider'];
export default function AppConfig($stateProvider, $urlRouterProvider) {
//define an app-wide abstract state for ui-router
$stateProvider.state('app', {
url: '/',
//controller: 'AppController as AppController',
templateUrl: appPartial
});
$urlRouterProvider.otherwise('/');
}
import appPartial from 'ngtemplate!html!./app.partial.html';
This is the error that I get:
Module parse failed: Unexpected token (1:0) You may need an appropriate loader to handle this file type. | <!-- <form class="form-horizontal" name="obqCtrl.forms.deviceOverrideForm"> -->
my loader config is:
{
// to load all the html templates which are required in the application
test: function(filePath) {
var isHtml = /\.html$/.test(filePath);
if (!isHtml) return false;
return paths.isChildOf(filePath, paths.appDir);
},
use: [{
loader: 'ngtemplate-loader?relativeTo=/src/app/',
options: {
minimize: true,
// ignore html comments <!-- -->
ignoreCustomFragments: [/\<\!\-\-.*?-->/]
}
},{
loader: require.resolve('html-loader'),
options: {
minimize: true,
// ignore html comments <!-- -->
ignoreCustomFragments: [/\<\!\-\-.*?-->/]
}
}]
},
I have installed both loaders and its working for files that don't start with a comment. I don't know if this is an issue with ngtemplate-loader or the html-loader.
We are using the ngtemplate-loader, but cannot get it to work even after following the example in the readme. Could you help? https://github.com/ronnross/angular-webpack-example
default to requireAngular enabled
default to relativeTo being the webpack config file dir.
Hi there, I'm not sure it's the correct place to ask for help but probably is something this library could help do,
in js, within webpack with the define plugin you can do:
if (__DEVELOPMENT__) {}
this code is completely removed from build because it will be interpreted as if(false)
, you think it's possible to do the same with this plugin?
Like conditionally include the html for debugging purposes (e.g. dev only buttons) and the source template is removed from build too? Not just hidden from angular?
Thank you for this loader. It does great job. However it leads to some code duplication. Calling require('some.html')
will generate JS code that only adds some.html
to $templateCache
. It would be great if that require()
call would return templateUrl
. It can be very clear on directive example:
require('./stateDebugger.html');
module.directive('stateDebugger', function($state) {
return {
templateUrl: 'shared/directives/stateDebugger.html',
link: function() { /* some code */ }
};
});
As you can see I have to manually set templateUrl
of the directive. It would be great if this would be possible:
templateUrl: require('./stateDebugger.html'),
Hey everyone, I'd like to use the requireAngular
feature but a release hasn't been pushed to NPM yet which contains it.
I have tried a lot of different configuration settings to be able to load my templates like so:
import myTemplateUrl from './hello-angular2-template.thtml';
angular
.module('pd')
.component('helloAngular2', {
templateUrl: myTemplateUrl,
});
However either all I get from the template import is either "undefined" or an error:
ERROR in ./src/components/hello-angular2/hello-angular2-template.thtml
Module parse failed: /home/sfriedrich/dev/ng-webpack/node_modules/ngtemplate-loader/index.js!/home/sfriedrich/dev/ng-webpack/node_modules/html-loader/index.js??ref--0-1!/home/sfriedrich/dev/ng-webpack/src/components/hello-angular2/hello-angular2-template.thtml Unexpected token (2:11)
You may need an appropriate loader to handle this file type.
| var path = '/home/sfriedrich/dev/ng-webpack/src/components/hello-angular2/hello-angular2-template.thtml';
| var html = export default "<div>Angular, from templateURL!</div>";;
| window.angular.module('ng').run(['$templateCache', function(c) { c.put(path, html) }]);
| module.exports = path;
@ ./src/components/hello-angular2/hello-angular2-component.ts 5:38-80
@ ./src/index.ts
@ multi (webpack)-dev-server/client?http://localhost:8375 ./src/index.ts
See example project at https://github.com/eekboom/ng-webpack (and also the stackoverflow question at https://stackoverflow.com/questions/44889493/ ).
Hi,
I use this pagination directive in my app, which make use of partial templates.
I can succesfully load the template, but when parsing it throws an error with any kind of ng-click attributes, in this case ng-click="setCurrent(1)"
:
Error: [$parse:lexerr] Lexer Error: Unexpected next character at columns 0-0 [\] in expression [\"setCurrent(1)\"].
http://errors.angularjs.org/1.3.17/$parse/lexerr?p0=Unexpected%20nextharacter%20&p1=s%200-0%20%5B%5C%5D&p2=%5C%setCurrent(1)%5C%22
at eval (webpack:///./~/angular/angular.js?:63:12)
at Lexer.throwError (webpack:///./~/angular/angular.js?:11950:11)
at Lexer.lex (webpack:///./~/angular/angular.js?:11909:16)
at Parser.parse (webpack:///./~/angular/angular.js?:12070:30)
at $parse (webpack:///./~/angular/angular.js?:12789:39)
at Object.compile (webpack:///./~/angular/angular.js?:21688:20)
at applyDirectivesToNode (webpack:///./~/angular/angular.js?:7530:32)
at compileNodes (webpack:///./~/angular/angular.js?:7071:15)
at compile (webpack:///./~/angular/angular.js?:6978:15)
at applyDirectivesToNode (webpack:///./~/angular/angular.js?:7443:33)
Any help would be appreciated! Kind regards
Maybe related #1?
I've noticed this issue in two projects thus far. The loader will properly stick the template into the cache, but somehow can't retrieve it. So for instance, if this fails:
import template from './template.html';
...
templateURL: template,
...
and this fails:
templateURL: <pasted value of template var>,
but this works:
template: ['$templateCache', function ($templateCache) {
return $templateCache.get(template);
}],
In many cases, the template will properly load for some directives or components and fail for others.
My configuration is as follows:
Entry points to include all templates:
templates: glob.sync("./src/app/**/*.tpl.html"),
Loader to add templates to module:
{
test: /\.tpl\.html$/,
loader: 'ngtemplate?module=myapp.templates&relativeTo=' + (path.resolve(__dirname, '/src/app')) + '/!html'
},
Load order:
Vendor, Templates, App.
This is because the app 'requires' the templates module. I need a way to ask ngtemplate to create the myapp.templates module for me. Is this possible?
If a html template is unable to be compressed by the UglifyJsPlugin, this loader throws a warning, when it should throw an error.
By only throwing a warning the build succeeds even when --bail and the NoErrorsPlugin is configured. Ideally, if the html cannot be compressed an error should be thrown.
Any thoughts or ideas?
I'm trying to run it with baggage-loader
and each time get
Cannot resolve module 'html'
I was wondering what would be the good way to handle templates with ng-include
or ng-messages-include
.
For example, the following code will fail as it tries to load the template without hitting $templateCache
:
<div ng-messages-include="error-messages.html"></div>
I've tried a few things, like writing import errorMessageTemplate from './error-messages.html
in my main module, but it doesn't work :(
Any suggestions?
First of all, thanks for the very useful loader. I'm using ngtemplate-loader in my angular 1.x app. On running with --hot and changing a template html file I can see a log that the loader processes it. But the template in the webapp is not changed. How to get started in extending the above loader or writing a new module which hot reloads such templates?
Hi,
I have used ngtemplate-loader with webpack 1.x and 2.x (upgraded within a day) (using Angular 1)
Upgrading to 2 got me into some trouble.
I was using the helper to load all templates recursively. templateUrl with root.html
was working in 1.x. I had to change it to /root.html
to get it working with webpack 2.x. The missing /
was the problem.
var templates = require.context('./templates', true, /\.html$/);
templates.keys().forEach(function(key) {
templates(key);
});
adding this here so that others can solve the same issue.
Hi, would it be possible to pass raw html instead of a url to use with template:
instead of templateUrl:
For a use case similar to this:
app.config(function($stateProvider) {
$stateProvider
.state('root', {
url: '/',
template: require('./components/root.jade')
});
});
loaders: [
{ test: /\.html$/, loader: 'ngtemplate?raw!html' },
{ test: /\.jade$/, loader: 'ngtemplate?raw!html!jade-html' }
]
Line 8 in b5390e0
DeprecationWarning: loaderUtils.parseQuery() received a non-string value which can be problematic, see https://github.com/webpack/loader-utils/issues/56
parseQuery() will be replaced with getOptions() in the next major version of loader-utils.
Due to a bug nodejs/node#6624 in node 6.x ngtemplate
loader fails on Windows. While doing resource.indexOf(relativeTo)
it cannot find a part of the relative path as indexOf
is case sensitive. Any chance to change it to case insensitive on Windows (or do toLower()
before indexOf()
)?
Hi, I'm trying to build a SPA which load controllers and templates asynchronously. I have a dashboard module like below:
var html = require( './view.html' );
angular.module( 'app' ). controller( 'dashboardCtrl', function(){
/../
});
and in some point I will dynamically load this module:
require.ensure( [ 'dashboard' ], function(){
....
})
In the dev mode, I can see that ngtemplate-loader had generated the correct code, but I can not get the html from $templateCache.get()
, then I hack the source code of ngTemplate-loader
, add some debug code ( like alert(1)
) into the callback of module( 'x' ).run()
, but the hack code is not executed.
I think the problem is that angular.module.run will not be executed again after angular finished its initialization.
I did a little test below:
angular.module( 'app', [] );
angular.module( 'app' ).run(function(){ console.log( 'run 1' ); }); // output: "run 1"
setTimeout(function(){
angular.module( 'app' ).run(function(){
console.log( 'run 2' ); // never executed.
});
}, 1000);
This loader does not work on os x!
always returns ERROR in ReferenceError: window is not defined
.
This is my setup:
loaders: [
{
test: /\.(png|jpg|jpeg|gif)$/,
loader: 'file'
},
{
test: /\.html$/,
loader: 'ngtemplate!html'
},
{ test: /\.json$/, loader: 'json-loader' }
]
Hi,
I'm a bit confused by this loader, I'll try to set up a very straightforward config where all my HTML files are located into a templates folder (see the folder structure below). Thus if I have correctly understood the way this module works, I defined the following config:
webpack.config.js
{
test: /\.html$/,
use: [
{
loader: 'ngtemplate-loader?relativeTo=' + (path.resolve(__dirname, '../templates')),
}
]
}
Folder structure
.
├── app
├── templates
└── ...
When I try to require my templates/root.html
from my angular entry point app/main.js
with the following command:
const rootTpl = require('root.html');
I get the following error:
ERROR in ./app/main.js
Module not found: Error: Can't resolve 'root.html' in '[__dirname]/app'
I don't understand why it tries to resolve the path of my root.html
from /app
instead of /templates
.
Any idea about what is wrong with my configuration? Maybe I'm missing something obvious.
I'm using angular 1.5.11, webpack 3.10.0 and ngtemplate-loader 2.0.1.
Hi!
I've found one problem with the current method of generating the key for template in cache. Given app/component/include.html
and this code
var filePath = path.join(prefix, resource.slice(relativeToIndex + relativeTo.length))
on Windows the generated key will be app\component\include.html
which seems to be bad since I suppose that all template keys should have URL-like separator which is /
.
Wouldn't it be better to always translate the final path to the one with /
as separator ? Like:
var filePath = path.join(prefix, resource.slice(relativeToIndex + relativeTo.length)).replace(pathSepRegex, pathSep);
I am open for discussion :)
Hi, I'm trying to switch my Angular 1.5.3 app to use Webpack 3.10.0 for bundling and using ngtemplate-loader to make angular templates work.
Would appreciate any help since I'm stuck with this for quite a long time.
The problem I'm getting now is strange text which wraps <html></html>
tags in generated html file :
var path = 'C:/source/kjopslosning-smb/ksmb-frontend/app/index-webpack.html';
var html = <!DOCTYPE html>
<html lang="no" class="no-js" ng-app="ksmbApp">
<head>.....</head>
<body>.....</body>
</html>
;
window.angular.module('ng').run(['$templateCache', function(c) { c.put(path, html) }]);
module.exports = path;
+app
+--fonts
+--images
+--styles
+--scripts
+------app.js
+------entry.js
+------controllers
+------sevices
+------directives
+--views (here are all the templates)
+--index-webpack.html
+webpack.config.js
+package.json
var webpack = require('webpack');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const path = require('path');
const extractLess = new ExtractTextPlugin({
filename: "wbpk-bundle.css",
});
const modules = {
rules: [
{
test: /\.html$/,
exclude: /node_modules/,
use: [
{
loader: 'html-loader',
options: {
root: path.resolve(__dirname, './app/images'),
attrs: ['img:src', 'link:href']
}
},
{
loader: 'ngtemplate-loader?relativeTo=' + __dirname + '/app/views',
options: {
exclude: path.resolve(__dirname, './app/index-webpack.html'),
}
},
]
},
{
test: /\.(png|svg|jpg|gif|ico)$/,
use: [
{
loader: 'file-loader',
}
]
},
{
test: /\.less$/,
use: extractLess.extract({
use: [{
loader: "css-loader"
}, {
loader: "less-loader",
}],
// use style-loader in development
fallback: "style-loader"
})
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: [
'file-loader'
]
}
]
};
module.exports = {
entry: path.resolve(__dirname, './app/scripts/entry.js'),
output: {
path: __dirname + '/wdist',
// filename: 'app.bundle.js',
filename: '[name].bundle.js',
publicPath: '/ksmb/app'
},
devtool: 'inline-source-map',
module: modules,
devServer: {
port: 9000,
contentBase: './wdist',
openPage: 'ksmb/app',
hot: false
},
plugins: [
new CleanWebpackPlugin(['wdist']),
new HtmlWebpackPlugin({
filename: 'index.html',
template: path.resolve(__dirname, './app/index-webpack.html'),
}),
extractLess
],
};
Templates are injected in two manners:
Either with ng-include <div ng-include="require('../views/header.html')"></div>
, or like this:
$routeProvider
.when('/about', {
template: require('../views/about.html'),
controller: 'AboutCtrl',
controllerAs: 'aboutCtrl',
title: 'Selskapsinformasjon',
resolve: {
initComplete: initComplete
}
})
});
Generated main.bundle.js
seems to have srtingified templates:
.............................................
/***/ }),
/* 27 */
/***/ (function(module, exports) {
module.exports = "var path = 'C:/source/kjopslosning-smb/ksmb-frontend/app/views/about.html';\nvar html = <section class=\"ffe-section-wrapper\" mg-controller=\"AboutCtrl as aboutCtrl\">\r\n <div class=\"ffe-content-container ffe-content-container--lg ffe-content-container--text-left\">\r\n <a href=\"\" class=\"ffe-link-text ksmb-to-previous\" ng-click=\"aboutCtrl.back()\" ng-bind-html=\"::texts['common.back']\"></a>\r\n </div>\r\n</section>\r\n<section>\r\n <div class=\"ffe-content-container ffe-content-container--text-left content-wrapper\">\r\n <h1 class=\"ffe-h2\" ng-bind-html=\"::texts['about.title']\"></h1>\r\n <p class=\"ffe-body-paragraph\" ng-bind-html=\"::texts['about.insurance.body']\"></p>\r\n <p class=\"ffe-body-paragraph\" ng-bind-html=\"::texts['about.damageinsurance.body']\"></p>\r\n </div>\r\n</section>\r\n;\nwindow.angular.module('ng').run(['$templateCache', function(c) { c.put(path, html) }]);\nmodule.exports = path;";
/***/ }),
/* 28 */
/***/ (function(module, exports) {
module.exports = "var path = 'C:/source/kjopslosning-smb/ksmb-frontend/app/views/terms.html';\nvar html = <section class=\"ffe-section-wrapper\" mg-controller=\"TermsCtrl as termsCtrl\">\r\n <div class=\"ffe-content-container ffe-content-container--lg ffe-content-container--text-left\">\r\n <a href=\"\" class=\"ffe-link-text ksmb-to-previous\" ng-click=\"termsCtrl.back()\" ng-bind-html=\"::texts['common.back']\"></a>\r\n </div>\r\n</section>\r\n<section>\r\n <div class=\"ffe-content-container ffe-content-container--text-left content-wrapper\">\r\n <h1 class=\"ffe-h2\" ng-bind-html=\"::texts['terms.title']\"></h1>\r\n <div ng-bind-html=\"::texts['terms.body']\"></div>\r\n </div>\r\n</section>\r\n;\nwindow.angular.module('ng').run(['$templateCache', function(c) { c.put(path, html) }]);\nmodule.exports = path;";
/***/ }),
...............................................
So page looks like this when webpack-server is started:
:
Please help to get it work
After changing order of loaders (ngtemplate-loader first and html-loader after) I'm getting error:
ERROR in Error: C:\source\kjopslosning-smb\ksmb-frontend\app\index-webpack.html:73
window.angular.module('ng').run(['$templateCache', function(c) { c.put(path, html) }]);
^
ReferenceError: window is not defined
As mentioned in this issue #41 exclude needs to be addded to config. This is confusing to me coz I already have it:
options: {
exclude: path.resolve(__dirname, './app/index-webpack.html')
}
Any thoughts?
please add release notes and a changelog, especially for semver major changes.
Hi,
I've set the configuration as:
module: {
preLoaders: [
{ test: /.js$/, loader: 'baggage?[file].html&[file].css'}
],
loaders: [
// if you're going to do both ng-cache and normal html loading, comment out the two loaders
// and explicitly write the loader type yourself, e.g. require('html!./blah.html') or require('ng-cache!./blah.html')
// { test: /.html$/, loader: "ng-cache-loader" },
// { test: /.html$/, loader: "html-loader" },
{ test: /.css$/, loader: 'style!css'},
{ test: /.scss$/, loader: 'style-loader!css-loader!autoprefixer-loader!sass-loader'},
{ test: /.png$/, loader: 'url-loader?limit=100000&mimetype=image/png'},
{ test: /.jpg$/, loader: 'file-loader'},
{ test: /.html$/, loader: 'ngtemplate-loader?relativeTo=' + __dirname + '/!html'}
]
},
But I'm getting the following error when I attempt to require an html template:
Module not found: Error: Cannot resolve module 'html'
Hi,
thanks for the great work! I got the following error when parsing my template with the loader
Module parse failed: /path/to/my/project/node_modules/ngtemplate-loader/index.js!/path/to/my/project/node_modules/html-loader/index.js?module=snApp&relativeTo=/path/to/my/project/app/controllers/views/Pagelist/list.html Line 1: Unexpected token ;
My template looks as follows and does not contain ";" :
<script type="text/ng-template" id="views.pagelist.list.html"> ... </script>To use loader in requre() call now I have to specify full path including username, i.e. /Users/homemac/Documents/work/projectname/client/src/blocks/app/
and i don't want to using __dirname right in my sources.
This is really bad to store full path in code, so I want to store only piece of path in code, 'src/blocks/app/' for example.
My rendered output looks like this:
I am using angular 1.5 and I am creating components like this:
import angular from 'angular';
const templateUrl = require('ngtemplate!html!./home.html');
angular.module('app.components', [])
.component('home', {
templateUrl: templateUrl
});
And my webpack.config.js looks like this:
'use strict';
// Modules
var webpack = require('webpack');
var autoprefixer = require('autoprefixer');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = function makeWebpackConfig (ENV) {
/**
* Config
* Reference: http://webpack.github.io/docs/configuration.html
* This is the object where all configuration gets set
*/
var config = {};
/**
* Entry
* Reference: http://webpack.github.io/docs/configuration.html#entry
* Should be an empty object if it's generating a test build
* Karma will set this when it's a test build
*/
config.entry = ENV === 'test' ? {} : {
app: './src/app/app.js'
};
/**
* Output
* Reference: http://webpack.github.io/docs/configuration.html#output
* Should be an empty object if it's generating a test build
* Karma will handle setting it up for you when it's a test build
*/
config.output = ENV === 'test' ? {} : {
// Absolute output directory
path: __dirname + '/dist',
// Output path from the view of the page
// Uses webpack-dev-server in development
publicPath: ENV === 'prod' ? '/' : 'http://localhost:8080/',
// Filename for entry points
// Only adds hash in build mode
filename: ENV === 'prod' ? '[name].[hash].js' : '[name].bundle.js',
// Filename for non-entry points
// Only adds hash in build mode
chunkFilename: ENV === 'prod' ? '[name].[hash].js' : '[name].bundle.js'
};
/**
* Devtool
* Reference: http://webpack.github.io/docs/configuration.html#devtool
* Type of sourcemap to use per build type
*/
if (ENV === 'test') {
config.devtool = 'inline-source-map';
} else if (ENV === 'prod') {
config.devtool = 'source-map';
} else {
config.devtool = 'eval-source-map';
}
/**
* Loaders
* Reference: http://webpack.github.io/docs/configuration.html#module-loaders
* List: http://webpack.github.io/docs/list-of-loaders.html
* This handles most of the magic responsible for converting modules
*/
// Initialize module
config.module = {
preLoaders: [],
loaders: [{
// JS LOADER
// Reference: https://github.com/babel/babel-loader
// Transpile .js files using babel-loader
// Compiles ES6 and ES7 into ES5 code
test: /\.js$/,
loader: 'babel',
exclude: /node_modules/
}, {
// CSS LOADER
// Reference: https://github.com/webpack/css-loader
// Allow loading css through js
//
// Reference: https://github.com/postcss/postcss-loader
// Postprocess your css with PostCSS plugins
test: /\.css$/,
// Reference: https://github.com/webpack/extract-text-webpack-plugin
// Extract css files in production builds
//
// Reference: https://github.com/webpack/style-loader
// Use style-loader in development.
loader: ENV === 'test' ? 'null' : ExtractTextPlugin.extract('style', 'css?sourceMap!postcss')
}, {
// ASSET LOADER
// Reference: https://github.com/webpack/file-loader
// Copy png, jpg, jpeg, gif, svg, woff, woff2, ttf, eot files to output
// Rename the file using the asset hash
// Pass along the updated reference to your code
// You can add here any file extension you want to get copied to your output
test: /\.(png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot)$/,
loader: 'file'
}, {
// HTML LOADER
// Reference: https://github.com/webpack/raw-loader
// Allow loading html through js
test: /\.html$/,
loader: 'raw'
}]
};
// ISPARTA LOADER
// Reference: https://github.com/ColCh/isparta-instrumenter-loader
// Instrument JS files with Isparta for subsequent code coverage reporting
// Skips node_modules and files that end with .test.js
if (ENV === 'test') {
config.module.preLoaders.push({
test: /\.js$/,
exclude: [
/node_modules/,
/\.spec\.js$/
],
loader: 'isparta-instrumenter'
})
}
/**
* PostCSS
* Reference: https://github.com/postcss/autoprefixer-core
* Add vendor prefixes to your css
*/
config.postcss = [
autoprefixer({
browsers: ['last 2 version']
})
];
/**
* Plugins
* Reference: http://webpack.github.io/docs/configuration.html#plugins
* List: http://webpack.github.io/docs/list-of-plugins.html
*/
config.plugins = [];
// Skip rendering index.html in test mode
if (ENV !== 'test') {
// Reference: https://github.com/ampedandwired/html-webpack-plugin
// Render index.html
config.plugins.push(
new HtmlWebpackPlugin({
template: './src/public/index.html',
inject: 'body'
}),
// Reference: https://github.com/webpack/extract-text-webpack-plugin
// Extract css files
// Disabled when in test mode or not in build mode
new ExtractTextPlugin('[name].[hash].css', {disable: ENV !== 'prod'})
)
}
// Add build specific plugins
if (ENV === 'prod') {
config.plugins.push(
// Reference: http://webpack.github.io/docs/list-of-plugins.html#noerrorsplugin
// Only emit files when there are no errors
new webpack.NoErrorsPlugin(),
// Reference: http://webpack.github.io/docs/list-of-plugins.html#dedupeplugin
// Dedupe modules in the output
new webpack.optimize.DedupePlugin(),
// Reference: http://webpack.github.io/docs/list-of-plugins.html#uglifyjsplugin
// Minify all javascript, switch loaders to minimizing mode
new webpack.optimize.UglifyJsPlugin(),
// Copy assets from the public folder
// Reference: https://github.com/kevlened/copy-webpack-plugin
new CopyWebpackPlugin([{
from: __dirname + '/src/public'
}])
)
}
/**
* Dev server configuration
* Reference: http://webpack.github.io/docs/configuration.html#devserver
* Reference: http://webpack.github.io/docs/webpack-dev-server.html
*/
config.devServer = {
contentBase: './src/public',
stats: {
modules: false,
cached: false,
colors: true,
chunk: false
}
};
return config;
}();
Hello, first let me thank you for this awesome plugin, it really does help a lot.
While my setup currently works, I was wondering if there's a way to output all required templates into a separate file (templates.js) automatically.
My webpack.config.js:
var path = require("path");
var webpack = require("webpack");
module.exports = {
entry: {
app: path.resolve(__dirname, 'app/src/app.js'),
vendors: [
'angular',
'angular-ui-router',
'angular-bootstrap',
'angular-cookies',
'angular-slugify',
'chartjs',
'tc-angular-chart',
'angular-breadcrumb',
'ng-notifications-bar',
'lodash',
'restangular',
'ng-tags-input'
]
},
output: {
path: path.resolve(__dirname, 'build'),
filename: 'app.js'
},
resolve: {
root: [
path.resolve(__dirname, "bower_components")
],
alias: {
component: path.resolve(__dirname, "app/src"),
root: path.resolve(__dirname)
}
},
plugins: [
new webpack.ResolverPlugin(
new webpack.ResolverPlugin.DirectoryDescriptionFilePlugin("bower.json", ["main"])
),
new webpack.optimize.CommonsChunkPlugin('vendors', 'vendors.js')
],
module: {
loaders: [
{
test: /\.json/,
loader: "json-loader"
},
{
test: /\.scss/,
loader: "style!css!sass"
},
{
// angularjs doesn't properly export a CommonJS module, so we need to manually export the variable
test: /[\/]angular\.js$/,
loader: "exports?angular"
},
{
test: /\.html$/,
loader: "ngtemplate?relativeTo=" + (path.resolve(__dirname)) + "/!html"
}
]
}
};
As you can see I already have to explicitly define the vendors (which I'd also like to somehow get rid of but that's for another time), so I don't want to get into the same business with templates.
My templates are scattered "randomly" inside the app/src directory, under the component-name/_resources/views/ path if that matters.
Sorry if it doesn't really belong here, I'm new to webpack and there's so many parties that I don't even know who to ask which question :/
Hi,
I am using oclayload for load module lazily, and make split chunks using web pack. Some directive depends on lazily load the module when any state invoke, In directive have templatedUrl these are not registered lazily and showing 404 not found file.html.
As we know, the windows path separator is dramatic different from other systems. So shouldn't we handle it in this loader?
Say I have 3 entry points:
config.entry = {
"a": [root("modules/a")],
"b": [root("modules/b")],
"c": [root("modules/c")]
};
I'd like to be able to create template modules for each of these:
// angular.module('aTemplates').run(['$templateCache', ...
// angular.module('bTemplates').run(['$templateCache', ...
// angular.module('cTemplates').run(['$templateCache', ...
Is this possible?
When using webpack 3.5.2
with loader options
configured instead of query
:
(node:15402) DeprecationWarning: loaderUtils.parseQuery() received a non-string value which can be problematic, see https://github.com/webpack/loader-utils/issues/56
parseQuery() will be replaced with getOptions() in the next major version of loader-utils.
at Object.parseQuery (/plethora/frontend/node_modules/loader-utils/index.js:78:3)
at Object.module.exports (/plethora/frontend/node_modules/ngtemplate-loader/index.js:8:29)
at LOADER_EXECUTION (/plethora/frontend/node_modules/loader-runner/lib/LoaderRunner.js:119:14)
at runSyncOrAsync (/plethora/frontend/node_modules/loader-runner/lib/LoaderRunner.js:120:4)
at iterateNormalLoaders (/plethora/frontend/node_modules/loader-runner/lib/LoaderRunner.js:229:2)
at iterateNormalLoaders (/plethora/frontend/node_modules/loader-runner/lib/LoaderRunner.js:218:10)
at /plethora/frontend/node_modules/loader-runner/lib/LoaderRunner.js:233:3
at runSyncOrAsync (/plethora/frontend/node_modules/loader-runner/lib/LoaderRunner.js:130:11)
at iterateNormalLoaders (/plethora/frontend/node_modules/loader-runner/lib/LoaderRunner.js:229:2)
at Array.<anonymous> (/plethora/frontend/node_modules/loader-runner/lib/LoaderRunner.js:202:4)
Relevant Configuration:
{
//...
modules: {
//...
loaders: [
//...
{
loader: 'ngtemplate-loader',
options: {
relativeTo: '/public/',
prefix: '/',
},
},
//...
],
//...
}
//...
}
I want use require
function inside template, there's an example of usage:
<div data-ng-include="require('myApp/templates/directive.html')"></div>
After processing of this template by wepback, module with this template will look like this:
function(module, exports) {
var path = '/some/prefix/path/myApp/templates/directive.html';
window.angular.module('ng').run(['$templateCache', function(c) {
c.put(path, "<div data-ng-include=\"require('myApp/templates/directive.html')\"></div>")
}]);
module.exports = path;
}
But require function should be replaced by webpack_require function and the result module should be like this:
function(module, exports) {
var path = '/some/prefix/path/myApp/templates/directive.html';
window.angular.module('ng').run(['$templateCache', function(c) {
c.put(path, "<div data-ng-include=\"'" + __webpack_require__(123) + "'\"></div>")
}]);
module.exports = path;
}
Additionally, require
function can be used not only in ng-include
, ng-inline
directives, it can be used in other custom attributes also.
When I run npm run server to start the webpack dev server, it report the error such as below:
Error: E:\js-test\Angularjs-ES6-Demo\src\script\index.html:76
window.angular.module('ng').run(['$templateCache', function(c) { c.put(path, h tml) }]);
^
ReferenceError: window is not defined
- index.html:76 Object.
E:/js-test/Angularjs-ES6-Demo/src/script/index.html:76:1
- index.html:21 __webpack_require__
E:/js-test/Angularjs-ES6-Demo/src/script/index.html:21:30
- index.html:67 path
E:/js-test/Angularjs-ES6-Demo/src/script/index.html:67:18
- index.html:70
E:/js-test/Angularjs-ES6-Demo/src/script/index.html:70:10
- index.js:231 HtmlWebpackPlugin.evaluateCompilationResult
[Angularjs-ES6-Demo]/[[email protected]@html-webpack-plugin]/inde x.js:231:26
- index.js:117
[Angularjs-ES6-Demo]/[[email protected]@html-webpack-plugin]/inde x.js:117:21
- util.js:16 tryCatcher
[Angularjs-ES6-Demo]/[[email protected]@bluebird]/js/release/util.js:16:23
- promise.js:512 Promise._settlePromiseFromHandler
[Angularjs-ES6-Demo]/[[email protected]@bluebird]/js/release/promise.js:512:3 1
- promise.js:569 Promise._settlePromise
[Angularjs-ES6-Demo]/[[email protected]@bluebird]/js/release/promise.js:569:1 8
I'v been install the html-loader and ngtemplate-loader, and the relative webpack.config.js is:
module: {
rules: [
{
test: /\.scss$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: ["css-loader", 'sass-loader']
})
},// ['style-loader', 'css-loader', 'sass-loader']
{
test: /\.js$/,
exclude: /node_modules/,
use: ['ng-annotate-loader','babel-loader']
},
{
test: /\.html$/,
use: [
{ loader:'ngtemplate-loader?relativeTo=' + (path.resolve(__dirname, './src/')) },
{ loader: 'html-loader' }
]
}
]
},
Sorry I don't really have any sort of log output, since Webpack will just idle for ages whenever UglifyJS2 gets a hold of invalid HTML. Some of the causes we've had that triggered this:
<div><div></div>
or some suchclass""
instead of class=""
This wouldn't be such an issue, except the log doesn't indicate any issues at all. Is there a way to see the JavaScript strings in a verbose mode output to the logs just as a sanity check?
I'm trying to set up a loader in my webpack.config juste like advised in the readme of the repo, but I can't get it to work.
My project is structured like this:
src/
└── app/
├── app.js
└── streams/
├── streams.js
└── templates/
└── streams.html
I'm doing all my requires in streams.js.
When I require the template this way it works:
//var templateUrl = require('!ngtemplate!html!./templates/streams.html');
My loader is defined like so:
loaders: [
{
test: /\.html$/,
loader: 'ngtemplate?relativeTo=' + (path.resolve(__dirname, './app')) + '/!html'
}
]
I have tried to require my template in various ways, and it does not work:
var templateUrl = require('./templates/streams.html');
var templateUrl = require('streams.html');
I get exactly the same error if I don't have any loader defined for html files.
ERROR in ./src/app/streams/templates/streams.html
Module build failed:
@ ./src/app/streams/streams.js 4:18-53
Any ideas ?
I have a folder full of SVGs that I want to load with ngtemplate-loader
. When I require them individually, everything works great, but when I try to require the entire folder by putting require.context('.', false, /\.svg$/);
in an index.js
file, ngtemplate-loader
fails silently without adding them to $templateCache
. The dynamic require works fine with e.g. file-loader
, but I'm having trouble debugging this combination.
Throwing a string does not appear to be supported with the output of webpack. This code should throw a new Error
instance with the message set to 'The path for file doesn\'t contains relativeTo param'
Anytime I try a relativeTo
path I get this error:
ModuleBuildError: Module build failed:
at DependenciesBlock.onModuleBuildFailed (/Users/dave/domo/domoweb/DomoWeb/node_modules/webpack/node_modules/webpack-core/lib/NormalModuleMixin.js:315:19)
at nextLoader (/Users/dave/domo/domoweb/DomoWeb/node_modules/webpack/node_modules/webpack-core/lib/NormalModuleMixin.js:270:31)
at /Users/dave/domo/domoweb/DomoWeb/node_modules/webpack/node_modules/webpack-core/lib/NormalModuleMixin.js:292:15
at runSyncOrAsync (/Users/dave/domo/domoweb/DomoWeb/node_modules/webpack/node_modules/webpack-core/lib/NormalModuleMixin.js:173:4)
at nextLoader (/Users/dave/domo/domoweb/DomoWeb/node_modules/webpack/node_modules/webpack-core/lib/NormalModuleMixin.js:290:3)
at /Users/dave/domo/domoweb/DomoWeb/node_modules/webpack/node_modules/webpack-core/lib/NormalModuleMixin.js:292:15
at runSyncOrAsync (/Users/dave/domo/domoweb/DomoWeb/node_modules/webpack/node_modules/webpack-core/lib/NormalModuleMixin.js:160:12)
at nextLoader (/Users/dave/domo/domoweb/DomoWeb/node_modules/webpack/node_modules/webpack-core/lib/NormalModuleMixin.js:290:3)
at /Users/dave/domo/domoweb/DomoWeb/node_modules/webpack/node_modules/webpack-core/lib/NormalModuleMixin.js:259:5
at Storage.finished (/Users/dave/domo/domoweb/DomoWeb/node_modules/webpack/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:38:16)
at /Users/dave/domo/domoweb/DomoWeb/node_modules/webpack/node_modules/enhanced-resolve/node_modules/graceful-fs/graceful-fs.js:76:16
at FSReqWrap.readFileAfterClose [as oncomplete] (fs.js:404:3)
I've tried the following:
loader: "ngtemplate?module=mason&relativeTo=mason!html"
loader: "ngtemplate?module=mason&relativeTo=/public/mason/!html"
loader: "ngtemplate?module=mason&relativeTo="+__dirname +"/public/mason/!html"
It would be nice if all query params could be processed via loaderUtils.interpolateName()
like it does file-loader. Also it would be nice if developers can use some placeholders for instance like baggage-loader.
It would be very useful when you have more then one module and you don't need to create ngtemplate-loader
for each of them.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.