This is to track the move to ES6 modules.
define() statement anywhere, good job, you're done. Mention it here so it can be taken off the list.define() statement, continue.define() statement so that this kind of line:javascript
define(['datetime', 'imageLoader', 'scripts/imagehelper', 'css!./card', 'paper-icon-button-light', 'programStyles'], function (datetime, imageLoader, imageHelper) {
javascript
import datetime from "datetime";
import imageLoader from 'imageLoader';
import imageHelper from 'scripts/imagehelper';
import 'css!./card';
import 'paper-icon-button-light';
import 'programStyles';
return statement and, if present, add export in front of the functions referenced by the return statement and delete it.javascript
export function getCardsHtml(items, options) {
test array of the overrides section in the babel key.import and export are done, save the file, test the client using yarn serve (If possible, try to get your converted file to load, which may mean performing some specific flow in the web client).Edit: Of course, some modules may require more work. This is the basics and should be all you need to do for a fair number of modules, but a few might require to be refactored into classes, for example.
Edit 2: In order to convert the instances of require() inside of files (generally meant for conditional loading of modules), the conversion should be done as follows:
Current
require(['slideshow'], function (slideshow) {
ES6
import('slideshow').then(({default: Slideshow}) => {
Just checked, these files do not have any define's in them.
But wouldn't they need to have the functions exported?
Thanks for checking :)
- ./src/components/polyfills/objectassign.js
- ./src/components/polyfills/focusPreventScroll.js
These will be moved out of tree eventually, if possible.
./src/components/serviceworker/notifications.js
This is a service worker, it can stay as-is for now.
./src/libraries/query-string/index.js
This was moved out of tree since this list was made.
./src/scripts/apploader.js
./src/standalone.js
./src/serviceworker.js
Nothing to migrate here at the moment.
Thanks, I'll remove them from the list.
./src/components/backdropscreensaver/plugin.js
./src/components/htmlvideoplayer/plugin.js
Since these get loaded up by the PluginManager, I wasn't able to convert them, probably my lack of knowledge of AMD but I tried making it a class but when PluginManager is newing up the plugin it fails.
./src/components/backdropscreensaver/plugin.js
./src/components/htmlvideoplayer/plugin.js
Since these get loaded up by the PluginManager, I wasn't able to convert them, probably my lack of knowledge of AMD but I tried making it a class but when PluginManager is newing up the plugin it fails.
I am basically seeing this for any module that has a return function(someParams). Which gets used like
require(['component'], function(component) {
new component(params)
}
After converting to a class I get 'component' is not a constructor
@MrTimscampi What's the correct approach for modules that are defined but their functions are not used?
For example:
define(["dialogHelper", "datetime", "globalize", "emby-select", "paper-icon-button-light", "formDialogStyle"], function (dialogHelper, datetime, globalize) {
"emby-select", "paper-icon-button-light", "formDialogStyle" are not used as functions. That means that we need to follow the same procedure when importing or it has extra steps?
I suppose the only difference is that we don't need to specify those modules in package.json, as they're not JS but CSS files
@ferferga These become this:
import 'paper-icon-button-light';
The only things you need to add to package.json are the packages converted to ES6, not the imports of those packages :)
@MrTimscampi After converting #810 to ES6 modules
I get 'Uncaught (in promise) TypeError: tabbedPage is not a constructor what shall i do?
when i add default like this it work
var tabbedPageInstance = new tabbedPage.default(view, {
handleFocus: true
});
and a big issue for me when i convert home.js it not load at all?
@grafixeyehero Seems like you don't have a default export in the file (export default instead of only export)
Do note that usually, for compatibility, we do it like this:
import stuff from 'somewhere';
/* eslint-disable indent */
function regularPrivateFunction () {
...
}
export yourExportedFunction () {
...
}
/* eslint-enable indent */
export default {
yourExportedFunction: yourExportedFunction
}
For home.js, it's a bit more complicated. Since you're using require() to lazy-load a module. I guess we can replace it with the new import() (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import under Dynamic Imports).
As for the conversion to a class, I'd need to see the code produced to help you debug it. Feel free to commit and push changes if you can :)
picking up:
File Done
PR https://github.com/jellyfin/jellyfin-web/pull/1174
Files:
./src/components/backdropscreensaver/plugin.js
./src/components/htmlvideoplayer/plugin.js
Since these get loaded up by the PluginManager, I wasn't able to convert them, probably my lack of knowledge of AMD but I tried making it a class but when PluginManager is newing up the plugin it fails.I am basically seeing this for any module that has a
return function(someParams). Which gets used likerequire(['component'], function(component) { new component(params) }After converting to a class I get
'component' is not a constructor
i had the same problem - after hours of research and trying it looks like we need to change the import style or the calling style
new ClassA(param) -> new ClassA.ClassA(param)
Better example and explanation
hope it will help you :)
This should be fixed by #1091
At least for stuff using the plugin manager I think (it then checks for default and calls new plugin.default() on demand)
The logs page controller has been merged to develop as the first controller with ES6 support included, so it can be used as a base for the other controllers.
Quick question on src/controllers/dashboard/dashboard.js.
I have got: import datefns from 'date-fns'; at the start of the file. However, on line 462: datefns.formatDistanceToNow(Date.parse(session.LastActivityDate), dfnshelper.localeWithSuffix)
when running it produces the following error in the console:
Uncaught TypeError: Cannot read property 'formatDistanceToNow' of undefined.
But when I put the return statement inside an import there is no error:
import('date-fns').then(({default: datefns}) => {
return {
html: globalize.translate('LastSeen', datefns.formatDistanceToNow(Date.parse(session.LastActivityDate), dfnshelper.localeWithSuffix)),
image: imgUrl
};
})
I just wondered what the best way to approach it is? Or what am I doing wrong?
You likely need to do something like datefns.default.formatDistanceToNow(), during the ES6 migration.
It is counter-intuitive, but you are currently still importing AMD modules, not ES6 modules. Only the source file is written a different way, but when building it all gets rewritten as AMD modules.
It will be a lot simpler once we're done.
Usually, you can output the object you're having issues with to the console or put a breakpoint somewhere around it to see what's inside, then adapt your code to match.
Thanks for that, I changed the import statement to
import * as datefns from 'date-fns';
Which made it work. Before if you outped the object datefns, it was undefined. Now it has all the functions in the module.
@MrTimscampi Correct me if I'm wrong but I believe the following are missing from the list above:
src/controllers/dashboard/devices/device.js[ ] src/controllers/dashboard/devices/devices.js
[ ] src/controllers/dashboard/dlna/profile.js
src/controllers/dashboard/dlna/profiles.js[ ] src/controllers/dashboard/dlna/settings.js
[ ] src/controllers/dashboard/plugins/repositories.js
[ ] src/controllers/dashboard/users/useredit.js
src/controllers/dashboard/users/userlibraryaccess.jssrc/controllers/dashboard/users/usernew.jssrc/controllers/dashboard/users/userparentalcontrol.jssrc/controllers/dashboard/users/userpasswordpage.jssrc/controllers/dashboard/users/userprofilespage.jsI think some of the files also don't exist anymore, I guess it's an old list
I am currently on the latest es6 branch, so it might be an old list.
Some of the files I have listed are there just not listed in the correct directory e.g
In the original list: ./src/controllers/useredit.js
whereas its actual location: ./src/controllers/dashboard/users/useredit.js
The list is indeed old (It was generated when opening the issue)
Multiple files have been moved, removed or renamed since.
The file list has been updated to the current paths as of July 11th 2020.
Edit: The progress has also been updated.
Closing - #1994 🥂🥳🎉