Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 1.X, webpack and ngtemplate loader issue

I’ve been introduced recently to Webpack and I’ve been trying to put a starter pack for Angular 1 and Webpack with ES6. So far so god. I’m able to create things like this:

import angular from 'angular';
import uiRouter from 'angular-ui-router';
import ngAnimate from 'angular-animate';
import ngAria from 'angular-aria';
import ngMessages from 'angular-messages';
import ngMaterial from 'angular-material';

import UserModule from './modules/user';

const MODULE_NAME = 'nukehome';

const ngModule = angular.module(MODULE_NAME, [
  uiRouter,
  ngAnimate,
  ngAria,
  ngMessages,
  ngMaterial,
  UserModule.name
]);

Which I personally really like.

However, issue comes with ngtemplate-loader. My web pack config looks like this one:

webpack: {
  context: '<%= ui %>/js',
      entry: ['babel-polyfill', './index.js'],
      output: {
    path: '<%= build %>/js',
        filename: '<%= package.name %>.js'
  },
  module: {
    loaders: [
      {
        test: /\.html$/,
        loader: 'ngtemplate?relativeTo=' + (path.resolve(__dirname, './static/js')) + '/!html'
      },
      {
        test: /\.js$/,
        exclude: /(node_modules|bower_components)/,
        loader: 'ng-annotate',
        query: {
          map: false
        }
      }, {
        test: /\.js$/,
        exclude: /(node_modules|bower_components)/,
        loader: 'babel',
        query: {
          cacheDirectory: true,
          presets: ['es2015']
        }
      }
    ]
  }

However, whenever I try to do something like this:

import angular from 'angular';
import uiRouter from 'angular-ui-router';

import userCreateTemplate from './user-create.html';

const MODULE_NAME = 'nukehome.user';

const ngModule = angular.module(MODULE_NAME, [
  uiRouter
]);

ngModule.config(function($stateProvider, $urlRouterProvider) {
  $stateProvider
      .state('user', {
        url: '/user/',
        templateUrl: userCreateTemplate,
        controller: function() {
          console.log('Hi user');
        }
      });

  $urlRouterProvider.otherwise('/404/');
});

export default ngModule;

It fails miserably with this error:

ERROR in ./static/js/modules/user/index.js
Module not found: Error: Cannot resolve module '.modules/user/user-create.html' in /Users/alaguna/project/static/js/modules/user
 @ ./static/js/modules/user/index.js 15:18-75

I’ve tried with require too and the output seems to be the same. Here’s the tree:

├── Gruntfile.js
├── app.js
├── bin
│   └── www
├── config
│   └── config.json
├── content
│   └── data
│       └── nukehome.db
├── core
│   ├── models
│   │   ├── device.js
│   │   ├── index.js
│   │   └── user.js
│   └── server
│       ├── auth.js
│       └── utils
│           └── gravatar.js
├── grunt
│   ├── develop-tasks.yaml
│   ├── scripts-tasks.yaml
│   ├── styles-tasks.yaml
│   └── webpack.js
├── package.json
├── public
│   ├── css
│   │   └── nukehome.css
│   └── js
│       └── nukehome.js
├── static
│   ├── css
│   │   └── nukehome.css
│   ├── js
│   │   ├── app.controller.js
│   │   ├── index.js
│   │   └── modules
│   │       └── user
│   │           ├── index.js
│   │           └── user-create.html
│   └── scss
│       └── nukehome.scss
└── views
    ├── error.hbs
    ├── index.hbs
    └── layout.hbs

My main question is, is there anything I can do to see how ngtemplate-loader is storing the paths internally (or serving them to webpack)?

Is there something that strikes out as being wrong?

I know I could use other ways to get this done such as run any grunt|gulp task that outputs a module with the template and concat it with the rest of the files. However I do like how composable this is.

EDIT: I've uploaded this to Github so anyone can play with this.

like image 499
Antonio Laguna Avatar asked Apr 28 '16 20:04

Antonio Laguna


1 Answers

The template you are trying to require lives alongside the .js files that requires it. Thus, the correct relative path to that template is just ./user-create.html. Also, your webpack config already defines ngtemplate and html loaders for your .html files so you should only have to do

import userCreateTemplate from './user-create.html';

Note that .modules is a valid a file or folder name. You probably meant ./modules.

Your relativeTo parameter is also wrong. Since your webpack config is located inside of grunt, path.resolve(__dirname, './static/js') will resolve to /path/to/project/grunt/static/js. You should use either path.resolve(__dirname, '../static/js') or path.resolve('./static/js') instead.

like image 77
Alexandre Kirszenberg Avatar answered Sep 20 '22 14:09

Alexandre Kirszenberg