I added slick.js to my project.
entry: {
vendor: [
....
'jquery',
....
'slick-carousel',
'slick-carousel/slick/slick.css'
]
}
Added a typescript file for it and referenced it in one of my components.
import { isBrowser, isNode } from 'angular2-universal';
import 'slick-carousel';
@Component({
....
})
export class HomeComponent {
constructor() {
....
if (isBrowser) {
$('#recom-carousel').slick({
dots: false,
infinite: true,
speed: 300,
slidesToShow: 4,
slidesToScroll: 1,
variableWidth: true
});
}
}
}
However, even after using isBrowser, i still get window is not defined error.
slick.js doesn't support being loaded in a Node environment. It tries to reference window immediately, even before you invoke any of its exports. It's not enough to use an if(isBrowser) { ... }, check - simply having an import that loads the slick.js code is going to throw in a non-browser environment.
Fortunately this is fairly easy to work around. Three things you need to do:
import 'slick-carousel'; line into any Angular 2 component (because those files load for server-side execution). Instead, put that line into your boot-client.ts file. Then the library will only be loaded for client-side execution.import { isBrowser } from 'angular2-universal'; and import * as $ from 'jquery'; at the top, then use the if(isBrowser) { ... } test around any place you try to call $(...).slick.package.json file to reference jQuery 3.0.0+ (e.g., "jquery": "^3.0.0"), because that's what slick.js depends on, and then rebuild both your vendor and main bundles. If you don't do this, then your code is referencing a different version of jQuery than slick is, so Webpack will bundle two differently-versioned copies of jQuery, and it won't work at runtime because slick will have attached itself to a different instance of jQuery than your code receives.you're so awesome. thanks! :)
i actually saw that part of slick js that immediately calls 'window'. got a hunch that maybe that's causing the issue. but your explanation about importing it in the components cleared everything. thanks again!
Steve, thanks for the info.
I have a similar issue and this has helped get me on right tracks but I can't quite figure out how to get around my issue. I am using the Ace editor. I imported the following js in the boot-client instead of the component I was using it as suggested.
import 'brace/theme/monokai';
import 'brace/mode/javascript';
I am using the AceEditorDirective so in the module file I use the isBrowser like so:
var decs: any = [
EqualValidator,
AppComponent,
NavMenuComponent,
HomeComponent,
PricesComponent,
ContactComponent,
SignupComponent,
LoginComponent,
TestsComponent,
TestComponent
];
if (isBrowser) {
console.log("broswer");
decs.push(AceEditorDirective);
};
Still having the issue. It seems to be pushing this directive even when not a browser or maybe I am missing something. (newbie to Angular 2 and Typescript)
Thanks
Most helpful comment
slick.jsdoesn't support being loaded in a Node environment. It tries to referencewindowimmediately, even before you invoke any of its exports. It's not enough to use anif(isBrowser) { ... }, check - simply having animportthat loads theslick.jscode is going to throw in a non-browser environment.Fortunately this is fairly easy to work around. Three things you need to do:
import 'slick-carousel';line into any Angular 2 component (because those files load for server-side execution). Instead, put that line into yourboot-client.tsfile. Then the library will only be loaded for client-side execution.import { isBrowser } from 'angular2-universal';andimport * as $ from 'jquery';at the top, then use theif(isBrowser) { ... }test around any place you try to call$(...).slick.package.jsonfile to reference jQuery 3.0.0+ (e.g.,"jquery": "^3.0.0"), because that's what slick.js depends on, and then rebuild both your vendor and main bundles. If you don't do this, then your code is referencing a different version of jQuery than slick is, so Webpack will bundle two differently-versioned copies of jQuery, and it won't work at runtime because slick will have attached itself to a different instance of jQuery than your code receives.