kenwheeler / slick

the last carousel you'll ever need
kenwheeler.github.io/slick
MIT License
28.54k stars 5.89k forks source link

Can't get slick to "import/require" using WebPack, maybe slick doesn't implement a WebPack supported module format? #1170

Open 01AutoMonkey opened 9 years ago

01AutoMonkey commented 9 years ago

So I'm doing this:

require('./main.css');
var Jquery = require('jquery');
//var Slick = require('slick');
var React = require('react');

Which works, I get no errors, but if I uncomment the "slick require" I start getting an error:

ReferenceError: require is not defined

I'm new to the whole "js import" thing but am trying out WebPack, and I'm thinking that perhaps slick doesn't implement a webpack supported "module format", see: https://github.com/webpack/docs/wiki/shimming-modules

In some cases webpack cannot parse some file, because it has a unsupported module format or isn’t even in a module format.

Could this be true? I think it's suppose to support "AMD" and "CommonJS" but I may be wrong.

My code is just this code with slick and jquery added.

Oh and here is my config file:

 var webpack = require('webpack');
 var path = require('path');
 var bower_dir = path.join(__dirname, 'bower_components');
 var node_modules_dir = path.join(__dirname, 'node_modules');

 var config = {
   addVendor: function (name, path) {
     this.resolve.alias[name] = path;
     this.module.noParse.push(path);
   },
   context: __dirname,
   entry: {
     app: ['webpack/hot/dev-server', './app/main.js']
   },
   output: {
     publicPath: '/',
     path: path.resolve(__dirname, process.env.NODE_ENV === 'production' ? './dist/' : './build'),
     filename: 'bundle.js'
   },
   resolve: {
     alias: {}
   },
   module: {
     noParse: [],
     loaders: [{
       test: /\.js$/,
       loader: 'jsx-loader',
       exclude: [bower_dir, node_modules_dir]
     }, {
       test: /\.css$/,
       loader: 'style-loader!css-loader'
     }, {
       test: /\.(woff|png)$/,
       loader: 'url-loader?limit=100000'
     }]
   },
   plugins: [
     new webpack.optimize.CommonsChunkPlugin('app', null, false)
   ]
 };

 config.addVendor('react', path.resolve(bower_dir, 'react/react.min.js'));
 config.addVendor('jquery', path.resolve(bower_dir, 'jquery/dist/jquery.min.js'));
 config.addVendor('slick', path.resolve(bower_dir, 'slick.js/slick/slick.min.js'));

 module.exports = config;
kenwheeler commented 9 years ago

What happens if you add bower components to your resolve option and try to require it into files?

resolve: {
    root: [path.join(__dirname, "bower_components")],
    alias: {}
}
kenwheeler commented 9 years ago

It's UMD so it should work?

fleeboy commented 9 years ago

Hey,

It does work after some messing around -in my index.js where I import modules from node_modules (It would be similar with Bower):

import 'expose?$!expose?window.jQuery!jquery';
import 'slick-carousel/slick/slick';

Above I am using "expose-loader": "^0.7.0" in NPM and ES6 (with Babel-loader). I found I had to expose 'jQuery' AND '$' to a global var as Slick seems to require both as globals?

Not sure if its an issue with Slick needing both vars or a WebPack config issue, or both.

TomOne commented 8 years ago

This works for me (without exposing jQuery as global):

import $ from 'jquery';
import 'slick-carousel';

$('.some-element').slick();
anilGupta commented 8 years ago

@TomOne so we need to import css too please give me suggestion

gabrielperales commented 8 years ago

I have tryed with what @fleeboy and @TomOne said, but it doesn't work.

Can somebody help me?

This is my code:

file webpack.config.js:

'use strict';
var ExtractTextPlugin = require('extract-text-webpack-plugin');

var sources = [
  './source/style/main.css',
  './source/js/main.js'
];

module.exports = {
  entry: {
    bundle: sources
  },
  output: {
    path: './public',
    filename: 'js/[name].js'
  },
  module: {
    loaders: [{
      test: /\.js$/,
      exclude: /node_modules/,
      loader: 'babel',
      query: {
        presets: ['es2015']
      }
    }, {
      test: /\.css$/,
      loader: ExtractTextPlugin.extract('css')
    }]
  },
  plugins: [
    new ExtractTextPlugin('style/[name].css')
  ]
};

and this is my public/js/main.js:

import $ from 'jquery';
import 'slick-carousel';

$('.slides').slick();

And this is what the console show up:

bundle.js:8101 Uncaught TypeError: (0 , _jquery2.default)(...).slick is not a function

I have tried removing import $ from 'jquery' and but seems like import 'slick-carousel' returns an empty object. Thank you

he9qi commented 8 years ago

have you tried this? https://github.com/kenwheeler/slick/issues/2290#issuecomment-216122431

this works for me.

simboonlong commented 6 years ago

Try defining externals in webpack config?

module.exports = {
  externals: {
    jquery: 'jQuery',
  },
  entry: ...
}

Read more here https://webpack.js.org/configuration/externals/

zeshanshani commented 6 years ago

@simboonlong worked like a charm! Thank you!

tnormington commented 6 years ago

I'm able to import slick js files with webpack like this:

import $ from 'jquery'
import 'slick-carousel'

Then I import the scss files with the @import sass method like this:

$slick-font-path: "~slick-carousel/slick/fonts/"
$slick-loader-path: "~slick-carousel/slick/"
@import "~slick-carousel/slick/slick.scss"
@import "~slick-carousel/slick/slick-theme.scss"

This method lets me override scss variables before I import. I'm using a css-loader, sass-loader, an file-loader with webpack.

mak633 commented 6 years ago

Hi. I found a solution which works for me:

  1. add to js file:

    import $ from 'jquery';
    import 'slick-carousel';
  2. add to scss file:

    $slick-font-path: "/node_modules/slick-carousel/slick/fonts/" !default;
    $slick-font-family: "slick" !default;
    $slick-loader-path: "/node_modules/slick-carousel/slick-carousel/slick/" !default;
    $slick-arrow-color: black !default;
    @import "~slick-carousel/slick/slick.scss"; 
    @import "~slick-carousel/slick/slick-theme.scss";
Igor-Art commented 5 years ago

Hi! I have a similar problem:

$(...).slick is not a function

I watched other issue, but the solution doesn’t suit me.

So I use the plugin: app.js:

window.$ = window.jQuery = require('jquery')

slider.js:

import 'slick-carousel'

These are two different files. I use jQuery on all pages, and slider only on a few. Solution with import $ from jquery will add jquery code to file. But it is already in app.js and connects before slider.js (console.log($) in slider.js return jQuery object)

$.fn.slick === undefined //without jquery in file

I looked at the source code of the plugin:

if (typeof define === 'function' && define.amd) {  
        define(['jquery'], factory);  
    } else if (typeof exports !== 'undefined') {  
        module.exports = factory(require('jquery'));  
    } else {  
        factory(jQuery);  
    }

Now the first condition is working: define(['jquery'], factory); If I delete everything except only factory (jQuery); then everything works fine. It looks weird.

I also found a recommendation:

plugins: [
        new webpack.ProvidePlugin({
            $: "jquery",
            jQuery: "jquery"
        })
    ],

but this option includes jQuery in every js file, it is unacceptable.

So far, the only working solution is to copy the slick.min.js from the node_modules folder to the plugins app folder and connect it to the page separately. But at the same time, I had to make scripts that initialized the slider in my app.js, this increases the percentage of unused code on the pages and increases the size of app.js.

Can you help me with anything?