foundation-sites: Problems while importing foundation js in webpack.

I would like to import some foundation js files in a webpack app.

In my entry js file I do the following:

import 'foundation-sites/js/foundation.core.js'; // this works
import 'foundation-sites/js/foundation.tabs.js'; // this works
import 'foundation-sites/js/foundation.reveal.js'; // this fails

The last one fails with the following error:

ERROR in ./~/foundation-sites/js/foundation.reveal.js
Module not found: Error: Cannot resolve module 'foundation' in /home/kai/Projects/myapp/node_modules/foundation-sites/js
 @ ./~/foundation-sites/js/foundation.reveal.js 474:4-476:6

So it seems there is a problem with all files that contain the code define(['foundation'] ... as foundation is not defined anywhere.

I installed foundation-sites (v6.0.5) using NPM.

How do I import those files that have the define(['foundation'] correctly?

About this issue

  • Original URL
  • State: closed
  • Created 9 years ago
  • Reactions: 4
  • Comments: 68 (11 by maintainers)

Most upvoted comments

+1

You guys have done so much nice work in allowing us to modularly import SCSS, it’s a tragedy that I can’t use this library because your javascript is essentially un-importable as a CommonJS module. This is going to severely limit its adoption in both webpack and browserify build environments.

We’ve just merged #9965 which moves all of Foundation’s javascript to true module dependency, and actually uses webpack for our internal builds, so this will be well and truly fixed in the 6.4 release, scheduled for mid to late May.

I took solution from https://github.com/vue-foundation/vue-foundation/blob/master/src/foundation.js and it works fine for me.

import jQuery from 'jquery';
import { Foundation } from 'foundation-sites/js/foundation.core';
import { Tooltip } from 'foundation-sites/js/foundation.tooltip';
import { Box } from 'foundation-sites/js/foundation.util.box';

Foundation.addToJquery(jQuery);

Foundation.Box = Box;

Triggers.init(jQuery, Foundation);
Foundation.plugin(Tooltip, 'Tooltip');

// and so on

Hey guys, it’s much easier than you think 😉 Just npm i script-loader and prefix the import with a script! everywhere where you need to load the script in the global scope. No need to configure externals, aliases or ProvidePlugins in webpack.

If you want to load everything from foundation it would look like this:

import 'script!jquery'
import 'script!what-input'
import 'script!foundation-sites'

You can checkout my boilerplate project https://github.com/timaschew/r3-foundation-boilerplate

@tomByrer

I’ve noticed on the SCSS side switching from v5.x to v6.x there were compiling issues; the root file

Didn’t see any errors. It’s working fine with v6 in my boilerplate project.

This is how I currently do it using Foundation 6.2.1

var foundation = require(“babel!foundation-sites/js/foundation.core”); require(‘babel!what-input/what-input.js’); require(“babel!foundation-sites/js/foundation.util.mediaquery.js”); require(“babel!foundation-sites/js/foundation.util.nest.js”); require(“babel!foundation-sites/js/foundation.util.box.js”); require(“babel!foundation-sites/js/foundation.util.keyboard.js”); require(“babel!foundation-sites/js/foundation.util.motion.js”); require(“babel!foundation-sites/js/foundation.util.timerandimageloader.js”); require(“babel!foundation-sites/js/foundation.util.touch.js”); require(“babel!foundation-sites/js/foundation.util.triggers.js”); require(‘babel!foundation-sites/js/foundation.offcanvas.js’); require(‘babel!foundation-sites/js/foundation.dropdownMenu.js’); require(‘babel!foundation-sites/js/foundation.dropdown.js’); require(‘babel!foundation-sites/js/foundation.equalizer.js’);

// Related dependencies From package.json

“devDependencies”: { “babel”: “^6.5.2”, “babel-core”: “^6.6.0”, “babel-loader”: “^6.2.4”, “babel-preset-es2015”: “^6.6.0”, “gulp-babel”: “^6.1.2”, […]

I’m sure there’s other ways to do it, but this is what works for me after many wasted hours trying to get it to work.

@timaschew This thread is just a collection of different workarounds/hacks to circumvent the initial problem. IMO @Nerdinacan described it in the best way:

it’s a tragedy that I can’t use this library because your javascript is essentially un-importable as a CommonJS module

So my expectation is that the zurb people will come up with a fix or explain what should be fixed so that someone else can do it.

UPDATED: feb 29 2016

A simpler solution (no vendor.js, no externals, simply an alias). 1 - Use this in your webpack config:

// this will force the export of the jQuery 'foundation' function, which we'll use later
loaders: [
  {
    test: /(foundation\.core)/,
    loader: 'exports?foundation=jQuery.fn.foundation'
  },
],
// this makes sure that every module can resolve define(['foundation']) calls
resolve: {
  extensions: ['', '.js'],
  alias: {
    foundation: 'foundation-sites/js/foundation.core'
  }
},
// this makes sure 'jQuery' is available to any jQuery plugin you might want to load 
// (including Foundation files) regardless of how they are written
plugins: [
  new webpack.ProvidePlugin({
    $: 'jquery',
    jQuery: 'jquery',
    'window.jQuery': 'jquery'
  })
]

2 - In your index.js:

// thanks to the ProvidePlugin we don't need to
// > import $ from 'jquery';

// import core foundation files
import { foundation } from 'foundation-sites/js/foundation.core';
import 'foundation-sites/js/foundation.util.mediaQuery';

/* import here any additional module */

// we need to attach the function we exported above to the jQuery object in use in this file
$.fn.foundation = foundation;

// ready to go
$(document).ready(function() {
  $(document).foundation();
  …
});

@fchengpc this is what I’m doing, based on what’s been described in this thread (I’m on 6.1.x though, not sure if it makes a difference):

import 'script!jquery'
import 'script!foundation-sites'

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

I’m not doing anything specific in the webpack file.

If I’m understanding this properly, there are workarounds, but moving Foundation to ES2016 true dependency management is the real fix. This is a pretty large project, but I think important. We’re about to release 6.3… I’d like to target this for version 6.4.

@anselmdk Thanks you. finally got it working now. You are right nothing special in webpack config.(i took most of stuff out). Here is what i have in entry file.

require('script!jquery');
foundation = require('foundation-sites/dist/foundation.min.js');

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

not sure why i need to require jquery again. since i do use (webpack.ProvidePlugin) in webpack config. But if i took it out it throw jQuery undefined error. (assume b/c foundation use $, JQuery and window.jQuery

@priedthirdeye I actually end up use both. first ProvidePlugin in webpack config file then define foundation variable in entry file. Hope this help out someone the future.

I know this is old but its high on “the googles”. The solutions above worked for me with some modifications.

I installed script loader and removed weback.provideplugin, then I used the inline script loader with the minified files since it would be more complicated to minify them later in line.

https://github.com/webpack-contrib/script-loader

webpack ^3.4, foundation-sites ^6.4, script-loader ^0.7

import 'script-loader!jquery/dist/jquery.min.js';
import 'script-loader!foundation-sites/dist/js/foundation.min.js';

$(document).ready(() => {
  $(document).foundation();
});

@priedthirdeye that is the best solution to be used with

new webpack.ProvidePlugin({
    $: "jquery",
    jQuery: "jquery",
    "window.jQuery": "jquery"
})

I’ve used some of the above workarounds in the past but was hoping to get to something clearner with Foundation 6.4.4, but unfortunately it throws this issue when I try to build it in a setup using create-react-app:

Failed to minify the code from this file:

        ./node_modules/foundation-sites/js/foundation.util.core.js:24
Read more here: http://bit.ly/2tRViJ9

I do see this is a known issue (related discussion: #10987), just wanted to note here for future searchers.

As a reference, checkout vue-foundation. It is for Vuejs also however you can just reference the foundation portions of the config.

Maybe open a new issue for that and add it to the milestone? It would allow people to track the progress specific to the transition easier, under a title that reflects the intent.

In webpack.config

  sassLoader: {
    includePaths: [
        path.resolve(srcPath, 'node_modules/foundation-sites/scss/'),
        path.resolve(srcPath, 'node_modules/motion-ui/src/'),
        path.resolve(srcPath, "node_modules"),
    ]
  },

  resolve: {
    //tells webpack where to look for modules
    modulesDirectories: ['node_modules',],// 'bower_components'],
    extensions: ['', '.js', '.jsx'],
    alias: {
        foundation: 'foundation-sites/js/foundation.core'
    }
  },

in main.scss

// @import "../../node_modules/foundation-sites/scss/foundation";
// Webpack allows you to use ~ to import from module directories:

@import "~foundation-sites/scss/foundation";
@import "gh_settings";

$fa-font-path: "~font-awesome/fonts";
@import "~font-awesome/scss/font-awesome";
// where the $fa-font-path variable is seen in font-awesome/scss/_variables.scss
// $fa-font-path: "../fonts" !default;
// As is described overhere: http://fontawesome.io/get-started/

// You need to @include the pieces you want to use. For example, to include everything:
// http://foundation.zurb.com/sites/docs/sass.html#adjusting-css-output
// @include foundation-everything(true);

@include foundation-global-styles;
@include foundation-grid;
@include foundation-flex-grid;
@include foundation-typography;
@include foundation-button;
@include foundation-forms;
// @include foundation-range-input;
@include foundation-accordion;
@include foundation-accordion-menu;
@include foundation-badge;
@include foundation-breadcrumbs;
@include foundation-button-group;
@include foundation-callout;
@include foundation-close-button;
@include foundation-menu;
@include foundation-menu-icon;
@include foundation-drilldown-menu;
@include foundation-dropdown;
@include foundation-dropdown-menu;
@include foundation-flex-video;
@include foundation-label;
@include foundation-media-object;
@include foundation-off-canvas;
@include foundation-orbit;
@include foundation-pagination;
@include foundation-progress-bar;
// @include foundation-progress-element;
// @include foundation-meter-element;
@include foundation-slider;
@include foundation-sticky;
@include foundation-reveal;
@include foundation-switch;
@include foundation-table;
@include foundation-tabs;
@include foundation-thumbnail;
@include foundation-title-bar;
@include foundation-tooltip;
@include foundation-top-bar;
@include foundation-visibility-classes;
@include foundation-float-classes;
// @include foundation-flex-classes;


@import "motion-ui";
@include motion-ui-transitions;
@include motion-ui-animations;

React index.js begin

//load jquery and foundation in the window scope
import 'script!jquery'
import 'script!what-input'
import 'script!foundation-sites'

import './styles/index.css'

$(document).foundation();

I’s work for us

Thanks for all the support here! Could we get this documented somewhere in the repo. Then I’d anyone comes and submits an issue or question on our (webpack) repo, we can link them to a solution.

@timaschew I disagree, it’s a pity that in 2016 such a big project still hasn’t adopted UMD. Every module should require the core and the core should require jquery. I’m not saying it’s easy, it’s very possible that adopting UMD would require a big rewrite and for this reason they haven’t done it yet. But it has to be done or someone else will come forward (see lodash - which I can import function by function in my project - vs the monolithic underscore)