Alberplz / angular2-color-picker

Angular 2 Color Picker Directive, no dependences required.
MIT License
185 stars 82 forks source link

Not working in angular2-rc6 and webpack #29

Closed Abrissirba closed 7 years ago

Abrissirba commented 8 years ago

The library doesn't work with webpack and the angular 2 rc6. It seems like external libraries that are compiled to .js needs to have a metadata.json (https://github.com/orizens/angular2-infinite-scroll/issues/77, ). I'm having the same issue as described here, http://stackoverflow.com/questions/39335621/angular2-metadata-error-when-pre-compiling-feature-module.

BrainCrumbz commented 7 years ago

In our team we're trying to import and export ColorPickerModule, which seems to be present in 'angular2-color-picker', and we're getting what seems to be a similar error at runtime:

compiler.umd.js:14126 Uncaught Error: Unexpected value 'ColorPickerModule' imported by the module 'SharedModule'

where SharedModule is a custom module where we import and export commonly used third-party modules (e.g. angular's FormsModule, ReactiveFormsModule, as well as ColorPickerModule).

EDIT

Also, if dropping completely ColorPickerModule and just working with plain "old" service and directive, ColorPickerDirective cannot be added to custom module declarations:

compiler.umd.js:14174 Uncaught Error: Unexpected value 'ColorPickerDirective' declared by the module 'SharedModule'

and of course not even re-exported, so as soon as some component view uses that, following console error shows up:

main.browser.ts:17 Error while bootstrapping application. Error: Template parse errors:
Can't bind to 'colorPicker' since it isn't a known property of 'input'. ("ound"
                         [style.background]="finalColorBackground"
                         [ERROR ->][colorPicker]="finalColorBackground" cpNoAlpha
                         (colorPickerChange)="onColor"): RelaxingMainComponent@34:25
maartentibau commented 7 years ago

Any news on this? We're now on the final release of ng2, would be great if this issue could be fixed, because there are A LOT of webpack users out there.

Thx!

One way to "fix" this. Is just to copy paste the typescript source code into a folder of your own project and just import the ColorPickerModule. Just make sure you have this in your webpack config (or something a like) and the sass-loader and node-sass dep installed

{
  test: /\.scss$/,
  exclude: root('src', 'app'),
  loader: ExtractTextPlugin.extract({ notExtractLoader: 'style-loader', loader: 'css?sourceMap!postcss!sass' })
},

{
  test: /\.scss$/,
  include: root('src', 'app'),
  loader: 'raw!postcss!sass'
},
BrainCrumbz commented 7 years ago

@webtrix yep we were doing the same with a fork of this project: manually copying library source code into our own project subfolder.

Having seen recent commits on original library, we opted to switch back to it, but now we're stuck on those errors.

BrainCrumbz commented 7 years ago

This should be a valid example of another library being adapted to angular-cli compiler, so to generate metadata files:

feature(build): Added @angular/compiler-cli support

BrainCrumbz commented 7 years ago

BTW @webtrix the copy-source-in-place trick does not seem to work for us now. All is fine at build time and when browsing the application. Then when user clicks the field to open color picker popup, the following error shows up in console:

EXCEPTION: Uncaught (in promise): Error: Template parse errors:
'web-admin-app' is not a known element:
1. If 'web-admin-app' is an Angular component, then verify that it is part of this module.
2. If 'web-admin-app' is a Web Component then add "CUSTOM_ELEMENTS_SCHEMA" to the '@NgModule.schema' of this component to suppress this message. ("
<body>

    [ERROR ->]<web-admin-app>
        <div class="col-md-12 app-loading-page">
            <p class="text-muted">"): DialogComponent@19:4

but that doesn't make a lot of sense: the reported component is the root app component, which of course has already been parsed correctly as the application runs already in client. That is the actual original body of page, before angular kicks in.

It looks like somehow the DialogComponent tries to "inflate" the whole body again. Maybe it's an issue related to dynamic component creation, don't know really. Or maybe is due to the presence of BrowserModule within library: there were other libraries where this was mentioned as an issue, as they should import some common module or what else, don't remember precisely.

EDIT
After some debugging, error happens somewhere within this call in ColorPickerDirective:

this.compiler.compileModuleAndAllComponentsAsync(DynamicCpModule)  // <--
    .then(factory => {
maartentibau commented 7 years ago

I don't use the Angular-CLI since it still has to many issues, certainly when using 3rd party libraries.

BrainCrumbz commented 7 years ago

We're not using it either, we're on webpack too. The angular-cli seems to be needed for the author, in order to build the library so to generate metadata files.

We copied source code in our project and are getting that error. It looks like dynamic component creation has changed:

Equivalent of $compile in Angular 2

We're still on RC7 and get the mentioned error. Does this library currently work for you, when copying its source code? Thanks

maartentibau commented 7 years ago

That seems to be strange... I'm using webpack as well and I have had no problems what so ever.

I created a folder in my project called "color-picker". I pasted all the files in there (Typescript only of course) and the template folder. Then added the sass-loader and node-sass to my webpack config.

And then in my app, I added "ColorPickerModule" in the imports array and that was it, all works fine. I'm on Angular 2.0.0

BrainCrumbz commented 7 years ago

Thanks. Moved to angular 2 final. Initially had still same issue. Then, after some experiments with webpack CSS loaders, it seems like issue is somehow related to color picker CSS not being correctly included during build phase.

If you copied library source code as-is (styleUrls: ['./templates/default/color-picker.css']) and you're on webpack, I guess you're chaining angular2-template-loader after (awesome-?)typescript loader in order to turn template/style URLs into inlined template/style + require() calls. Is that the case?

BrainCrumbz commented 7 years ago

Until now, the only way we were able to make this work is with this change to color-picker.directive.ts:

@Component({
    selector: 'color-picker',
    //templateUrl: './templates/default/color-picker.html',
    //styleUrls: ['./templates/default/color-picker.css']
    template: require('./templates/default/color-picker.html'),
    styles: [require('./templates/default/color-picker.scss')],  // <-- note also extension change
})
// ...

and then of course enable dedicated Sass loading in webpack, with following loader:

{
  test: [/component\.scss$/, /color-picker\.scss$/],
  loaders: ['raw-loader', 'postcss-loader', 'sass-loader'],
  // ...
}

EDIT Further improvement by chaining angular2-template-loader. This brought back template/style URLs as original, but still with SCSS extension for style:

@Component({
    selector: 'color-picker',
    templateUrl: './templates/default/color-picker.html',
    //styleUrls: ['./templates/default/color-picker.css']
    styleUrls: ['./templates/default/color-picker.scss']  // <-- note extension
})
// ...
Alberplz commented 7 years ago

Sorry, I'm updating the library very soon. Adding this line (in gulpfile.js): .pipe(gulp.dest('lib'))

after ->.pipe(inlineNg2Template({base: '/lib'})) in compile task should solve the problem.

gatapia commented 7 years ago

Using angular cli this also fails. I think its due to webpack and barrels. See: https://github.com/angular/angular-cli/issues/1831

Which implies that export * from ... does not work, you have to explicitly export {Item1, Item2, etc} from ....

I tried modifying node_modules/angular2_color_picker/index.ts to:

export {Hsva, Hsla, Rgba, SliderPosition, SliderDimension} from './lib/classes';
export {ColorPickerDirective} from './lib/color-picker.directive';
export {ColorPickerModule} from './lib/color-picker.module';
export {ColorPickerService} from './lib/color-picker.service';

no luck tho, still the same issue.

maartentibau commented 7 years ago

@BrainCrumbz you shouldn't use the .css, but the real source and that's the .scss file indeed. Angular doesn't care if it's .css of or .scss as long as you have the right loaders in your webpack everything is fine.

I'll lay out the steps one more time for everybody else.

  1. Download the full source, zip or what ever from GitHub
  2. Create a new folder in your project called e.g. color-picker
  3. Copy all the files and folders from the src folder into the folder you've just created
  4. Add "sass-loader": "4.0.2", and "node-sass": "^3.10.0", to your package.json dev deps and run npm update
  5. Go to your webpack config and add .scss to your config.resolve.extentions array
  6. Add this code (modify it to your own setup of course) to your config.module.loaders
{
 test: /\.scss$/,
 exclude: root('src', 'app'),
 loader: ExtractTextPlugin.extract({ notExtractLoader: 'style-loader', loader: 'css?sourceMap!postcss!sass' })
},

{
  test: /\.scss$/,
  include: root('src', 'app'),
  loader: 'raw!postcss!sass'
},
  1. Go to your project in your app.module file and add ColorPickerModule to your imports array, or if you use the color picker in a specific module go to that file and add ColorPickerModule to that imports array.

Run your app, you should be good...

BrainCrumbz commented 7 years ago

Just to be clear, the original library source code references CSS, not SCSS:

styleUrls: ['./templates/default/color-picker.css']

So it's not that I'm intentionally using CSS. I got that from original source, and had then to change it in order to work.

So if you "just" copy the original source, leaving CSS extension, very likely the SCSS loading is not really being involved, probably CSS file is processed by its corresponding loader I guess.

maartentibau commented 7 years ago

That's a typo (for webpack users), it needs to point to '.scss' and then it works fine. Because in the template folder, the file itself is a '.scss' file.

Since webpack will use the actual path of the file, that isn't there, it's normal it will throw an error. If you're using Gulp or something else, the compiling probably will be done before, so a '.css' variant will be created, and then the path is correct, but in our case it never will be.

BrainCrumbz commented 7 years ago

I'm sure author will address that. It's just something to be aware of when you copy library source over to your project.

BrainCrumbz commented 7 years ago

@gatapia I'm not sure editing .ts files within node_module package has any effect. Maybe at that point it's the .js one to be picked up, and .ts is basically ignored?

mlessio commented 7 years ago

Was having this issue too.

Please check https://github.com/Alberplz/angular2-color-picker/pull/38/commits/e37afec4767b0a2f7140feac940e8ffbc2a28c00 for a working fork. I alto made a PR to @Alberplz

BrainCrumbz commented 7 years ago

Hello there

Are you closing this issue because it has been solved or what? Also, mentioned PR by @mlessio does not seem merged, so cannot really figure out what happened.

Could you share some more info @Alberplz ? Thank you!

Alberplz commented 7 years ago

I added a new release (https://github.com/Alberplz/angular2-color-picker/releases/tag/1.2.1 ) to solve that, also included a webpack example. Sorry not to mention that.