Skip to content

Instantly share code, notes, and snippets.

@thehme
Last active December 18, 2018 15:22
Show Gist options
  • Save thehme/dfec6f3e1949239a1db263fdfc687ef3 to your computer and use it in GitHub Desktop.
Save thehme/dfec6f3e1949239a1db263fdfc687ef3 to your computer and use it in GitHub Desktop.

I have a large backbone/requirejs app that I want to migrate to webpack, the latest "webpack": "^4.27.1".

I have been reading the https://webpack.js.org/concepts/ docs and saw this video by Dodss - https://www.youtube.com/watch?v=a96r7Tjf0Ps

My current webpack.config.js file looks like this:

var path = require('path');
module.exports = {
    mode: 'development',
    context: path.resolve(__dirname),
    entry: {
        main: './public/assets/js/main',
        base: './public/assets/js/base'
    },
    output: {
        filename: '[name].js',
        path: __dirname + '/dist'
    },
    resolve: {
        alias: { 
            '/libs': './libs',
            'events': path.resolve(__dirname, 'public/assets/js/events'), 
            'views': path.resolve(__dirname, 'public/assets/js/views'),
            'models': path.resolve(__dirname, 'public/assets/js/models'),
            'collections': path.resolve(__dirname, 'public/assets/js/collections'),
            'templates': path.resolve(__dirname, 'public/assets/templates'),
            'jquery': path.resolve(__dirname, 'public/assets/js/libs/jquery/jquery'),
            'raven': path.resolve(__dirname, 'public/assets/js/libs/raven/raven'),
            'backbone': path.resolve(__dirname, 'public/assets/js/libs/backbone/backbone'),
            'daterangepicker': path.resolve(__dirname, 'public/assets/js/libs/daterangepicker/daterangepicker'),
            'highchart': path.resolve(__dirname, 'public/assets/js/libs/highchart/highcharts'),
            'intlTelInput': path.resolve(__dirname, 'public/assets/js/libs/intltelinput/intlTelInput'),
            'mask': path.resolve(__dirname, 'public/assets/js/libs/inputmask/inputmask'),
            'momentTimeZone': path.resolve(__dirname, 'public/assets/js/libs/moment-timezone/moment-timezone-with-data-2010-2020'),
            'socket': path.resolve(__dirname, 'public/assets/js/libs/socket.io-client/socket'),
            'kTranslate': path.resolve(__dirname, 'public/assets/js/utils/kTranslate'),
            'detectizr': path.resolve(__dirname, 'public/assets/js/libs/detectizr/detectizr'),
            'sjcl': path.resolve(__dirname, 'public/assets/js/libs/sjcl/sjcl'),
            'authRouter': './authRouter',
            'client': './client',
            'router': './router',
            'auth': './auth',
        }
    }
}

Many of the files in the project seem to be bundling okay when I run webpack --display-error-details, but I get an error about the node_modules:

ERROR in ./node_modules/stream-browserify/node_modules/readable-stream/lib/internal/streams/stream-browser.js
Module not found: Error: Can't resolve 'events' in '/path/to/project/node_modules/stream-browserify/node_modules/readable-stream/lib/internal/streams'
resolve 'events' in '/path/to/project/node_modules/stream-browserify/node_modules/readable-stream/lib/internal/streams'
  Parsed request is a module
  using description file: /path/to/project/node_modules/stream-browserify/node_modules/readable-stream/package.json (relative path: ./lib/internal/streams)
    aliased with mapping 'events': '/path/to/project/public/assets/js/events' to '/path/to/project/public/assets/js/events'
      using description file: /path/to/project/node_modules/stream-browserify/node_modules/readable-stream/package.json (relative path: ./lib/internal/streams)
        using description file: /path/to/project/package.json (relative path: ./public/assets/js/events)
          no extension
            Field 'browser' doesn't contain a valid alias configuration
            /path/to/project/public/assets/js/events is not a file
          .wasm
            Field 'browser' doesn't contain a valid alias configuration
            /path/to/project/public/assets/js/events.wasm doesn't exist
          .mjs
            Field 'browser' doesn't contain a valid alias configuration
            /path/to/project/public/assets/js/events.mjs doesn't exist
          .js
            Field 'browser' doesn't contain a valid alias configuration
            /path/to/project/public/assets/js/events.js doesn't exist
          .json
            Field 'browser' doesn't contain a valid alias configuration
            /path/to/project/public/assets/js/events.json doesn't exist
          as directory
            existing directory
              using path: /path/to/project/public/assets/js/events/index
                using description file: /path/to/project/package.json (relative path: ./public/assets/js/events/index)
                  no extension
                    Field 'browser' doesn't contain a valid alias configuration
                    /path/to/project/public/assets/js/events/index doesn't exist
                  .wasm
                    Field 'browser' doesn't contain a valid alias configuration
                    /path/to/project/public/assets/js/events/index.wasm doesn't exist
                  .mjs
                    Field 'browser' doesn't contain a valid alias configuration
                    /path/to/project/public/assets/js/events/index.mjs doesn't exist
                  .js
                    Field 'browser' doesn't contain a valid alias configuration
                    /path/to/project/public/assets/js/events/index.js doesn't exist
                  .json
                    Field 'browser' doesn't contain a valid alias configuration
                    /path/to/project/public/assets/js/events/index.json doesn't exist
[/path/to/project/public/assets/js/events]
[/path/to/project/public/assets/js/events.wasm]
[/path/to/project/public/assets/js/events.mjs]
[/path/to/project/public/assets/js/events.js]
[/path/to/project/public/assets/js/events.json]
[/path/to/project/public/assets/js/events/index]
[/path/to/project/public/assets/js/events/index.wasm]
[/path/to/project/public/assets/js/events/index.mjs]
[/path/to/project/public/assets/js/events/index.js]
[/path/to/project/public/assets/js/events/index.json]
 @ ./node_modules/stream-browserify/node_modules/readable-stream/lib/internal/streams/stream-browser.js 1:17-34
 @ ./node_modules/stream-browserify/node_modules/readable-stream/lib/_stream_writable.js
 @ ./node_modules/stream-browserify/node_modules/readable-stream/writable-browser.js
 @ ./node_modules/stream-browserify/index.js
 @ ./node_modules/browserify-sign/browser/index.js
 @ ./node_modules/crypto-browserify/index.js
 @ ./public/assets/js/libs/sjcl/sjcl.js
 @ ./public/assets/js/views/auth.view.js
 @ ./public/assets/js/authRouter.js
 @ ./public/assets/js/auth.js
 @ ./public/assets/js/base.js

My project architecture looks like this:

app
-/public
  /assets
  /img
  /js
      /collections
      /views
      /events
      /models
      ...
-/dist
-/node_modules
...
@thehme
Copy link
Author

thehme commented Dec 17, 2018

Since fixing the above issue, I now have another issue. When I load the webpack build, the page loads, but there are errors in the console that say:

VM7106 base.js:186 TypeError: $ is not a function
    at eval (VM7107 base.js:39)
    at eval (VM7107 base.js:49)
__webpack_require__.oe @ VM7106 base.js:186
Promise.catch (async)
(anonymous) @ VM7107 base.js:49
./public/assets/js/base.js @ VM7106 base.js:209
__webpack_require__ @ VM7106 base.js:64
(anonymous) @ VM7106 base.js:197
(anonymous) @ VM7106 base.js:200
VM7107 base.js:39 Uncaught (in promise) TypeError: $ is not a function
    at eval (VM7107 base.js:39)
    at eval (VM7107 base.js:49)
(anonymous) @ VM7107 base.js:39
(anonymous) @ VM7107 base.js:49
Promise.catch (async)
(anonymous) @ VM7107 base.js:49
./public/assets/js/base.js @ VM7106 base.js:209
__webpack_require__ @ VM7106 base.js:64
(anonymous) @ VM7106 base.js:197
(anonymous) @ VM7106 base.js:200
VM7106 base.js:186 TypeError: Cannot read property 'extend' of undefined
    at Object.eval (VM7134 inputmask.js:23)
    at eval (VM7134 inputmask.js:10)
    at eval (VM7134 inputmask.js:12)
    at Object../public/assets/js/libs/inputmask/inputmask.js (VM7116 3.js:54)
    at __webpack_require__ (VM7106 base.js:64)
    at eval (VM7133 auth.view.js:5)
    at Object../public/assets/js/views/auth.view.js (VM7109 8.js:66)
    at __webpack_require__ (VM7106 base.js:64)
    at eval (VM7121 authRouter.js:9)
    at Object../public/assets/js/authRouter.js (VM7109 8.js:21)
__webpack_require__.oe @ VM7106 base.js:186
Promise.catch (async)
(anonymous) @ VM7107 base.js:35
./public/assets/js/base.js @ VM7106 base.js:209
__webpack_require__ @ VM7106 base.js:64
(anonymous) @ VM7106 base.js:197
(anonymous) @ VM7106 base.js:200
VM7134 inputmask.js:23 Uncaught (in promise) TypeError: Cannot read property 'extend' of undefined
    at Object.eval (VM7134 inputmask.js:23)
    at eval (VM7134 inputmask.js:10)
    at eval (VM7134 inputmask.js:12)
    at Object../public/assets/js/libs/inputmask/inputmask.js (VM7116 3.js:54)
    at __webpack_require__ (VM7106 base.js:64)
    at eval (VM7133 auth.view.js:5)
    at Object../public/assets/js/views/auth.view.js (VM7109 8.js:66)
    at __webpack_require__ (VM7106 base.js:64)
    at eval (VM7121 authRouter.js:9)
    at Object../public/assets/js/authRouter.js (VM7109 8.js:21)
(anonymous) @ VM7134 inputmask.js:23
(anonymous) @ VM7134 inputmask.js:10
(anonymous) @ VM7134 inputmask.js:12
./public/assets/js/libs/inputmask/inputmask.js @ VM7116 3.js:54
__webpack_require__ @ VM7106 base.js:64
(anonymous) @ VM7133 auth.view.js:5
./public/assets/js/views/auth.view.js @ VM7109 8.js:66
__webpack_require__ @ VM7106 base.js:64
(anonymous) @ VM7121 authRouter.js:9
./public/assets/js/authRouter.js @ VM7109 8.js:21
__webpack_require__ @ VM7106 base.js:64
(anonymous) @ VM7118 auth.js:5
./public/assets/js/auth.js @ VM7109 8.js:10
__webpack_require__ @ VM7106 base.js:64
(anonymous) @ VM7107 base.js:5
Promise.catch (async)
(anonymous) @ VM7107 base.js:35
./public/assets/js/base.js @ VM7106 base.js:209
__webpack_require__ @ VM7106 base.js:64
(anonymous) @ VM7106 base.js:197
(anonymous) @ VM7106 base.js:200
Navigated to https://localhost:5050/login?lang=en-us
base.js:formatted:377 TypeError: $ is not a function
    at eval (base.js:39)
    at eval (base.js:49)
__webpack_require__.oe @ base.js:formatted:377
Promise.catch (async)
(anonymous) @ base.js:49
./public/assets/js/base.js @ base.js:formatted:415
__webpack_require__ @ base.js:formatted:115
(anonymous) @ base.js:formatted:400
(anonymous) @ base.js:formatted:405
base.js:39 Uncaught (in promise) TypeError: $ is not a function
    at eval (base.js:39)
    at eval (base.js:49)
(anonymous) @ base.js:39
(anonymous) @ base.js:49
Promise.catch (async)
(anonymous) @ base.js:49
./public/assets/js/base.js @ base.js:formatted:415
__webpack_require__ @ base.js:formatted:115
(anonymous) @ base.js:formatted:400
(anonymous) @ base.js:formatted:405
base.js:formatted:377 TypeError: Cannot read property 'extend' of undefined
    at Object.eval (inputmask.js:23)
    at eval (inputmask.js:10)
    at eval (inputmask.js:12)
    at Object../public/assets/js/libs/inputmask/inputmask.js (3.js:54)
    at __webpack_require__ (base.js:formatted:115)
    at eval (auth.view.js:5)
    at Object../public/assets/js/views/auth.view.js (8.js:66)
    at __webpack_require__ (base.js:formatted:115)
    at eval (authRouter.js:9)
    at Object../public/assets/js/authRouter.js (8.js:21)
__webpack_require__.oe @ base.js:formatted:377
Promise.catch (async)
(anonymous) @ base.js:35
./public/assets/js/base.js @ base.js:formatted:415
__webpack_require__ @ base.js:formatted:115
(anonymous) @ base.js:formatted:400
(anonymous) @ base.js:formatted:405
inputmask.js:23 Uncaught (in promise) TypeError: Cannot read property 'extend' of undefined
    at Object.eval (inputmask.js:23)
    at eval (inputmask.js:10)
    at eval (inputmask.js:12)
    at Object../public/assets/js/libs/inputmask/inputmask.js (3.js:54)
    at __webpack_require__ (base.js:formatted:115)
    at eval (auth.view.js:5)
    at Object../public/assets/js/views/auth.view.js (8.js:66)
    at __webpack_require__ (base.js:formatted:115)
    at eval (authRouter.js:9)
    at Object../public/assets/js/authRouter.js (8.js:21)

I googled the error and found some suggestions to add an item for jquery into the plugins section for the webpack.config.js file, so I added the following and also installed jquery via npm, i.e. npm install jquery --save-dev

plugins: [
    // Provides jQuery for other JS bundled with Webpack
    new webpack.ProvidePlugin({
      $: 'jquery',
      jQuery: 'jquery',
      jquery: 'jquery'
    })
  ]

When I rebuild the project, I see the same errors.

@thehme
Copy link
Author

thehme commented Dec 18, 2018

Someone suggested adding window to my jquery plugin, but it still does not work, I get the same error when I load the page. I am wondering if the issue is in how jquery is used in the entry file, e.g.

if (['login'].indexOf(urlEndpoint) !== -1) {
    require(['jquery'], function($) {
        $( document ).ready(function() {
            if (urlEndpoint) {
               ...
            }
        });
    });
}

Need to figure out what needs to change in the app for this to work. Previously I had an issue with the use of text! to use the underscore templates, and after looking into it more, i had to change all those instances to text-loader! everywhere. It was a lot changes, but it was the only way I was able to fix this. I also have jquery in my vendors folder (above \libs) and then I also installed it via npm for the plugin to work (according to Stackoverflow), so maybe there is a conflict in here somewhere.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment