Skip to content
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

Jade support in webpack releases #1886

Closed
ShadowManu opened this issue Aug 30, 2016 · 42 comments

Comments

@ShadowManu
Copy link

commented Aug 30, 2016

Sorry for not providing template information but I only have my phone available (and there's no critical info either).

Is there some in-the-works support for jade? The related issues/PR 's were closed but no real solution was provided. What can be done to have support for this?

@ShadowManu

This comment has been minimized.

Copy link
Author

commented Sep 9, 2016

So you guys closed #996 and #968 in favor of #40, then closed #40 with no specific ending, then closed the efforts in #1433 and #626 because you changed to webpack and here we are with no answers.

Sorry, I'm not trying to be annoying, specially when I see a lot of hate on recent issues with bugs regarding latest TS/Angular/CLI combinations. I can understand error because we are humans, I can understand time because we need to sleep and have to live, but I do hate purposeful indifference, just because its not your problem. I'm open to work myself on the CLI on a new PR, but I do need guidance, and that really starts at least with a single answer in a timelapse of 10 days. Nevertheless, thank you for your efforts.

@niklas-dahl

This comment has been minimized.

Copy link
Contributor

commented Sep 12, 2016

This is my current "solution":

gulpfile.js:

let path = require('path');
let gulp = require('gulp');
let pug  = require('gulp-pug');

let pugFiles = './src/**/*.pug';

gulp.task('compilePug', () => {
  gulp.src( pugFiles )
    .pipe( pug().on('error', () => console.log('JADE ERROR')) )
    .pipe( gulp.dest('./src') );
});

gulp.task('default', ['compilePug'], () => {
  gulp.watch(pugFiles, ['compilePug']);
});

.vscode/settings.json:

{
  "files.exclude": {
      "src/app/**/*.html": {"when": "$(basename).pug"}
  }
}

This actually works but it's obviously only a temporary solution..

@ShadowManu

This comment has been minimized.

Copy link
Author

commented Sep 12, 2016

My team is using pug-cli with --watch at the moment for the same results. However, I would prefer jade to be part of the webpack bundling itself. I'll submit a PR if I have time to figure out how to set it up.

@theklausster

This comment has been minimized.

Copy link

commented Sep 16, 2016

Any news on how to add pug to cli?

I opened a thread on Stockoverflow aswell, hoping for some result
http://stackoverflow.com/questions/39518500/how-to-add-pug-to-angular-cli

@ShadowManu

This comment has been minimized.

Copy link
Author

commented Sep 18, 2016

Opened a PR to see how this goes.

@filipesilva

This comment has been minimized.

Copy link
Member

commented Sep 21, 2016

Heya @ShadowManu, we're not trying to be indifferent and I'm sorry that the jade support has fallen to the wayside.

I can't say jade/pug support is a big on our radars right now to be honest. If you can get a PR to work I'm happy to review it, but bear in mind that it needs to have tests and documentation.

See https://github.com/angular/angular-cli#development-hints-for-hacking-on-angular-cli for a way to start working with a local copy of the CLI.

The command that runs the e2e suite is node tests/e2e_runner.js. Have a look at https://github.com/angular/angular-cli/tree/master/tests/e2e/tests/build/styles for sass/less/styl tests.

You should test that the the correct html is generated, and that base jade/pug functionality (like imports) works.

Regarding documentation, something akin to https://github.com/angular/angular-cli#css-preprocessor-integration should be enough.

Ideally we'd also support initializing a project with pug like we do with sass (ng new sassy-project --style=sass), or setting the default template language (ng set defaults.styleExt scss) but to be honest that's further down the road.

@ShadowManu

This comment has been minimized.

Copy link
Author

commented Sep 21, 2016

Thanks man. I'll be looking at the tests and a proper similar documentation as soon as I have time.

@KingsDevelopment

This comment has been minimized.

Copy link

commented Oct 10, 2016

Any updates @ShadowManu ?

@nvrossett

This comment has been minimized.

Copy link

commented Oct 14, 2016

@ShadowManu please, you can look too the support to (lost-grid and/or jeet.gs) and rupture in stylus too?

@ShadowManu

This comment has been minimized.

Copy link
Author

commented Oct 15, 2016

@KingsDevelopment @filipesilva I've worked a little with some time I had on this, but got blocked on how to make the tests pass (specially on the time they take). I'll have a second try tomorrow.

@nvrossett not that I have knowledge of it. And probably should be on a different PR/issue.

@TaylorDennisLee

This comment has been minimized.

Copy link

commented Nov 24, 2016

I just wanted to throw my support behind @tycho01 's pug-plugin-ng and pug-ng-html-loader. I used them to use pug with the Angular Class seed, and it really cleans up the syntax and makes development with Angular2 and pug very pleasant. I recommend checking it out:

https://github.com/tycho01/pug-plugin-ng
https://github.com/tycho01/pug-ng-html-loader

(pug-ng-html-loader is just a fork of pug-html-loader which allows pug-plugin-ng to work)

@tycho01

This comment has been minimized.

Copy link

commented Nov 24, 2016

@TaylorDennisLee: thanks. note that for Webpack 2 it should work without the additional loader as well now, see the readme.

Edit: note that original pug syntax is not harmed/disabled; the plugin just patches the lexer to ensure this cleaner more natural (perspective: HTML) option is parsed correctly as well.

@TaylorDennisLee

This comment has been minimized.

Copy link

commented Nov 24, 2016

@tycho01 Okay, so now pug-plugin-ng should work with pug-html-loader, as long as you are using Webpack 2?

Also, do you still have to do

template: require('./myComp.pug')

instead of:

templateUrl: 'myComp.pug'

Thanks,

Taylor

@tycho01

This comment has been minimized.

Copy link

commented Nov 24, 2016

@TaylorDennisLee: yeah; if you're experiencing issues feel free to file them.
It does still need the require like that, though it seems angular-cli appeared to have addressed this for Sass and co., so I imagine they could for template engines like Pug as well.

@mbonski

This comment has been minimized.

Copy link

commented Nov 26, 2016

@tycho01 can you please provide small guide how to add this loader to angular cli. I'm getting:

src/app/app.component.pug Unexpected token (1:3) You may need an appropriate loader to handle this file type.

import { Component } from '@angular/core';
@Component({
selector: 'app-root',
 template: require('./app.component.pug'),
 styleUrls: ['app.component.scss']
})
export class AppComponent {
  title = 'app works!';
}
@tycho01

This comment has been minimized.

Copy link

commented Nov 26, 2016

@mbonski: I may have use for further info (where/how you set it, first line of the pug file, whether it worked without it). Could you post an issue with those here?

@mbonski

This comment has been minimized.

Copy link

commented Nov 26, 2016

@tycho01 I created one. reference

@TaylorDennisLee

This comment has been minimized.

Copy link

commented Nov 27, 2016

I'd be interested to see how to do this with just temporary script that runs right before "ng serve" or "ng build" and also what in the angular-cli source code a change would naturally go. @tycho01 do you have a link for how they handled the Sass issue?

@tycho01

This comment has been minimized.

Copy link

commented Nov 27, 2016

@TaylorDennisLee you might consider using a Gulp task for Pug compilation then, preferably along with one of the watchy kind. That's what I've been using, failing a better solution thus far. That could look something like this:

let gulp = require('gulp'),
    gulpWatch = require('gulp-watch'),
    runSequence = require('run-sequence'),
    pug = require('gulp-pug'),
    pug_plugin_ng = require('pug-plugin-ng');

let pug_opts = { doctype: 'html', plugins: [pug_plugin_ng], pretty: true };
let toSrc = gulp.dest((file) => file.base);

gulp.task('pug', () =>
  gulp.src('src/**/*.pug')
  .pipe(pug(pug_opts))
  .pipe(toSrc)
);

gulp.task('watch', [], () => {
  runSequence(
    ['pug'],
    () => {
      gulpWatch('src/**/*.pug', () => gulp.start('pug'));
    }
  );
});

As to changes, I linked ShadowManu's and mine in mbonski's issue thread.

On the Sass point, I didn't know yet :), but the magic appears to be located here. If I'm reading that correctly, than it should be automatically adding support for any extension already recognized by webpack. So I may have been wrong there earlier!

@ShadowManu

This comment has been minimized.

Copy link
Author

commented Nov 27, 2016

@TaylorDennisLee @tycho01 why not simply using pug src --watch & ng serve? Sure, since they're running simultaneously, webpack generally starts doing 2 builds. But hey, config-wise, you just need to install pug and pug-cli with npm.

@tycho01

This comment has been minimized.

Copy link

commented Nov 28, 2016

@ShadowManu: Yeah, under normal circumstances I suppose that would've been the straight-forward way. One complication I faced personally with my plugin was (1) adding configuration, and (2) having to ensure I could add Pug plugins as well (-> functions, therefore can't survive JSON serialization, so couldn't be passed through a CLI). I never really wanted to use a plugin, but that's how it ended up. I'd definitely rather not resort to Gulp either.

I just did manage that with help from @TaylorDennisLee though, so to answer @mbonski's earlier question of a guide on how to get this to work before it's merged:

git clone -b pug https://github.com/zoitravel/angular-cli.git
# alternative with plugin: git clone -b pug-html https://github.com/tycho01/angular-cli.git
cd angular-cli
npm link
cd PATH/TO/MY/PROJECT
npm link angular-cli
# in component: templateUrl: './my_pug_file.pug',
ng serve

(Now as to the real frontier, ditching pug gulp tasks in Ionic...)

@vanor89

This comment has been minimized.

Copy link

commented Jan 25, 2017

Has anyone gotten variable interpolation to work with webpack1 and pug-ng-html-loader? For some reason its not being able to access my variables

Edit: Just figured out I was basically writing the angular templates using pug and rendering it so instead of using pug variables I should be using angular variables like such {{var}}

@CrystalzWind

This comment has been minimized.

Copy link

commented Feb 16, 2017

I found a way to use AngularCLI with Pug using pug-html-loader. After generate new projects using ng new.
Install pug and pug-html-loader packages. npm install --save-dev pug pug-html-loader.
Add pug-html-loader to your project \node_modules@angular\cli\models\webpack-configs\common.js

{ test: /.(pug|jade)$/, loader: 'pug-html-loader' },
under { test: /.html$/, loader: 'raw-loader' },

Use .jade template in component.

@component({
selector: 'app',
templateUrl: './app.template.jade'
})

I'v made a demo template here https://github.com/CrystalzWind/AngularCLI-Pug
*Note: We must add pug loader to common.js manually after install

@donmahallem

This comment has been minimized.

Copy link

commented Feb 19, 2017

Equivalent option to @CrystalzWind 's example is to use pug-loader with apply-loader.

npm install pug-loader apply-loader

and piping the output of the pug-loader through the apply loader which simply executes the template function.

{ test: /\.pug$/, loader: "apply-loader!pug-loader?self" }
in

\node_modules@angular\cli\models\webpack-configs\common.js

Which works with ng serve and ng build --aot for me now

@Aides359

This comment has been minimized.

Copy link

commented Feb 21, 2017

Extending on the workaround presented by @CrystalzWind and @donmahallem, looking at
https://github.com/angular/angular-cli/blob/master/packages/%40angular/cli/models/webpack-configs/common.ts#L33
https://github.com/angular/angular-cli/blob/master/packages/%40angular/cli/models/webpack-configs/common.ts#L104-L112
it seems like giving configuration access to the extraRules variable (there seems to be some configuration options through buildOptions and appConfig already) might be enough to solve this issue.

Edit: Aides359/angular-cli@f3cfdb8 shows how such a change might look like (it works but I am fully aware that this is not suited for PR yet).
This would allow "loaderRules": [{ "test": "\\.(pug|jade)$", "loader": "apply-loader!pug-loader" }] in .angular-cli.json to fix this issue.

@filipesilva

This comment has been minimized.

Copy link
Member

commented Feb 21, 2017

I'm sorry to be the bearer of bad news, but jade/pug support will not make it to 1.0. It's an medium/big feature that we can't spare the time to make sure it work properly.

I know it looks like it would only be a small change in loaders but that's just not been the case with similar features like sass support.

We're looking at it for 2.0 instead, either as base functionality or as one of the main usecases for addons.

@tycho01

This comment has been minimized.

Copy link

commented Feb 21, 2017

Thanks for the update. If we could help out in the testing department, I'd be glad to.

@Aides359

This comment has been minimized.

Copy link

commented Feb 21, 2017

@filipesilva one of the things that would need some consideration for proper pug support would be how to handle the angular syntax with pug since pug has problems with it (would we want to trade equivalence to pug for syntax convenience).

For reference see tycho01/pug-plugin-ng

@tycho01

This comment has been minimized.

Copy link

commented Feb 21, 2017

On that, fixing Pug to play nice with Angular amounted to one small addition if it'd made it into Pug core (-> consider '[' and '(' after whitespace as valid indication a new property has started).
While I feel this makes much sense in the Angular 2+ context, I don't consider it a blocker for initial support, in the sense that it's pretty much backward compatible.
In the Angular context I'd be in favor of doctype: 'html' as well, to allow #myVar / md-raised-button over #myVar='' / md-raised-button=''.

@filipesilva

This comment has been minimized.

Copy link
Member

commented Feb 24, 2017

They could, yes. We'd still like to make it a first class citizen one day.

@Aides359

This comment has been minimized.

Copy link

commented Feb 24, 2017

@MarkPieszak this was my current solution to this problem.
Thanks for mentioning.

@ausir0726

This comment has been minimized.

Copy link

commented Mar 3, 2017

hope some day can support pug in angular-cli

@Anthonyzou

This comment has been minimized.

Copy link

commented Mar 5, 2017

@mbonski
Your example is really close.
First install pug and pug-loader and use this example code.

import { Component } from '@angular/core';
@Component({
selector: 'app-root',
 template: require('pug-loader!./app.component.pug')(),
 styleUrls: ['app.component.scss']
})
export class AppComponent {
  title = 'app works!';
}

The only difference is
template: require('./app.component.pug')
To =>
template: require('pug-loader!./app.component.pug')()

You may also need to add the following into typings.d.ts

// telling the typescript compiler that there is a global function
// called require. And to not freak out about references to it.
declare var require: any;

This also works for any other loader in the webpack universe

@donmahallem

This comment has been minimized.

Copy link

commented Mar 5, 2017

So far I got it working with ng eject BUT this does not work with tests which again does desire an appropiate loader.

@Anthonyzou Your workaround does work for JIT but I don't seem to get it running with AOT.
The error reads as follows:

Error encountered resolving symbol values statically. Calling function 'template', function calls are not supported. Consider replacing the function or lambda with a reference to an exported function, resolving symbol abc in a/b/c

Following the advice of the error and some sites regarding aot I tried:
`
export function template() {
return require("pug-loader!./test.component.pug")();
}

@component({
template: template()
})`

But it still errors with basicly the same message. Any ideas?

@Anthonyzou

This comment has been minimized.

Copy link

commented Mar 5, 2017

@donmahallem I actually have no idea, actually. This is adapted from a graphql angular2 example where they manually require a graphql file and it works with AOT. It must also depend on how the loader is built.

@filipesilva

This comment has been minimized.

Copy link
Member

commented May 22, 2017

Heya all, this isn't a feature that we're looking at adding in the 1.x timeframe, but rather something that would happen as a third party addon using the upcoming addon system for v2+.

@svallory

This comment has been minimized.

Copy link

commented Jul 28, 2017

Guys, I made a pull request to allow tweaking webpack config with a file in the project root. For now, you can use the cli at https://github.com/cashfarm/angular-advanced-cli (branch 1.2.x)

Install pug, pug-ng-html-loader and add a webpack.config.js with this to root of your project:

module.exports = {
  module: {
    rules: [
      {
        test: /\.(pug|jade)$/,
        use: ['pug-ng-html-loader']
      }
    ]
  }
}

Then your components can use pug

@Component({
  selector: 'app-root',
  templateUrl: './app.component.pug',
  styleUrls: ['./app.component.styl']
})

But your index has to stay in html.

@Pexak

This comment has been minimized.

Copy link

commented Sep 20, 2017

Any update?

@MarkPieszak

This comment has been minimized.

Copy link
Member

commented Oct 1, 2017

Going along with some of the recommendations above, I created a little script that can be ran to automatically insert the pug rule into the node_modules folder. @Pexak

This can be used as a temporary solution until it can be available natively. Note this could need to be updated & changed if the CLI changes the location or formatting of this file. It's naively searching for rules: [ within this specific file.

npm i --D apply-loader pug-loader

pug-rule-insert.js

Now you can just create a simple js file with the code below (put it at your root project level).

const fs = require('fs');

const commonCliConfig = 'node_modules/@angular/cli/models/webpack-configs/common.js';
const pug_rule = `\n{ test: /\.pug$/, loader: "apply-loader!pug-loader?self" },`;

fs.readFile(commonCliConfig, (err, data) => {
  if (err) { throw err; }

  const configText = data.toString();

  if (configText.indexOf(pug_rule) > -1) {
    return;
  }

  console.log('-- Inserting .pug webpack rule -- ');

  const position = configText.indexOf('rules: [') + 8;
  const output = [configText.slice(0, position), pug_rule, configText.slice(position)].join('');

  const file = fs.openSync(commonCliConfig, 'r+');
  fs.writeFile(file, output);
  fs.close(file);
});

Running it

Run it simply with: node pug-rule-insert.js or create a nice postinstall hook to do it for you on new installs.

"postinstall": "node pug-rule-insert.js"

Needed this for a client, hope this helps!

Works with ng serve (even live reloads pug file changes) and AoT ng prod builds, even Universal + CLI projects! 🎁

@clovisj

This comment has been minimized.

Copy link

commented Nov 3, 2017

@chenzhiguang

This comment has been minimized.

Copy link

commented Nov 29, 2017

@MarkPieszak thank you. I used pug-html-loader and html-loader instead, it is working fine, including the include ./pug-file

const pug_rule = `\n{ test: /.pug$/, loader: [ 'html-loader', { loader: "pug-html-loader", options: { doctype: 'html', pretty: true } } ], },`;

@oguimbal

This comment has been minimized.

Copy link

commented Dec 16, 2017

@MarkPieszak @clovisj @chenzhiguang
[Warning] this trick works fine, as long as you do not name your template files something.TS.pug (which I used to do so they pop below their .ts counterpart in vscode)

If you do so, your AOT builds will fail silently (at least on my machine, as of today)

This one was f***ng hard to find. see #8904

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
You can’t perform that action at this time.