4

I have a monolith project made with AngularJS using Webpack but I'm getting an error saying: Unexpected token < main.html. This error occurs when I have this line of code in one of my controllers:

 import templateUrl from './main.html';

From my understanding, it looks to me that Webpack does not bundle correctly my HTML template. the < symbol is coming from the main.html template, it is found with success but not parsed. I then thought about using html-loader and use it that way:

 import templateUrl from 'html-loader!./main.html';

To my great surprise, this does not solve the issue.

I am using Webpack version "webpack": "^3.4.1", and this is my config:

const path = require('path');
const webpack = require('webpack');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const ContextReplacementPlugin = 
require('webpack/lib/ContextReplacementPlugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');

const nodeEnv = process.env.NODE_ENV || 'development';
const isProd = nodeEnv === 'production';

const styles = [
 'css-loader?importLoaders=1',
 'postcss-loader',
 'sass-loader'
];

module.exports = {
 entry: {
    'root-application': 'src/root-application/root-application.js',
},
output: {
    publicPath: '/dist/',
    filename: '[name].js',
    path: path.resolve(__dirname, 'dist'),
},
module: {
    rules: [
        {
            test: /\.scss$/,
            use: !isProd
                ? [
                    'style-loader',
                    ...styles
                ]
                : ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: styles
                }),
            exclude: /(node_modules)/
        },
        {
            test: /\.(png|woff|woff2|eot|ttf|svg)$/,
            use: ['url-loader?limit=100000']
        },
        {
            test: /\.html$/,
            use: [
                'ngtemplate-loader',
                'html-loader'
            ],
            exclude: /(index)/
        },
        {
            test: /\.js?$/,
            exclude: /(node_modules)/,
            loader: 'babel-loader',
        },
        {
            test: /\.tsx?$/,
            loader: 'ts-loader',
        },
    ],
},
node: {
    fs: 'empty'
},
resolve: {
    modules: [
        __dirname,
        'node_modules',
    ],
},
plugins: [
    new CleanWebpackPlugin(['dist']),
    new webpack.optimize.CommonsChunkPlugin({
        name: 'common-dependencies',
    }),
    new ContextReplacementPlugin(
        /(.+)?angular(\\|\/)core(.+)?/,
        path.resolve(__dirname, '../src')
    )
],
devtool: 'source-map',
externals: [],
devServer: {
    historyApiFallback: true
 }
};

I've checked other SO topic about Unexpected token <, I am sure that there is no 404 - Not found error in my network tab.

3
  • we have code like this: import controller from './ctrl.ctrl'; component = { bindings: { }, controller: controller, template: require('./template.html') }; [So require for html instead of import] Commented Jul 18, 2018 at 13:03
  • @PetrAveryanov Why this should matter? There is plenty of example importing HTML template with import keyword in AngularJS app. But I give it a try since I ran out of ideas. Commented Jul 18, 2018 at 13:08
  • @PetrAveryanov I tried and for some reason it will now append .js to all my HTML file which result to an error - 404 not found. I'm not sure this is a right thing to do. Commented Jul 18, 2018 at 13:45

2 Answers 2

4

This is fundamentally taking the problem from a different tack, by not using the templateUrl property to load your directive's templates, but I've used this angularjs & webpack configuration to great effect; it also saves HTTP requests, by inlining the templates.

// webpack.config.js

module.exports = {
  // ...
  module: {
    rules: [
      // Load raw HTML files for inlining our templates
      { test: /\.(html)$/, loader: "raw-loader" },
      // ... other rules, config, etc.
    ]
  }
}

Then, in a directive file:

import templateString from './wherever.template.html'

function directiveFunc() {
  return {
    // template, rather than templateUrl   
    template: templateString,
    // ...
  }
}

export default directiveFunc

Install the raw-loader loader with:

$ npm install raw-loader --save-dev
Sign up to request clarification or add additional context in comments.

Comments

0

you may want to use angular2-template-loader instead of the generic one.

3 Comments

Think that I'm not using Angular but AngularJS.
Your dependencies clearly say you are, but anyway, there is a similar package for ng1
You're right, this is because I'm prototyping single-spa and will need it for later.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.