Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Foundation 6.4 JavaScript within project not working, but external JS does

I am losing my mind with javascript in Foundation 6.4. I have no idea what's going on with this Webpack thing. It seems like some libraries/plugins work and some do not. My latest issue is with plyr (https://plyr.io/). I do not understand why TweenMax works 100% fine and plyr.js does not. What am I doing wrong?

This is the error I get..

app.js:23026 Uncaught ReferenceError: plyr is not defined

This is what my app.js looks like..

import $ from 'jquery';
import whatInput from 'what-input';


window.$ = $;
window.jQuery = $;


require('./TweenMax.js');
require('./plyr.js');


//import Foundation from 'foundation-sites';
// If you want to pick and choose which modules to include, comment out the above and uncomment
// the line below
import './lib/foundation-explicit-pieces';

$(document).foundation().ready(function(){

    TweenMax.set(".logo-center", {transformOrigin:"50% 50%"});

    var blast = plyr.setup('#blast', {
        hideControls: true,
        clickToPlay: false,
        controls: []
    }); 
});

I also have the path to plyr.js in my config.yml file:

# Your project's server will run on localhost:xxxx at this port
PORT: 8000

# Autoprefixer will make sure your CSS works with these browsers
COMPATIBILITY:
  - "last 2 versions"
  - "ie >= 10"
  - "ios >= 9"

# UnCSS will use these settings
UNCSS_OPTIONS:
  html:
    - "src/**/*.html"
  ignore:
    - !!js/regexp .foundation-mq
    - !!js/regexp ^\.is-.*

# Gulp will reference these paths when it copies files
PATHS:
  # Path to dist folder
  dist: "dist"  
  # Paths to static assets that aren't images, CSS, or JavaScript
  assets:
    - "src/assets/**/*"
    - "!src/assets/{img,js,scss}/**/*"
  # Paths to Sass libraries, which can then be loaded with @import
  sass:
    - "node_modules/foundation-sites/scss"
    - "node_modules/motion-ui/src"
  # Paths to JavaScript entry points for webpack to bundle modules
  entries:
    - "src/assets/js/app.js"
    - "src/assets/js/plyr.js"
    - "src/assets/js/TweenMax.js"
like image 926
Dustin Avatar asked Jan 30 '18 17:01

Dustin


3 Answers

I assume you started your Foundation project from ZURB template. It uses a Gulpfile (gulpfile.babel.js) for JavaScript module bundling with Webpack.

Inside this script there is a Webpack configuration like below:

let webpackConfig = {
  module: {
    rules: [
      {
        test: /.js$/,
        use: [
          {
            loader: 'babel-loader'
          }
        ]
      }
    ]
  }
}

Webpack config can define, in the module section, some rules for modules (configure loaders, parser options, etc.). In particular loaders enable webpack to process files and bundle them (or do other Webpack tasks).

So the specific configuration in gulpfile.babel.js tells to Webpack to use babel-loader for all files in /src folder with js extension. However as explained in Webpack - Shimming some modules/libraries may expect global dependencies (e.g. $ for jQuery) or create globals which need to be exported.

To support these libraries, like Plyr, you can use expose-loader. So add a module rule to Webpack config inside gulpfile.babel.js, pointing to expose-loader for plyr.js:

let webpackConfig = {
  module: {
    rules: [
      {
        test: /plyr.js/,
        use: [
          {
            loader: 'expose-loader',
            options: 'plyr'
          }
        ]
      },
      {
        test: /.js$/,
        use: [
          {
            loader: 'babel-loader'
          }
        ]
      }
    ]
  }
}

No other changes are needed to your project files (config.yml, app.js).

This way you should access plyr as global variable like in your app.js:

var blast = plyr.setup('#blast', {
    hideControls: true,
    clickToPlay: false,
    controls: []
}); 
like image 120
beaver Avatar answered Nov 18 '22 04:11

beaver


You might need to use something like expose-loader so that plyr is available globally on window. Here's more info on how we used expose-loader in our project.

like image 1
olore Avatar answered Nov 18 '22 04:11

olore


Without the actual project code, it is rather difficult to figure out what went wrong. But here's my take on the situation.

First off, why are you import plyr from a local file? Shouldn't it be require('plyr') instead of require('./plyr.js').

Also, why are you using plyr with a lower-case 'p' when the module exports the library as Plyr, with an upper-case 'P' in global binding, i.e., binding on window.

Your code:

plyr.setup('#blast', {
    ...
}); 

The plyr module:

! function (e, t) {
    "object" == typeof exports && "undefined" != typeof module
        ? module.exports = t() // commonjs
        : "function" == typeof define && define.amd
            ? define("Plyr", t) // requirejs
            : e.Plyr = t() // window/global binding
}(this, function () {
    ...
});

Full dump here and here. Source here.

You can make it work by loading plyr.js in your index.html before loading your code and use the globally bound Plyr.

// index.html
<html>
<head>
    <script src="plyr.js"></script> // window.Plyr = ...
</head>
<body>
    ...
    <script src="bundle.js"></script>
</body>
</html>


//main.js
...
Plyr.setup('#blast', {
    hideControls: true,
    clickToPlay: false,
    controls: []
});

You could also import plyr module in your code as a named import:

import Plyr from 'plyr';

...

Plyr.setup('#blast', {
    hideControls: true,
    clickToPlay: false,
    controls: []
});

If all this still don't work, I believe it'd best if you share your project code - at least something more than you did alreday.

like image 1
zhirzh Avatar answered Nov 18 '22 05:11

zhirzh