Materialize: Webpack import materializecss but can't call methods

Created on 11 Apr 2017  路  4Comments  路  Source: Dogfalo/materialize

Description

I'm trying to call some materializecss javascript methods in my Vue project, based on CLI created with Webpack, but when I do the call, there is some problem, and I recieve "$(...).modal is not a function" for example.

Repro Steps

My webpack config:

var path = require('path')
var utils = require('./utils')
var config = require('../config')
var vueLoaderConfig = require('./vue-loader.conf')
var ExtractTextPlugin = require('extract-text-webpack-plugin');

function resolve (dir) {
  return path.join(__dirname, '..', dir)
}

module.exports = {
  entry: {
    app: './src/main.js'
  },
  output: {
    path: config.build.assetsRoot,
    filename: '[name].js',
    publicPath: process.env.NODE_ENV === 'production'
      ? config.build.assetsPublicPath
      : config.dev.assetsPublicPath
  },
  resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
      '$': 'jquery',
      'jQuery': 'jquery',
      '@': resolve('src'),
      'vue$': 'vue/dist/vue.esm.js'
    }
  },
  module: {
    rules: [
      {
        test: /\.(js|vue)$/,
        loader: 'eslint-loader',
        enforce: 'pre',
        include: [resolve('src'), resolve('test')],
        options: {
          formatter: require('eslint-friendly-formatter')
        }
      },
      {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: vueLoaderConfig
      },
      {
        test: /\.js$/,
        loader: 'babel-loader',
        include: [resolve('src'), resolve('test')]
      },
      {
        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: utils.assetsPath('img/[name].[hash:7].[ext]')
        }
      },
      {
        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
        }
      }
    ]
  }
}

My main.js:

[...]

require('materialize-css/dist/css/materialize.min.css')
require('materialize-css/dist/js/materialize.min.js')

[...]

The template:

    <select id="sel"name="sel">
      <option value="foo bar">Foo Bar</option>
    </select>

The script:

import $ from 'jquery'

export default {
  mounted: function () {
    $(document).ready(function () {
      $('#sel').material_select()
    })
  }
}

The error I'm facing:
Uncaught TypeError: $(...).material_select is not a function at eval (eval at <anonymous> (eval at <anonymous> (0.js:278)), <anonymous>:1:11) at HTMLDocument.eval (eval at <anonymous> (0.js:278), <anonymous>:42:7) at mightThrow (eval at <anonymous> (0.js:45), <anonymous>:3583:29) at process (eval at <anonymous> (0.js:45), <anonymous>:3651:12)

To ensure that all the script was loaded, I put a console.log in the end of materialize.min.js file.

Screenshots / Codepen

Additionally, there's a screenshot to show that jQuery was loaded, but the materialize-css javascript couldn't be called.
image

Most helpful comment

I was struggling with this issue a few days ago, I was eventually able to get it to work with the following setup:

In webpack.base.conf.js, add:

resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
        'vue$': 'vue/dist/vue.esm.js',
        '@': resolve('src'),
                'jquery': resolve('node_modules/jquery/dist/jquery')
    }
}

In webpack.prod.conf.js && webpack.dev.conf.js:

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

In main.js:

import 'materialize-css/dist/js/materialize.min.js'
import 'materialize-css/dist/css/materialize.min.css'

In your component.vue:

import $ from 'jquery' //this one is not needed if your eslint is disabled

and

mounted () {
    $('select').material_select()
},

All 4 comments

I was struggling with this issue a few days ago, I was eventually able to get it to work with the following setup:

In webpack.base.conf.js, add:

resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
        'vue$': 'vue/dist/vue.esm.js',
        '@': resolve('src'),
                'jquery': resolve('node_modules/jquery/dist/jquery')
    }
}

In webpack.prod.conf.js && webpack.dev.conf.js:

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

In main.js:

import 'materialize-css/dist/js/materialize.min.js'
import 'materialize-css/dist/css/materialize.min.css'

In your component.vue:

import $ from 'jquery' //this one is not needed if your eslint is disabled

and

mounted () {
    $('select').material_select()
},

Thank you @DRoet ! It works!

@DRoet Thank you! Worked so well.

@DRoet Thanks a lot of!!! you are the best)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ruslandzhumaev picture ruslandzhumaev  路  3Comments

alexknipfer picture alexknipfer  路  3Comments

locomain picture locomain  路  3Comments

serkandurusoy picture serkandurusoy  路  3Comments

ericlormul picture ericlormul  路  3Comments