0

I have two wordpress themes. A parent and a child theme. The parent theme uses NPM to bring in all of the bootstrap, popper.js, and jQuery libraries. In the child theme I am choosing to bring whatever pieces of those packages I want into my project. When I write a jQuery function in another file and bring it into my app.js file and webpack compiles, it continues to throw jQuery not defined errors. I have used this same setup multiple times and never had any problems. Here's my code below.

:: Parent Theme ::

package.json

  {
    "name": "ouw_parent",
    "version": "0.1.3",
    "scripts": {
      "dev": "webpack --mode development --watch",
      "prod": "webpack --mode production"
    },
    "license": "GPLv3",
    "devDependencies": {
      "babel-core": "^6.26.3",
      "babel-loader": "^7.1.4",
      "babel-preset-env": "^1.7.0",
      "bootstrap": "^4.1.1",
      "bump-webpack-plugin": "^0.1.0",
      "css-loader": "^0.28.11",
      "jquery": "^3.3.1",
      "mini-css-extract-plugin": "^0.4.0",
      "node-sass": "^4.9.0",
      "optimize-css-assets-webpack-plugin": "^4.0.2",
      "popper.js": "^1.14.3",
      "postcss-loader": "^2.1.5",
      "sass-loader": "^7.0.1",
      "style-loader": "^0.21.0",
      "uglifyjs-webpack-plugin": "^1.2.5",
      "webpack": "^4.8.0",
      "webpack-cli": "^2.1.3",
      "webpack-dev-server": "^3.1.4"
    },
    "dependencies": {}
  }

postcss.config.js

module.exports = {
        plugins: [
            require('autoprefixer')
        ]
    };

.babelrc

{
    "presets": [
        "env"
    ]
}

webpack.config.js

const path                      = require('path');
const Bump                      = require("bump-webpack-plugin");
const UglifyJsPlugin            = require("uglifyjs-webpack-plugin");
const MiniCssExtractPlugin      = require("mini-css-extract-plugin");
const OptimizeCSSAssetsPlugin   = require("optimize-css-assets-webpack-plugin");


const config = {
    entry: {
        app: './assets/js/app.js',
    },
    output: {
        filename: './dist/js/[name].js',
        path: path.resolve(__dirname, 'assets'),
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: "/dist/css/[name].css",
            chunkFilename: "/dist/css/[id].css" 
        }),
        new Bump([
            'package.json',
        ]),
    ],
    module: {
        rules: [
            {
                test: /\.scss$/,
                use: [
                    MiniCssExtractPlugin.loader,
                        'css-loader',
                        {loader: 'postcss-loader', options: {grid: false}}, 
                        'sass-loader'
                ],
            },
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: {
                  loader: "babel-loader"
                }
              }
        ]
    },
    optimization: {
        minimizer: [
            new UglifyJsPlugin({
            cache: true,
            parallel: true,
            sourceMap: true // set to true if you want JS source maps
            }),
            new OptimizeCSSAssetsPlugin({})
        ]
    }
}

module.exports = config;

:: Child Theme ::

package.json

 {
  "name": "ouw_child",
  "version": "0.1.193",
  "scripts": {
    "dev": "webpack --mode development --watch",
    "prod": "webpack --mode production"
  },
  "license": "GPLv3",
  "devDependencies": {
    "babel-core": "^6.26.3",
    "babel-loader": "^7.1.4",
    "babel-preset-env": "^1.7.0",
    "bump-webpack-plugin": "^0.1.0",
    "css-loader": "^0.28.11",
    "mini-css-extract-plugin": "^0.4.0",
    "node-sass": "^4.9.0",
    "optimize-css-assets-webpack-plugin": "^4.0.2",
    "postcss-loader": "^2.1.5",
    "sass-loader": "^7.0.1",
    "style-loader": "^0.21.0",
    "uglifyjs-webpack-plugin": "^1.2.5",
    "webpack": "^4.8.0",
    "webpack-cli": "^2.1.3",
    "webpack-dev-server": "^3.1.4"
  },
  "dependencies": {}
}

postcss.config.js

module.exports = {
        plugins: [
            require('autoprefixer')
        ]
    };

.babelrc

{
    "presets": [
        "env"
    ]
}

webpack.config.js

const path                      = require('path');
const Bump                      = require("bump-webpack-plugin");
const UglifyJsPlugin            = require("uglifyjs-webpack-plugin");
const MiniCssExtractPlugin      = require("mini-css-extract-plugin");
const OptimizeCSSAssetsPlugin   = require("optimize-css-assets-webpack-plugin");


const config = {
    entry: {
        app: './assets/js/app.js',
    },
    output: {
        filename: './dist/js/[name].js',
        path: path.resolve(__dirname, 'assets'),
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: "/dist/css/[name].css",
            chunkFilename: "/dist/css/[id].css" 
        }),
        new Bump([
            'package.json',
        ]),
    ],
    module: {
        rules: [
            {
                test: /\.scss$/,
                use: [
                    MiniCssExtractPlugin.loader,
                        'css-loader',
                        {loader: 'postcss-loader', options: {grid: false}}, 
                        'sass-loader'
                ],
            },
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: {
                  loader: "babel-loader"
                }
              }
        ]
    },
    optimization: {
        minimizer: [
            new UglifyJsPlugin({
            cache: true,
            parallel: true,
            sourceMap: true // set to true if you want JS source maps
            }),
            new OptimizeCSSAssetsPlugin({})
        ]
    }
}

module.exports = config;

:: Now here is where the error happens ::

Here is my child theme structure:

-assets

----dist

--------js

--------app.js

--------tooltip.js

----scss

Finally... Here is the child theme app.js file that brings in my tooltip.js file

// bootstrap scss
import '../../assets/scss/core.scss';

// bootstrap js
import '../../../ouw-parent-theme/node_modules/jquery';
import '../../../ouw-parent-theme/node_modules/popper.js';
import '../../../ouw-parent-theme/node_modules/bootstrap';

// or you could pull JS by utilities
// import '../../../ouw-parent-theme/node_modules/bootstrap/js/dist/util';
// import '../../../ouw-parent-theme/node_modules/bootstrap/js/dist/dropdown';
// import '../../../ouw-parent-theme/node_modules/bootstrap/js/dist/tooltip';

// other
import '../js/tooltip.js';

And here is my tooltip.js file

( function($){
    $('[data-toggle="tooltip"]').tooltip();
})(jQuery)

The tooltip.js file continues to say that jQuery is not defined. Even though my Bootstrap menu toggles just fine, So I know that jQuery is there. Also... Here is the final build file that gets output. You can see that all the dependencies are there.

Please help! I cannot figure it out. I have this same setup on another site and it DOES work.

I've removed the big chunks of code so it can be viewed here

/******/ (function(modules) { // webpackBootstrap
/******/    // The module cache
/******/    var installedModules = {};
/******/
/******/    // The require function
/******/    function __webpack_require__(moduleId) {
/******/
/******/        // Check if module is in cache
/******/        if(installedModules[moduleId]) {
/******/            return installedModules[moduleId].exports;
/******/        }
/******/        // Create a new module (and put it into the cache)
/******/        var module = installedModules[moduleId] = {
/******/            i: moduleId,
/******/            l: false,
/******/            exports: {}
/******/        };
/******/
/******/        // Execute the module function
/******/        modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/        // Flag the module as loaded
/******/        module.l = true;
/******/
/******/        // Return the exports of the module
/******/        return module.exports;
/******/    }
/******/
/******/
/******/    // expose the modules object (__webpack_modules__)
/******/    __webpack_require__.m = modules;
/******/
/******/    // expose the module cache
/******/    __webpack_require__.c = installedModules;
/******/
/******/    // define getter function for harmony exports
/******/    __webpack_require__.d = function(exports, name, getter) {
/******/        if(!__webpack_require__.o(exports, name)) {
/******/            Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/        }
/******/    };
/******/
/******/    // define __esModule on exports
/******/    __webpack_require__.r = function(exports) {
/******/        if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/            Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/        }
/******/        Object.defineProperty(exports, '__esModule', { value: true });
/******/    };
/******/
/******/    // create a fake namespace object
/******/    // mode & 1: value is a module id, require it
/******/    // mode & 2: merge all properties of value into the ns
/******/    // mode & 4: return value when already ns object
/******/    // mode & 8|1: behave like require
/******/    __webpack_require__.t = function(value, mode) {
/******/        if(mode & 1) value = __webpack_require__(value);
/******/        if(mode & 8) return value;
/******/        if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/        var ns = Object.create(null);
/******/        __webpack_require__.r(ns);
/******/        Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/        if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/        return ns;
/******/    };
/******/
/******/    // getDefaultExport function for compatibility with non-harmony modules
/******/    __webpack_require__.n = function(module) {
/******/        var getter = module && module.__esModule ?
/******/            function getDefault() { return module['default']; } :
/******/            function getModuleExports() { return module; };
/******/        __webpack_require__.d(getter, 'a', getter);
/******/        return getter;
/******/    };
/******/
/******/    // Object.prototype.hasOwnProperty.call
/******/    __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/    // __webpack_public_path__
/******/    __webpack_require__.p = "";
/******/
/******/
/******/    // Load entry module and return exports
/******/    return __webpack_require__(__webpack_require__.s = "./assets/js/app.js");
/******/ })
/************************************************************************/
/******/ ({

/***/ "../ouw-parent-theme/node_modules/bootstrap/dist/js/bootstrap.js":
/*!***********************************************************************!*\
  !*** ../ouw-parent-theme/node_modules/bootstrap/dist/js/bootstrap.js ***!
  \***********************************************************************/


/***/ "../ouw-parent-theme/node_modules/jquery/dist/jquery.js":
/*!**************************************************************!*\
  !*** ../ouw-parent-theme/node_modules/jquery/dist/jquery.js ***!
  \**************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {



/***/ "../ouw-parent-theme/node_modules/popper.js/dist/esm/popper.js":
/*!*********************************************************************!*\
  !*** ../ouw-parent-theme/node_modules/popper.js/dist/esm/popper.js ***!
  \*********************************************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {


/***/ "./assets/js/app.js":
/*!**************************!*\
  !*** ./assets/js/app.js ***!
  \**************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";
eval("\n\n__webpack_require__(/*! ../../assets/scss/core.scss */ \"./assets/scss/core.scss\");\n\n__webpack_require__(/*! ../../../ouw-parent-theme/node_modules/jquery */ \"../ouw-parent-theme/node_modules/jquery/dist/jquery.js\");\n\n__webpack_require__(/*! ../../../ouw-parent-theme/node_modules/popper.js */ \"../ouw-parent-theme/node_modules/popper.js/dist/esm/popper.js\");\n\n__webpack_require__(/*! ../../../ouw-parent-theme/node_modules/bootstrap */ \"../ouw-parent-theme/node_modules/bootstrap/dist/js/bootstrap.js\");\n\n__webpack_require__(/*! ../js/tooltip.js */ \"./assets/js/tooltip.js\");\n\n//# sourceURL=webpack:///./assets/js/app.js?");

/***/ }),

/***/ "./assets/js/tooltip.js":
/*!******************************!*\
  !*** ./assets/js/tooltip.js ***!
  \******************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";
eval("\n\n// ( function($){\n//     $('[data-toggle=\"tooltip\"]').tooltip();\n// })(jQuery)\n\n\n$(document).ready(function () {\n  console.log($);\n});\n\n//# sourceURL=webpack:///./assets/js/tooltip.js?");

/***/ }),

/***/ "./assets/scss/core.scss":
/*!*******************************!*\
  !*** ./assets/scss/core.scss ***!
  \*******************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

eval("// extracted by mini-css-extract-plugin\n\n//# sourceURL=webpack:///./assets/scss/core.scss?");

/***/ }),

/***/ "./node_modules/webpack/buildin/global.js":
/*!***********************************!*\
  !*** (webpack)/buildin/global.js ***!
  \***********************************/
/*! no static exports found */
/***/ (function(module, exports) {

eval("var g;\n\n// This works in non-strict mode\ng = (function() {\n\treturn this;\n})();\n\ntry {\n\t// This works if eval is allowed (see CSP)\n\tg = g || Function(\"return this\")() || (1, eval)(\"this\");\n} catch (e) {\n\t// This works if the window reference is available\n\tif (typeof window === \"object\") g = window;\n}\n\n// g can still be undefined, but nothing to do about it...\n// We return undefined, instead of nothing here, so it's\n// easier to handle this case. if(!global) { ...}\n\nmodule.exports = g;\n\n\n//# sourceURL=webpack:///(webpack)/buildin/global.js?");

/***/ })

/******/ });

1 Answer 1

2

To define jQuery globally through Webpack, use the ProvidePlugin plugin in your webpack.config.js file:

const webpack = require('webpack');    

module.exports = {
  plugins: [
    new webpack.ProvidePlugin({
      $: 'jquery',
      jQuery: 'jquery'
    });
  ]
}

See the plugin's documentation for more examples.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.