Skip to content

Webpack build breaks ability to use npm installed custom components #1624

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

Closed
adamduren opened this issue Aug 10, 2016 · 14 comments
Closed

Webpack build breaks ability to use npm installed custom components #1624

adamduren opened this issue Aug 10, 2016 · 14 comments
Assignees
Labels
P1 Impacts a large percentage of users; if a workaround exists it is partial or overly painful type: bug/fix

Comments

@adamduren
Copy link

  1. OS?
    Mac OSX El Capitan
  2. Versions.

angular-cli: local (v1.0.0-beta.11-webpack, branch: ??)
node: 6.3.1
os: darwin x64

  1. Repro steps.
$ ng  bug-demo
$ cd bug-demo
$ npm install NorthernLogic/angular-cli-imported-component-bug#typescript

# In app.component.ts

# Add this
import { CustomComponent } from 'ng2-custom-component';

# Add the `CustomComponent` directive to the directives list
@Component({
  #...
  selector: 'app-root',
  directives: [CustomComponent]
...

$ ng serve

# Observe errors in 
  1. The log given by the failure. Normally this include a stack trace and some
    more information.
zone.js:101GET http://127.0.0.1:4200/component.html 404 (Not Found)scheduleTask @ zone.js:101ZoneDelegate.scheduleTask @ zone.js:336Zone.scheduleMacroTask @ zone.js:273(anonymous function) @ zone.js:122send @ VM43932:3XHRImpl.get @ xhr_impl.js:47DirectiveNormalizer._fetch @ directive_normalizer.js:49DirectiveNormalizer.normalizeTemplateAsync @ directive_normalizer.js:92DirectiveNormalizer.normalizeDirective @ directive_normalizer.js:67RuntimeCompiler._getCompiledTemplate @ runtime_compiler.js:109RuntimeCompiler._getTransitiveCompiledTemplates @ runtime_compiler.js:117(anonymous function) @ runtime_compiler.js:120RuntimeCompiler._getTransitiveCompiledTemplates @ runtime_compiler.js:120(anonymous function) @ runtime_compiler.js:120RuntimeCompiler._getTransitiveCompiledTemplates @ runtime_compiler.js:120RuntimeCompiler.compileComponentAsync @ runtime_compiler.js:43RuntimeCompiler.resolveComponent @ runtime_compiler.js:39(anonymous function) @ application_ref.js:165(anonymous function) @ application_ref.js:364ZoneDelegate.invoke @ zone.js:323onInvoke @ ng_zone_impl.js:53ZoneDelegate.invoke @ zone.js:322Zone.run @ zone.js:216NgZoneImpl.runInner @ ng_zone_impl.js:84NgZone.run @ ng_zone.js:235ApplicationRef_.run @ application_ref.js:362coreLoadAndBootstrap @ application_ref.js:162bootstrap @ index.js:115(anonymous function) @ main.ts:9__webpack_require__ @ bootstrap f5caf8d…:52(anonymous function) @ environment.dev.ts:4__webpack_require__ @ bootstrap f5caf8d…:52webpackJsonpCallback @ bootstrap f5caf8d…:23(anonymous function) @ main.bundle.js:1
browser_adapter.js:93EXCEPTION: Failed to load /component.html
browser_adapter.js:84EXCEPTION: Failed to load /component.htmlBrowserDomAdapter.logError @ browser_adapter.js:84BrowserDomAdapter.logGroup @ browser_adapter.js:94ExceptionHandler.call @ exception_handler.js:65(anonymous function) @ application_ref.js:368ZoneDelegate.invoke @ zone.js:323onInvoke @ ng_zone_impl.js:53ZoneDelegate.invoke @ zone.js:322Zone.run @ zone.js:216(anonymous function) @ zone.js:571ZoneDelegate.invokeTask @ zone.js:356onInvokeTask @ ng_zone_impl.js:44ZoneDelegate.invokeTask @ zone.js:355Zone.runTask @ zone.js:256drainMicroTaskQueue @ zone.js:474ZoneTask.invoke @ zone.js:426XMLHttpRequest.send (async)scheduleTask @ zone.js:101ZoneDelegate.scheduleTask @ zone.js:336Zone.scheduleMacroTask @ zone.js:273(anonymous function) @ zone.js:122send @ VM43932:3XHRImpl.get @ xhr_impl.js:47DirectiveNormalizer._fetch @ directive_normalizer.js:49DirectiveNormalizer.normalizeTemplateAsync @ directive_normalizer.js:92DirectiveNormalizer.normalizeDirective @ directive_normalizer.js:67RuntimeCompiler._getCompiledTemplate @ runtime_compiler.js:109RuntimeCompiler._getTransitiveCompiledTemplates @ runtime_compiler.js:117(anonymous function) @ runtime_compiler.js:120RuntimeCompiler._getTransitiveCompiledTemplates @ runtime_compiler.js:120(anonymous function) @ runtime_compiler.js:120RuntimeCompiler._getTransitiveCompiledTemplates @ runtime_compiler.js:120RuntimeCompiler.compileComponentAsync @ runtime_compiler.js:43RuntimeCompiler.resolveComponent @ runtime_compiler.js:39(anonymous function) @ application_ref.js:165(anonymous function) @ application_ref.js:364ZoneDelegate.invoke @ zone.js:323onInvoke @ ng_zone_impl.js:53ZoneDelegate.invoke @ zone.js:322Zone.run @ zone.js:216NgZoneImpl.runInner @ ng_zone_impl.js:84NgZone.run @ ng_zone.js:235ApplicationRef_.run @ application_ref.js:362coreLoadAndBootstrap @ application_ref.js:162bootstrap @ index.js:115(anonymous function) @ main.ts:9__webpack_require__ @ bootstrap f5caf8d…:52(anonymous function) @ environment.dev.ts:4__webpack_require__ @ bootstrap f5caf8d…:52webpackJsonpCallback @ bootstrap f5caf8d…:23(anonymous function) @ main.bundle.js:1
browser_adapter.js:93EXCEPTION: Error: Uncaught (in promise): Failed to load /component.html
browser_adapter.js:84EXCEPTION: Error: Uncaught (in promise): Failed to load /component.htmlBrowserDomAdapter.logError @ browser_adapter.js:84BrowserDomAdapter.logGroup @ browser_adapter.js:94ExceptionHandler.call @ exception_handler.js:65(anonymous function) @ application_ref.js:337schedulerFn @ async.js:139SafeSubscriber.__tryOrUnsub @ Subscriber.js:225SafeSubscriber.next @ Subscriber.js:174Subscriber._next @ Subscriber.js:124Subscriber.next @ Subscriber.js:88Subject._finalNext @ Subject.js:128Subject._next @ Subject.js:120Subject.next @ Subject.js:77EventEmitter.emit @ async.js:127onError @ ng_zone.js:124onHandleError @ ng_zone_impl.js:74ZoneDelegate.handleError @ zone.js:327Zone.runGuarded @ zone.js:233_loop_1 @ zone.js:487drainMicroTaskQueue @ zone.js:494ZoneTask.invoke @ zone.js:426XMLHttpRequest.send (async)scheduleTask @ zone.js:101ZoneDelegate.scheduleTask @ zone.js:336Zone.scheduleMacroTask @ zone.js:273(anonymous function) @ zone.js:122send @ VM43932:3XHRImpl.get @ xhr_impl.js:47DirectiveNormalizer._fetch @ directive_normalizer.js:49DirectiveNormalizer.normalizeTemplateAsync @ directive_normalizer.js:92DirectiveNormalizer.normalizeDirective @ directive_normalizer.js:67RuntimeCompiler._getCompiledTemplate @ runtime_compiler.js:109RuntimeCompiler._getTransitiveCompiledTemplates @ runtime_compiler.js:117(anonymous function) @ runtime_compiler.js:120RuntimeCompiler._getTransitiveCompiledTemplates @ runtime_compiler.js:120(anonymous function) @ runtime_compiler.js:120RuntimeCompiler._getTransitiveCompiledTemplates @ runtime_compiler.js:120RuntimeCompiler.compileComponentAsync @ runtime_compiler.js:43RuntimeCompiler.resolveComponent @ runtime_compiler.js:39(anonymous function) @ application_ref.js:165(anonymous function) @ application_ref.js:364ZoneDelegate.invoke @ zone.js:323onInvoke @ ng_zone_impl.js:53ZoneDelegate.invoke @ zone.js:322Zone.run @ zone.js:216NgZoneImpl.runInner @ ng_zone_impl.js:84NgZone.run @ ng_zone.js:235ApplicationRef_.run @ application_ref.js:362coreLoadAndBootstrap @ application_ref.js:162bootstrap @ index.js:115(anonymous function) @ main.ts:9__webpack_require__ @ bootstrap f5caf8d…:52(anonymous function) @ environment.dev.ts:4__webpack_require__ @ bootstrap f5caf8d…:52webpackJsonpCallback @ bootstrap f5caf8d…:23(anonymous function) @ main.bundle.js:1
browser_adapter.js:84STACKTRACE:BrowserDomAdapter.logError @ browser_adapter.js:84ExceptionHandler.call @ exception_handler.js:67(anonymous function) @ application_ref.js:337schedulerFn @ async.js:139SafeSubscriber.__tryOrUnsub @ Subscriber.js:225SafeSubscriber.next @ Subscriber.js:174Subscriber._next @ Subscriber.js:124Subscriber.next @ Subscriber.js:88Subject._finalNext @ Subject.js:128Subject._next @ Subject.js:120Subject.next @ Subject.js:77EventEmitter.emit @ async.js:127onError @ ng_zone.js:124onHandleError @ ng_zone_impl.js:74ZoneDelegate.handleError @ zone.js:327Zone.runGuarded @ zone.js:233_loop_1 @ zone.js:487drainMicroTaskQueue @ zone.js:494ZoneTask.invoke @ zone.js:426XMLHttpRequest.send (async)scheduleTask @ zone.js:101ZoneDelegate.scheduleTask @ zone.js:336Zone.scheduleMacroTask @ zone.js:273(anonymous function) @ zone.js:122send @ VM43932:3XHRImpl.get @ xhr_impl.js:47DirectiveNormalizer._fetch @ directive_normalizer.js:49DirectiveNormalizer.normalizeTemplateAsync @ directive_normalizer.js:92DirectiveNormalizer.normalizeDirective @ directive_normalizer.js:67RuntimeCompiler._getCompiledTemplate @ runtime_compiler.js:109RuntimeCompiler._getTransitiveCompiledTemplates @ runtime_compiler.js:117(anonymous function) @ runtime_compiler.js:120RuntimeCompiler._getTransitiveCompiledTemplates @ runtime_compiler.js:120(anonymous function) @ runtime_compiler.js:120RuntimeCompiler._getTransitiveCompiledTemplates @ runtime_compiler.js:120RuntimeCompiler.compileComponentAsync @ runtime_compiler.js:43RuntimeCompiler.resolveComponent @ runtime_compiler.js:39(anonymous function) @ application_ref.js:165(anonymous function) @ application_ref.js:364ZoneDelegate.invoke @ zone.js:323onInvoke @ ng_zone_impl.js:53ZoneDelegate.invoke @ zone.js:322Zone.run @ zone.js:216NgZoneImpl.runInner @ ng_zone_impl.js:84NgZone.run @ ng_zone.js:235ApplicationRef_.run @ application_ref.js:362coreLoadAndBootstrap @ application_ref.js:162bootstrap @ index.js:115(anonymous function) @ main.ts:9__webpack_require__ @ bootstrap f5caf8d…:52(anonymous function) @ environment.dev.ts:4__webpack_require__ @ bootstrap f5caf8d…:52webpackJsonpCallback @ bootstrap f5caf8d…:23(anonymous function) @ main.bundle.js:1
browser_adapter.js:84Error: Uncaught (in promise): Failed to load /component.html
    at resolvePromise (zone.js:538)
    at PromiseCompleter.reject (zone.js:515)
    at application_ref.js:367
    at ZoneDelegate.invoke (zone.js:323)
    at Object.onInvoke (ng_zone_impl.js:53)
    at ZoneDelegate.invoke (zone.js:322)
    at Zone.run (zone.js:216)
    at zone.js:571
    at ZoneDelegate.invokeTask (zone.js:356)
    at Object.onInvokeTask (ng_zone_impl.js:44)BrowserDomAdapter.logError @ browser_adapter.js:84ExceptionHandler.call @ exception_handler.js:68(anonymous function) @ application_ref.js:337schedulerFn @ async.js:139SafeSubscriber.__tryOrUnsub @ Subscriber.js:225SafeSubscriber.next @ Subscriber.js:174Subscriber._next @ Subscriber.js:124Subscriber.next @ Subscriber.js:88Subject._finalNext @ Subject.js:128Subject._next @ Subject.js:120Subject.next @ Subject.js:77EventEmitter.emit @ async.js:127onError @ ng_zone.js:124onHandleError @ ng_zone_impl.js:74ZoneDelegate.handleError @ zone.js:327Zone.runGuarded @ zone.js:233_loop_1 @ zone.js:487drainMicroTaskQueue @ zone.js:494ZoneTask.invoke @ zone.js:426XMLHttpRequest.send (async)scheduleTask @ zone.js:101ZoneDelegate.scheduleTask @ zone.js:336Zone.scheduleMacroTask @ zone.js:273(anonymous function) @ zone.js:122send @ VM43932:3XHRImpl.get @ xhr_impl.js:47DirectiveNormalizer._fetch @ directive_normalizer.js:49DirectiveNormalizer.normalizeTemplateAsync @ directive_normalizer.js:92DirectiveNormalizer.normalizeDirective @ directive_normalizer.js:67RuntimeCompiler._getCompiledTemplate @ runtime_compiler.js:109RuntimeCompiler._getTransitiveCompiledTemplates @ runtime_compiler.js:117(anonymous function) @ runtime_compiler.js:120RuntimeCompiler._getTransitiveCompiledTemplates @ runtime_compiler.js:120(anonymous function) @ runtime_compiler.js:120RuntimeCompiler._getTransitiveCompiledTemplates @ runtime_compiler.js:120RuntimeCompiler.compileComponentAsync @ runtime_compiler.js:43RuntimeCompiler.resolveComponent @ runtime_compiler.js:39(anonymous function) @ application_ref.js:165(anonymous function) @ application_ref.js:364ZoneDelegate.invoke @ zone.js:323onInvoke @ ng_zone_impl.js:53ZoneDelegate.invoke @ zone.js:322Zone.run @ zone.js:216NgZoneImpl.runInner @ ng_zone_impl.js:84NgZone.run @ ng_zone.js:235ApplicationRef_.run @ application_ref.js:362coreLoadAndBootstrap @ application_ref.js:162bootstrap @ index.js:115(anonymous function) @ main.ts:9__webpack_require__ @ bootstrap f5caf8d…:52(anonymous function) @ environment.dev.ts:4__webpack_require__ @ bootstrap f5caf8d…:52webpackJsonpCallback @ bootstrap f5caf8d…:23(anonymous function) @ main.bundle.js:1
zone.js:461Unhandled Promise rejection: Failed to load /component.html ; Zone: angular ; Task: Promise.then ; Value: Failed to load /component.htmlconsoleError @ zone.js:461_loop_1 @ zone.js:490drainMicroTaskQueue @ zone.js:494ZoneTask.invoke @ zone.js:426XMLHttpRequest.send (async)scheduleTask @ zone.js:101ZoneDelegate.scheduleTask @ zone.js:336Zone.scheduleMacroTask @ zone.js:273(anonymous function) @ zone.js:122send @ VM43932:3XHRImpl.get @ xhr_impl.js:47DirectiveNormalizer._fetch @ directive_normalizer.js:49DirectiveNormalizer.normalizeTemplateAsync @ directive_normalizer.js:92DirectiveNormalizer.normalizeDirective @ directive_normalizer.js:67RuntimeCompiler._getCompiledTemplate @ runtime_compiler.js:109RuntimeCompiler._getTransitiveCompiledTemplates @ runtime_compiler.js:117(anonymous function) @ runtime_compiler.js:120RuntimeCompiler._getTransitiveCompiledTemplates @ runtime_compiler.js:120(anonymous function) @ runtime_compiler.js:120RuntimeCompiler._getTransitiveCompiledTemplates @ runtime_compiler.js:120RuntimeCompiler.compileComponentAsync @ runtime_compiler.js:43RuntimeCompiler.resolveComponent @ runtime_compiler.js:39(anonymous function) @ application_ref.js:165(anonymous function) @ application_ref.js:364ZoneDelegate.invoke @ zone.js:323onInvoke @ ng_zone_impl.js:53ZoneDelegate.invoke @ zone.js:322Zone.run @ zone.js:216NgZoneImpl.runInner @ ng_zone_impl.js:84NgZone.run @ ng_zone.js:235ApplicationRef_.run @ application_ref.js:362coreLoadAndBootstrap @ application_ref.js:162bootstrap @ index.js:115(anonymous function) @ main.ts:9__webpack_require__ @ bootstrap f5caf8d…:52(anonymous function) @ environment.dev.ts:4__webpack_require__ @ bootstrap f5caf8d…:52webpackJsonpCallback @ bootstrap f5caf8d…:23(anonymous function) @ main.bundle.js:1
zone.js:463Error: Uncaught (in promise): Failed to load /component.html(…)
  1. Anything else that might be helpful

This worked pre the switch to using webpack instead of broccoli.

@filipesilva
Copy link
Contributor

@TheLarkInn this seems bad, probably related to the template loader. Can you add some insight?

@filipesilva filipesilva added type: bug/fix P1 Impacts a large percentage of users; if a workaround exists it is partial or overly painful feature: webpack labels Aug 16, 2016
@TheLarkInn
Copy link
Member

Is there a link or repo to this component we can test?

@TheLarkInn
Copy link
Member

I believe I know what's going on here but it will help to have this component as an example.

@adamduren
Copy link
Author

@TheLarkInn @filipesilva The npm install command in the original message references this repo. https://github.com/NorthernLogic/angular-cli-imported-component-bug

@TheLarkInn
Copy link
Member

May need to apply the angular2-template-loader to both ts and js.

@filipesilva
Copy link
Contributor

I've been looking into this, and there isn't a easy solution to it right now.

Basically, there's no decent way to bundle 3rd party libs that do not inline their html/css. At the moment we use some regex to figure it out for ts files, but it's somewhat risky... it might replace stuff it shouldn't.

However risky it is for TS, it's much more so to apply it to all JS files. I tried and it immediately broke some other unrelated files. There isn't any foolproof way to regex both TS and JS files and only find templateUrl/styleUrls that are Angular 2 components, because that can't be determined just via regex. Using TS AST tools also doesn't help on the JS front, since JS isn't TS.

I talked with the team and the immediate solution is that libs should be distributed with inlined html/css. The solution in the near future is is for libs to be build with ngc which include metadata that Angular 2 needs to know this sort of stuff. We'll be making this information available as soon as possible.

I'm closing the issue then since this isn't a CLI bug per se, but rather a bigger topic that needs to be discussed in the docs or angular/angular issues.

/cc @hansl @TheLarkInn @robwormald

@adamduren
Copy link
Author

How about things such as images that I library may include? Will it be covered by ngc as well? Also do you have any links to the discussions you mentioned? Thank you.

@filipesilva
Copy link
Contributor

Actually, this is as good as any a place to discuss all this, reopening. I don't have any links to the discussions, it's ongoing.

@filipesilva filipesilva reopened this Sep 15, 2016
@serhiisol
Copy link
Contributor

serhiisol commented Jan 12, 2017

@filipesilva I have similar problem I've described in #3274 (comment)

@filipesilva
Copy link
Contributor

A couple of months have passed since this issue was opened and even though there isn't much more to say, I want to give an update before closing it.

As far as libraries go, they should always inline html and css and be AoT ready. There isn't yet a published chapter about this on angular.io, but there's one in the works that needs a bit more work: angular/angular.io#2758

Images and other resources have to either be inlined, or somehow provided for the application to use. TSC doesn't do anything with these, as far as I know.

When the CLI has a library move (tracked in #1692) it should do all of this for you. Until then third party libraries have to do it themselves without the CLI.

@magemello
Copy link

magemello commented Feb 14, 2017

Why don't you add a custom loader in webpack that does the replace example:
templateUrl: './test.component.html' -> template: require('./test.component.html')

or you allow adding custom loaders to the webpack in the cli?

@filipesilva
Copy link
Contributor

Because that regex replacement might look fine for Angular components, but will also break any other third party library that happens to use those strings. We tried regex replacements for a while, and it's really not worth it. There's also no decent way to figure out which JS or TS files are Angular components.

@magemello
Copy link

magemello commented Feb 14, 2017

The modules that would require something like that could be explicitly configured somewhere in the package.json with the others angular-cli options, also I suppose are not a lot the modules that would require something like that.

example package.json :

{
fiximport: [
../node_modules/my_external_component
]
}

@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 6, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
P1 Impacts a large percentage of users; if a workaround exists it is partial or overly painful type: bug/fix
Projects
None yet
Development

No branches or pull requests

5 participants