New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Webpack] Using Jade instead of HTML results in runtime errors #396

Closed
Svenskunganka opened this Issue Apr 9, 2016 · 15 comments

Comments

Projects
None yet
4 participants
@Svenskunganka

Svenskunganka commented Apr 9, 2016

As Webpack doesn't re-write/transpile .jade-files to .html, Aurelia gives a runtime error that it cannot find file.html.

Unhandled rejection Error: Cannot find module './app.html'.
    at eval (webpack:///./src_^\.\/.*$?:101:41)
    at webpackContextResolve (webpack:///./src_^\.\/.*$?:101:89)
    at webpackContext (webpack:///./src_^\.\/.*$?:98:29)
    at eval (webpack:///./~/aurelia-loader-webpack/dist/commonjs/aurelia-loader-webpack.js?:94:49)
    at http://localhost:3000/bundle.js:125:24
    ...

Is there any configuration options to make Aurelia look for .jade instead of .html?

For example, in the bootstrap function, making

aurelia.start().then(() => aurelia.setRoot('app', document.body))

look for app.jade instead of app.html.

@EisenbergEffect

This comment has been minimized.

Member

EisenbergEffect commented Apr 9, 2016

I don't think this relates to Aurelia really. What you want to do is configure webpack to compile your jade views to html. There should be a way to set that up with a plugin.

@Svenskunganka

This comment has been minimized.

Svenskunganka commented Apr 9, 2016

@EisenbergEffect I do have a Jade Webpack compiler setup already, but in the end the sourcemaps will always say app.jade and not app.html, even though importing app.jade returns a string of HTML.

Looking at the bundle (I added an app.html-file to show the different results):

var map = {
  "./app": 14,
  "./app.html": 15,
  "./app.jade": 16,
  "./app.js": 14,
  "./aurelia-bootstrapper-webpack": 2,
  "./aurelia-event-aggregator": 17,
  ........


........

/* 15 */
/***/ function(module, exports) {

    module.exports = "<template>\n  <router-view></router-view>\n</template>\n";

/***/ },
/* 16 */
/***/ function(module, exports) {

    module.exports = "<template><router-view></router-view></template>";

/***/ },

Let's take the the Aurelia gulp environment as an example to illustrate how different Webpack handles source files.
Let's say I use Stylus, and in the gulp project I transpile stylus to css, and to import it I would do <require from="style.css">.
With Webpack, I would have to do <require from="style.styl"> as Webpack doesn't re-write the extension, even though the bundle maps to a CSS-transpiled string and not stylus code.

I've tried looking for a plugin that re-writes the extension in the sourcemaps from .jade to .html but I really can't find any that doesn't break the bundling process.

@EisenbergEffect

This comment has been minimized.

Member

EisenbergEffect commented Apr 9, 2016

@Svenskunganka

This comment has been minimized.

Svenskunganka commented Apr 9, 2016

@EisenbergEffect Thank you very much! Worked perfectly!

For future reference, here's the code I used:

var Promise = require('bluebird') // Promise polyfill for IE11
import {bootstrap} from 'aurelia-bootstrapper-webpack'
import {ViewLocator} from 'aurelia-framework'

bootstrap(function(aurelia) {
  aurelia.use
    .standardConfiguration()
    .developmentLogging()

  ViewLocator.prototype.convertOriginToViewUrl = function (origin) {
    let moduleId = origin.moduleId
    let id = (moduleId.endsWith('.js') || moduleId.endsWith('.ts')) ? moduleId.substring(0, moduleId.length - 3) : moduleId
    return id + '.jade'
  }

  aurelia.start().then(() => aurelia.setRoot('app', document.body))
})
@EisenbergEffect

This comment has been minimized.

Member

EisenbergEffect commented Apr 9, 2016

Excellent. If you want, this would be a nice addition to the docs. They are
in the framework repo if you are interested in submitting a PR.
On Apr 9, 2016 2:12 PM, "Tom" notifications@github.com wrote:

@EisenbergEffect https://github.com/EisenbergEffect Thank you very
much! Worked perfectly!

For future reference, here's the code I used:

var Promise = require('bluebird') // Promise polyfill for IE11
import {bootstrap} from 'aurelia-bootstrapper-webpack'
import {ViewLocator} from 'aurelia-framework'

bootstrap(function(aurelia) {
aurelia.use
.standardConfiguration()
.developmentLogging()

ViewLocator.prototype.convertOriginToViewUrl = function (origin) {
let moduleId = origin.moduleId
let id = (moduleId.endsWith('.js') || moduleId.endsWith('.ts')) ? moduleId.substring(0, moduleId.length - 3) : moduleId
return id + '.jade'
}

aurelia.start().then(() => aurelia.setRoot('app', document.body))
})


You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub
#396 (comment)

@niieani

This comment has been minimized.

Member

niieani commented Jul 15, 2016

@EisenbergEffect As long as we're adding support for aliasing css, we could do the same with View URLs, to allow for this use-case.

@EisenbergEffect

This comment has been minimized.

Member

EisenbergEffect commented Jul 15, 2016

I'm thinking of letting any extension be mapped. So, it should be covered.

@niieani

This comment has been minimized.

Member

niieani commented Jul 15, 2016

@EisenbergEffect Awesome. Just saying we have to remember to change the hardcoded parts, that includes convertOriginToViewUrl of ViewLocator.

@EisenbergEffect

This comment has been minimized.

Member

EisenbergEffect commented Jul 15, 2016

Oh, I see that as something different. I'm referring to only the plugin mapping. Let me think about it a bit.

@niieani

This comment has been minimized.

Member

niieani commented Jul 15, 2016

Yeah, we need to think globally here, there's:

  • JS-target extensions (.js, .ts, .coffee, .jsx, .tsx, etc...),
  • CSS-target extensions (.css, .scss, .less, .styl, etc...),
  • HTML-target extensions (.html, .jade, .tpl, etc...)

It would be best if all those scenarios were globally configurable so people can plug-in any technology they like.

@EisenbergEffect

This comment has been minimized.

Member

EisenbergEffect commented Jul 15, 2016

Ok, but plugin mapping doesn't necessarily have anything to do with that actually. That mapping says what view resource plugin should handle requires of a particular file extension.

@niieani

This comment has been minimized.

Member

niieani commented Jul 15, 2016

Sure, I understand that one issue is with loading a given resource, and the other one with internally supporting other extensions with Aurelia's conventions. I'd say both should be configurable though, rather than hardcoding JavaScript and TypeScript ones, like in the ViewLocator ((moduleId.endsWith('.js') || moduleId.endsWith('.ts'))).

@dbrezoev

This comment has been minimized.

dbrezoev commented Aug 9, 2016

@Svenskunganka you said you have Jade Webpack compiler setup. Can I see how did you set it up?

@Svenskunganka

This comment has been minimized.

Svenskunganka commented Aug 9, 2016

@dbrezoev

npm i -D jade-html-loader

Add this to your loaders array in the webpack config:

...
module: {
  loaders: [
    ...
    { test: /\.jade$/, loader: 'html!jade-html' },
    ...
  ]
}
...

When you bootstrap Aurelia:

import {bootstrap} from 'aurelia-bootstrapper-webpack'
import {ViewLocator} from 'aurelia-framework'

bootstrap(function(aurelia) {
  aurelia.use
    .standardConfiguration()
    .developmentLogging()

  ViewLocator.prototype.convertOriginToViewUrl = function (origin) {
    let moduleId = origin.moduleId
    let id = (moduleId.endsWith('.js') || moduleId.endsWith('.ts')) ? moduleId.substring(0, moduleId.length - 3) : moduleId
    return id + '.jade'
  }

  aurelia.start().then(() => aurelia.setRoot('app', document.body))
})
@dbrezoev

This comment has been minimized.

dbrezoev commented Aug 10, 2016

@Svenskunganka thanks a lot, it works now

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment