Closed rafibomb closed 6 years ago
It's somewhat ugly that you have to init the plugins, there is no way to do this on import somehow?
Would be awesome if you could do like with lodash-es
:
import {
Foundation,
Abide,
} from 'foundation-sites/js/entries/foundation-es'
@oxyc Great question, I've been stewing on this, so maybe you could help me think through it...
One item I'm thinking is to build a couple global entry points that you could import from... the one I'm confident we want is an entry that includes and initialized everything and returns the Foundation (Basically what is in foundation-sites/js/entries/foundation.js
except returning the Foundation object). The second would be something similar to what you're describing, one that essentially just creates a "bundled export".
The one thing that I'm a little concerned about with the latter is that if you want to tap into the auto-parsing from $(document).foundation()
you'll still need to set up the global Foundation registry with the plugins via Foundation.plugin(Abide)
, and that's not super obvious and a lot of boilerplate if you're pulling in a lot of plugins.
Do you have any other ideas on good ways to attack this?
Another way we could take this is create an entrypoint that dynamically requires the modules you want. So you'd do something like:
let Foundation = require(`foundation`);
Foundation.initializePlugins(Abide, Reveal, ...)
The core issue/question here is that we want including the modules themselves to be side effect free, but we also want to make it super simple to get started with the currently expected side effects (such as setting up the jquery helper with the set of plugins you've chosen)
The one thing that I'm a little concerned about with the latter is that if you want to tap into the auto-parsing from $(document).foundation() you'll still need to set up the global Foundation registry with the plugins via Foundation.plugin(Abide), and that's not super obvious and a lot of boilerplate if you're pulling in a lot of plugins.
Yes this is not ideal. Would be great if you could have a single import/init list where you just comment out the modules you dont need. If you need to maintain that list in two places you will for sure forget something and end up having to manually count the modules you have active.
import {
Foundation,
// Abide,
Accordion,
// AccordionMenu,
Drilldown,
...
} from 'foundation-sites/js/entries/foundation-es'
Not sure how to fix it properly, I was trying to make a POC but my webpack setup kept including all plugins in the build.
@oxyc I think we could get it to work if we did the 2nd approach where we imported a global Foundation object and then called our imports within the actual function of the initialization... should let webpack statically analyze our imports and only pull in the ones we want. I'll take a stab at this later today or tomorrow
Hmm... taking a pass at this @oxyc it looks like I was wrong. Imports are hoisted so we can't do the import inside the function.
I also did a pass on wrapping up all of the plugins and re-exporting them to see how webpack treats it... it looks like webpack is properly identifying which ones are not needed (labeling them in the generated JS as unused harmony reexport, but there's some configuration needed to make it actually drop them from the outputted JS.
I'll dig into this further and see what I can figure out. We still end up with the initialization problem if you want to initialize... and part of the premise of this type of modularization is don't necessarily have a global object to put things on to.
That said, since everything is depending on jQuery, and I suspect most folks will use a single global jquery instance, we do in fact have a de facto global object for most environments... we could hang things off of that object and use that as a way to bootstrap implicitly when you run $.fn.foundation()
...
Curious what folks like @gakimball @DaSchTour @Owlbertz think of that option
it looks like webpack is properly identifying which ones are not needed (labeling them in the generated JS as unused harmony reexport, but there's some configuration needed to make it actually drop them from the outputted JS.
I believe they're dropped in a production build. https://webpack.js.org/guides/tree-shaking/
I'm slightly confused by which files should be imported - however, this may just be because I'm not super familiar with Webpack yet.
There are a lot of similar JS files.
foundation-sites/dist/js/plugins - I'm assuming these are the non-webpack JS files. foundation-sites/js/entries/plugins - These look like the files to import into Webpack. foundation-sites/js/ - Not sure what these are. Can someone clarify?
@JeremyEnglert for an example you can check the zurb/foundation-zurb-template
repo:
I'm also having trouble figuring out how to import -- the "Import it all" example above is straightforward, but when it comes to importing and initialising a single plugin I'm at a loss.
I'm thinking something like:
import $ from 'jquery';
window.$ = $;
import { Foundation } from 'js/entries/plugins/foundation.core';
import { ResponsiveMenu, ResponsiveToggle, OffCanvas } from 'js/entries/foundation-plugins';
Foundation.plugin(ResponsiveMenu, 'ResponsiveMenu');
Foundation.plugin(ResponsiveToggle, 'ResponsiveToggle');
Foundation.plugin(OffCanvas, 'OffCanvas');
$(document).foundation();
Where am I going wrong? This is throwing the error plugins/foundation.core
doesn't export Foundation
, which I can see is the case by looking at that file -- however I also see that each plugin file e.g. "foundation.offcanvas.js" does actually include Foundation
from plugins/foundation.core
.
I'm using roll-up to bundle, in case that's pertinent.
Basically I'm just trying to work out the most minimal example code to import (and initialise) a single module.
@rossb Definitely confusing there, using entries for 2 different things at the moment, which is confusing and my bad. Other than the plugins file (which is kind of an experiment at a unified entry point, and probably should include Foundation core) the other files in entries
are being used by our internal process to build compiled files.
In your case, if you change import { Foundation } from 'js/entries/plugins/foundation.core';
to import { Foundation } from 'js/plugins/foundation.core';
it should work.
The compiled files in /dist/js/plugins seem to conflict with other jQuery.
In 6.3.x, almost all JS functions started with function($)
- which caused them to not to conflict with other jQuery plugins. This doesn't appear to be the case in 6.4.
Hi guys, so the following plugins don't seem to work at all with the ES6 imports and using through webpack:
An example would be the below, setting them as directives in Vue.js. Only the toggler works, the other two set some aria attributes correctly but just don't seem to function, i.e. nothing happens.
The syntax is all correct for Vue and I'm using some of the other plugins (tabs, reveal, accordion) as components in a similar way which function well. I have still to test some of the other plugins like equalizer etc.
import { Foundation } from '../../node_modules/foundation-sites/js/foundation.core';
import { Toggler } from '../../node_modules/foundation-sites/js/foundation.toggler';
import { Tooltip } from '../../node_modules/foundation-sites/js/foundation.tooltip';
import { Interchange } from '../../node_modules/foundation-sites/js/foundation.interchange';
Foundation.plugin(Toggler, 'Toggler');
Foundation.plugin(Tooltip, 'Tooltip');
Foundation.plugin(Interchange, 'Interchange');
const FoundationDirectives = {
install(Vue) {
Vue.directive('f-toggler', {
inserted(el) {
/* eslint-disable no-param-reassign */
el.fToggler = new Foundation.Toggler($(el));
},
unbind(el) {
el.fToggler.destroy();
},
});
Vue.directive('f-interchange', {
inserted(el) {
/* eslint-disable no-param-reassign */
el.fInterchange = new Foundation.Interchange($(el));
},
unbind(el) {
el.fInterchange.destroy();
},
});
Vue.directive('f-tooltip', {
inserted(el) {
/* eslint-disable no-param-reassign */
el.fTooltip = new Foundation.Tooltip($(el));
},
unbind(el) {
el.fTooltip.destroy();
},
});
},
};
export default FoundationDirectives;
What is the latest on the progress with this?
Many thanks!
@aaronjpitts thanks for the bug report... this is helpful, and the common thread through these plugins is they all use the MediaQuery utility which may not be initializing properly in the new world... I'll look into a fix, but to make sure can you try importing MediaQuery
and running Foundation.MediaQuery._init();
?
@kball I just tried, imported MediaQuery and tried running Foundation.MediaQuery._init();
, it gives undefined
. So hopefully this will help you track down the problem :) I hope this helps with the older github issues I logged and that you just replied to. It seems they may be related to MediaQuery, yes. I'm very excited to get all this working and I'm currently working on a Vue.js integration that I'd like to release as a starter template for Vue.js apps.
aaronjpitts Would it be possible for you to pull down the media-query-init-problem
branch and see if it resolves your issue?
@kball I haven't tested all the plugins yet, but from what I can see, yes they all seem to function fine now with this media-query-init-problem
branch :) thank you very much!
@kball also a question, for a framework like Vue.js, to integrate Foundation, do you think it's best to set all Foundation javascript plugins as global directives in Vue.js or to use them as components? I am using components for things such as Reveal because I think modal windows will often need to be opened programmatically. Just wondering your thoughts.
import $ from 'jquery';
This is hideous, either use ES6 or ES5 or jquery. By the way why is jquery a dependency in 2017? Are you supporting IE8?
@dgt41 100% agree we shouldn't need to have jquery as a dependency moving forward, that is the plan for F7, however F6 is deeply entangled with jQuery (partially due to support back to IE9 and old Android).
The change to use true ESmodern dependency management is the first step to stripping out the jQuery dependency by giving us a framework to separate out that entanglement and create a clean dom manipulation API.
You'll see this go much further in the 6.5 release, and for F7 (targeted Nov 7 of this year) we'll have fully moved to a pluggable architecture that both has a pure ES backend but also makes native implementations in frameworks like Angular, React, Ember, and Vue.
@kball are you planning to use web components or custom elements for the components that require javascript? I've played a bit with that concept and seems the right way to implement such components. you can check it out here
@dgt41 plans are still getting finalized... we have some experiments underway... With the custom elements, what's the browser support on the polyfill look like?
@kball Browser support is very good and depending on the polyfiill used for the unsupported browsers can be either > IE11 or > IE9. The 2 polyffils are: from Google https://github.com/webcomponents/custom-elements or https://github.com/WebReflection/document-register-element (used by Google in AMP)
The only thing with custom elements is that they're natively ES6 and if you need to target <IE11 then you need to transpile the code to ES5, but since you're already utilising webpack that will be an easy task.
Anyways eagerly awaiting to see your implementation, the framework support is a game changer IMHO
Hi all,
I got this working for me. Simple example to cherry pick Reveal
only.
One issue I had was having to add the Foundation.MediaQuery = MediaQuery
declaration. the addToJquery()
method calls for it in the file but it is not imported.
I'm def still learning webpack, so feel free to make any corrections/suggestions.
// foundation.js
import { Foundation } from 'foundation-sites/js/foundation.core';
import { Reveal } from 'foundation-sites/js/foundation.reveal';
import { MediaQuery } from 'foundation-sites/js/foundation.util.mediaQuery';
Foundation.plugin(Reveal, 'Reveal');
// MediaQuery is oddly needed for the addToJquery Method
Foundation.MediaQuery = MediaQuery;
Foundation.addToJquery(jQuery);
jQuery(document).foundation();
// index.js
import './foundation'
@jacobarriola - Thanks for posting your solution! The MediaQuery reference was a bug fixed here: https://github.com/zurb/foundation-sites/pull/10292
Ahh! Sweet @kball - I'll keep an eye out to see when that fix gets merged in.
Thanks! 👍
@jacobarriola it is! It was included in the 6.4.1 patch release we pushed out about an hour ago
Really nice !! I was looking for this kind of post: load only some plugins, i did this :
/**
* Foundation 6.4 Framework
*/
// ### Core
import { Foundation } from 'foundation-sites/js/foundation.core';
// ### Plugins
import { MediaQuery } from 'foundation-sites/js/foundation.util.mediaQuery';
Foundation.plugin(MediaQuery, 'MediaQuery');
// ### Init
Foundation.addToJquery(jQuery);
$(document).foundation();
It's perfectly working, thanks @jacobarriola and @kball 😘 😀
Hi!
The files in js/entries/plugins seem to provide an easy way to import foundation as well as plugins without having to initialize them. The only thing which is missing is an export of the main Foundation object at the end of js/entries/plugins/foundation.core.js. Adding the missing "export {Foundation}" then allows you to do this:
import 'foundation-sites/js/entries/plugins/foundation.core';
import 'foundation-sites/js/entries/plugins/foundation.util.triggers';
import 'foundation-sites/js/entries/plugins/foundation.util.mediaQuery';
import 'foundation-sites/js/entries/plugins/foundation.util.keyboard';
import 'foundation-sites/js/entries/plugins/foundation.interchange';
import 'foundation-sites/js/entries/plugins/foundation.offcanvas';
import 'foundation-sites/js/entries/plugins/foundation.drilldown';
...or importing any other needed plugin.
Do we need more feedback or is the current discussion happening in another issue?
Good news! Foundation 6.4 has shifted to a new ES2016 module-based architecture powered by webpack. This means speed! Super fast JS compilation on top of being more pluggable into more environments! If you are using webpack or another module bundler, you can now import Foundation modules quick and easy resolving a major pain point of the previous architecture.
It would be awesome if you could update your existing project or start a new one with the new webpack module integration and comment below with suggestions or feedback on how it went for your use case.
You can find the ZURB Template branch with the module integration here: https://github.com/zurb/foundation-zurb-template/tree/v6.4
For previous discussion history see:
9965
9438