Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use fullcalendar with webpack

I use npm, webpack and FullCalendar, but I get the following error in the browser console when using fullcalendar:

main.js:37556 Uncaught TypeError: (0 , _jquery2.default)(...).fullCalendar is not a function

How do I fix this?

I use FullCalendar 3.0.0-beta and jquery 3.1.0. My code is below.

index.js:

import $ from 'jquery'
import jQueryUI from 'jquery-ui'
import moment from 'moment'
import fullCalendar from 'fullcalendar'


$('#timetable').fullCalendar({
    editable: true,
    firstDay: 1,
    droppable: true,
})

webpack.config.js:

var path = require("path")
var webpack = require("webpack")
var BundleTracker = require("webpack-bundle-tracker")

module.exports = {
    context: __dirname,
    entry: [
        'fullcalendar',
        './static/index',
    ],
    output: {
        path: path.resolve('./static/bundles/'),
        filename: "[name].js",
    },

    plugins: [
        new BundleTracker({filename: './webpack-stats.json'}),
    ],

    resolve: {
        modulesDirectories: ['node_modules'],
        extensions: ['', '.js'],
    },

    module: {
        loaders:[
            { test: /\.js$/, exclude: /node_modules/, loader: 'babel', query: { presets: ['es2015'] } }
        ]
    }

}
like image 950
LeneH Avatar asked Sep 04 '16 20:09

LeneH


People also ask

What is the use of FullCalendar?

What is Fullcalendar? FullCalendar is a JavaScript library that seamlessly integrates with such popular JavaScript frameworks as Vue, React, Angular. Thanks to its excellent documentation, one won't have trouble incorporating the library into projects.

What is FullCalendar scheduler?

FullCalendar Premium (also known as “FullCalendar Scheduler”) is a collection of plugins released under a different license than the standard plugins. Each plugin offers additional functionality: Timeline View - display a large number of resources, with dates/times spanning horizontally.


1 Answers

I know I am somewhat late to the party here, but I thought I'd answer anyway in case somebody hits this up on Google.

Whenever I run into a jQuery Plugin with Webpack (which FullCalendar is), I need to make sure that jQuery itself is exposed to the global namespace before the plugin will work through require/import.

My webpack.config.js:

var webpack = require("webpack")
var path = require("path")
var ExtractTextPlugin = require("extract-text-webpack-plugin")
var HtmlWebpackPlugin = require("html-webpack-plugin")

module.exports = {
    entry: {
        app: "./index.js",
        vendor: [
            "jquery",
            "moment",
            "fullcalendar"
        ]
    },
    output: {
        path: path.join(__dirname, '../../public'),
        publicPath: '/',
        filename: "scripts/app.[chunkhash].js"
    },
    module: {
        loaders: [
            { test: /\.css$/, loader: ExtractTextPlugin.extract("style", ["css"]) },
            { test: require.resolve('jquery'), loader: 'expose?$!expose?jQuery' },
            { test: require.resolve('moment'), loader: 'expose?moment' }
        ]
    },
    resolve: {
      alias: {
        jquery: path.resolve(path.join(__dirname, '../..', 'node_modules', 'jquery')),
        fullcalendar: 'fullcalendar/dist/fullcalendar'
      }
    },
    plugins: [
        new webpack.optimize.DedupePlugin(),
        new webpack.optimize.CommonsChunkPlugin({ names: ["vendor"], filename: "scripts/[name].[chunkhash].js" }),
        new ExtractTextPlugin("styles/[name].[chunkhash].css"),
        new HtmlWebpackPlugin({
            template: "index.html.handlebars"
        }),
        new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/) 
    ]
};

The relevant part is where jquery and moment are forced to be in the global namespace via the loader: 'expose?$!expose?jQuery' syntax.

Second, because fullcalendar is packaged in a way that the require can't automatically pick it up, I setup an alias so that I can have a clean package name. This is the alias: { fullcalendar: 'fullcalendar/dist/fullcalendar' } bit.

These two let me load fullcalendar via require/import and use it as I normally would.

The styles also need to be loaded. For this one I have not created aliases yet, so I just did a relative path to the css file:

@import "../../../node_modules/fullcalendar/dist/fullcalendar.css";

You can replace fullcalendar.js with fullcalendar.min.js to avoid recompressing, but for my use case because I was bundling all the vendor JS files together, I thought I would get better compression if I had more files concatenated. (Ditto for CSS fullcalendar.css with fullcalendar.min.css)

Disclaimer: I don't know if this is the "correct" way of doing this, but I know it took me a fair bit of trial and error with webpack to get jQuery plug ins like FullCalendar and Select2 to work, and this shell and method did make it easy.

For reference, links to the relevant files in a public repo where I use this pattern:

webpack.config.js: https://github.com/thegrandpoobah/mftk-back-office/blob/e531de0a94130d6e9634ba5ab547a3e4d41c5c5f/app/src/public/webpack.config.js

style scss: https://github.com/thegrandpoobah/mftk-back-office/blob/e531de0a94130d6e9634ba5ab547a3e4d41c5c5f/app/src/public/styles/main.scss

module where I use fullcalendar: https://github.com/thegrandpoobah/mftk-back-office/blob/e531de0a94130d6e9634ba5ab547a3e4d41c5c5f/app/src/public/students/index.js#L277

like image 109
syazdani Avatar answered Oct 12 '22 18:10

syazdani