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 · 43 comments
Closed

Jade support in webpack releases #1886

ShadowManu opened this issue Aug 30, 2016 · 43 comments
Labels
P5 The team acknowledges the request but does not plan to address it, it remains open for discussion

Comments

@ShadowManu
Copy link

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
Copy link
Author

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
Copy link
Contributor

niklas-dahl 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
Copy link
Author

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
Copy link

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
Copy link
Author

Opened a PR to see how this goes.

@filipesilva filipesilva added command: build P5 The team acknowledges the request but does not plan to address it, it remains open for discussion labels Sep 21, 2016
@filipesilva
Copy link
Contributor

filipesilva 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
Copy link
Author

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

@jurienhamaker
Copy link

Any updates @ShadowManu ?

@nvrossett
Copy link

nvrossett 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
Copy link
Author

@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.

@qtleeq
Copy link

qtleeq 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)

@KiaraGrouwstra
Copy link

KiaraGrouwstra 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.

@qtleeq
Copy link

qtleeq 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

@KiaraGrouwstra
Copy link

@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.

@ghost
Copy link

ghost 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!';
}

@KiaraGrouwstra
Copy link

@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?

@ghost
Copy link

ghost commented Nov 26, 2016

@tycho01 I created one. reference

@qtleeq
Copy link

qtleeq 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?

@KiaraGrouwstra
Copy link

@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
Copy link
Author

@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.

@KiaraGrouwstra
Copy link

KiaraGrouwstra 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
Copy link

vanor89 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
Copy link

CrystalzWind 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
Copy link

donmahallem 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

@ScallyGames
Copy link

ScallyGames 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: ScallyGames/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
Copy link
Contributor

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.

@KiaraGrouwstra
Copy link

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

@ScallyGames
Copy link

ScallyGames 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

@KiaraGrouwstra
Copy link

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
Copy link
Contributor

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

@ScallyGames
Copy link

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

@ausir0726
Copy link

hope some day can support pug in angular-cli

@Anthonyzou
Copy link

Anthonyzou 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
Copy link

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
Copy link

@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
Copy link
Contributor

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
Copy link

svallory 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
Copy link

pexak commented Sep 20, 2017

Any update?

@MarkPieszak
Copy link
Member

MarkPieszak 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
Copy link

clovisj commented Nov 3, 2017

Tnks @MarkPieszak

@chenzhiguang
Copy link

chenzhiguang 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
Copy link

@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

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 7, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
P5 The team acknowledges the request but does not plan to address it, it remains open for discussion
Projects
None yet
Development

No branches or pull requests