angular / angular-cli

CLI tool for Angular
https://cli.angular.io
MIT License
26.67k stars 11.98k forks source link

Using `templateUrl` with a `.svg` file #10567

Closed phenomnomnominal closed 5 years ago

phenomnomnominal commented 6 years ago

Hey friendly @angular/cli team!

Would there be any appetite to enable using a .svg file as a component template?

As far as I can tell it would be a small change in webpack-config/common.js from:

{ test: /\.html$/, loader: 'raw-loader' },
{ test: /\.(eot|svg|cur)$/, // ...

to

{ test: /\.(html|svg)$/, loader: 'raw-loader' },
{ test: /\.(eot|cur)$/, // ...

Are there any downsides to this? Are there any other places that the change would need to be handled? It seems to work when I change it in my node_modules.

Let me know if this is something that would be useful/wanted, and I'll make a PR.

Thanks!

johnchristopherjones commented 6 years ago

Personally, I would definitely love to use svg for component templates.

sancelot commented 5 years ago

When working with svg files it seems mandatory. You can not copy your file in the template each time it is modified...

alan-agius4 commented 5 years ago

I am not understanding the use case, why an HTML template should have an .svg extention.

skreborn commented 5 years ago

@alan-agius4 I'm assuming the primary use case here is to create a component that is just and SVG and nothing else. Then again, nothing's stopping us from simply using a HTML file and embedding SVG into that, so I'm also not sure why this change is required.

phenomnomnominal commented 5 years ago

It’s mainly just so you don’t have to spend your time renaming files and copying stuff around. Also, it can be good to just using raw .svg files for the extra tooling you get with them.

alan-agius4 commented 5 years ago

Having an SVG image instead of a template, might increase the final bundle size if a SVGs are large.

You will lose the advantage of using HTTP2, fingerprinting etc.. which would mean that with every release you do the users will need to re-download all the svgs again.

Also, by definition an SVG is a graphic since doesn't seem correct to treat it as a template.

What if you than need to add an Input to the component? You change the extension to .html?

phenomnomnominal commented 5 years ago

I’ve made this change for some tests and as far as I can tell, nothing here is really different if you use it as a .html file or a .svg? Webpack still treats it as “raw”, it is bundled the same way, you can still use bindings and Inputs, etc. The main difference is clearer intent of what the template actually is, and easier workflows when consuming assets.

Using Angular bindings with SVG tags is really powerful. Yes, you can end up with big bundles, but’s that’s indenpendent of the file extension. I don’t think this change would encourage that anymore than the current situation. Are you suggesting they shouldn’t be used together just because you could end up with big bundles? A developer can do lots of things that cause large bundles, it doesn’t seem practical to stop all possible foot guns.

liorwohl commented 5 years ago

My use case of importing SVG as a component template was that in our application the logo of the app has an animation while the app is loading something using REST (so I have an animated-logo component), and the same SVG image is used somewhere else as a background. Right now I inline the SVG in the component because I dont want to change the background to html, its an ugly solution. I dont see why Angular care which text file extension I use.

filipesilva commented 5 years ago

Heya, I checked with the core team about SVG support in templates and the angular compiler should support it.

Would someone be interested in adding the feature? I ask that you test it in JIT and AOT. A good test to use as an example is https://github.com/angular/angular-cli/blob/master/packages/angular_devkit/build_angular/test/browser/allow-js_spec_large.ts. You can copy it, add fdescribe to only run that one, and run it with npm run test-large.

phenomnomnominal commented 5 years ago

Yeah I’ll have a crack!

filipesilva commented 5 years ago

@alan-agius4 brought up a problematic issue: how to differentiate between SVG being loaded as a templateUrl (inlined as raw) or as a resource in CSS (loaded as an extra asset file). I'm not sure there's a good way of doing that. It might need a fair bit of work even.

phenomnomnominal commented 5 years ago

This SO answer looks like it solves that issue: https://stackoverflow.com/questions/36281354/use-different-loader-in-webpack-depending-on-from-where-im-importing

oocx commented 5 years ago

Differentiating between .svg used as component templates and other .svg is pretty easy if you follow the convention to name component files like somename.component.(.ts|.html|.svg|.css|.less|...).

Just add a new webpack rule that tests for *.component.svg.

oocx commented 5 years ago

To give an example, real world use case: We have an application that is used to create process documentation for how a company processes its invoices. It does that by asking the user multiple choice questions which are then used to create a process documentation (a word file).

We use an .svg image to show a process diagram for processing invoices. In the .svg, we show/hide icons to indicate for which part of the process the user has already answered questions. You can even click on parts of the .svg to jump to the questions for that part of the invoice process (we did this by applying angular directives inside the .svg).

The .svg was created by our marketing department by simply using the grarphics tools they are used to work with. Our developer could then use that .svg with some minor modifications.

We created the app with a manual webpack configuration, I think Angular cli did not yet exist back then or was not mature enough (we started to use Angular around the time when the first version of Angular 2.0 was released).

oocx commented 5 years ago

With Angular CLI 8.0.0-beta.5, you can now use .svg files as templates. You can read more about the new feature in my blog on medium: https://medium.com/@oocx/using-svg-files-as-component-templates-with-angular-cli-ea58fe79b6c1

angular-automatic-lock-bot[bot] commented 4 years ago

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.