diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000000..ceeb850bea --- /dev/null +++ b/.babelrc @@ -0,0 +1,4 @@ +{ + "presets": ["react", "es2015", "es2016"], + "plugins": ["transform-class-properties", "transform-object-rest-spread", "transform-async-to-generator", "transform-runtime"] +} diff --git a/.gitignore b/.gitignore index ac9c2c300d..200fa33dd1 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ /vector/config.json /vector/olm.js .DS_Store +npm-debug.log diff --git a/karma.conf.js b/karma.conf.js index f05186af95..2474216916 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -92,13 +92,7 @@ module.exports = function (config) { test: /\.js$/, loader: "babel", include: [path.resolve('./src'), path.resolve('./test'), - ], - query: { - // we're using babel 5, for consistency with - // the release build, which doesn't use the - // presets. - // presets: ['react', 'es2015'], - }, + ] }, ], noParse: [ diff --git a/package.json b/package.json index 68440ccf34..d666aa3596 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "build:bundle": "NODE_ENV=production webpack -p lib/vector/index.js vector/bundle.js", "build:bundle:dev": "webpack --optimize-occurence-order lib/vector/index.js vector/bundle.js", "build:staticfiles": "cpx -v node_modules/olm/olm.js vector/", - "build": "npm run build:staticfiles && npm run build:emojione && npm run build:css && npm run build:compile && npm run build:bundle", + "build": "node scripts/babelcheck.js && npm run build:staticfiles && npm run build:emojione && npm run build:css && npm run build:compile && npm run build:bundle", "build:dev": "npm run build:staticfiles && npm run build:emojione && npm run build:css && npm run build:compile && npm run build:bundle:dev", "package": "scripts/package.sh", "start:emojione": "cpx \"node_modules/emojione/assets/svg/*\" vector/emojione/svg/ -w", @@ -28,7 +28,7 @@ "start:skins:css": "catw \"src/skins/vector/css/**/*.css\" -o vector/components.css", "start:staticfiles": "cpx -Lwv node_modules/olm/olm.js vector/", "//cache": "Note the -c 1 below due to https://code.google.com/p/chromium/issues/detail?id=508270", - "start": "parallelshell \"npm run start:staticfiles\" \"npm run start:emojione\" \"npm run start:js\" \"npm run start:skins:css\" \"http-server -c 1 vector\"", + "start": "node scripts/babelcheck.js && parallelshell \"npm run start:staticfiles\" \"npm run start:emojione\" \"npm run start:js\" \"npm run start:skins:css\" \"http-server -c 1 vector\"", "start:prod": "parallelshell \"npm run start:staticfiles\" \"npm run start:emojione\" \"npm run start:js:prod\" \"npm run start:skins:css\" \"http-server -c 1 vector\"", "clean": "rimraf lib vector/olm.js vector/bundle.css vector/bundle.js vector/bundle.js.map vector/webpack.css* vector/emojione", "prepublish": "npm run build:css && npm run build:compile", @@ -37,6 +37,7 @@ }, "dependencies": { "babel-polyfill": "^6.5.0", + "babel-runtime": "^6.11.6", "browser-request": "^0.3.3", "classnames": "^2.1.2", "draft-js": "^0.8.1", @@ -61,9 +62,19 @@ "url": "^0.11.0" }, "devDependencies": { - "babel": "^5.8.23", - "babel-core": "^5.8.25", - "babel-loader": "^5.3.2", + "babel-cli": "^6.5.2", + "babel-core": "^6.14.0", + "babel-eslint": "^6.1.0", + "babel-loader": "^6.2.5", + "babel-plugin-transform-async-to-generator": "^6.16.0", + "babel-plugin-transform-class-properties": "^6.16.0", + "babel-plugin-transform-object-rest-spread": "^6.16.0", + "babel-plugin-transform-runtime": "^6.15.0", + "babel-preset-es2015": "^6.16.0", + "babel-preset-es2016": "^6.16.0", + "babel-preset-es2017": "^6.16.0", + "babel-preset-react": "^6.16.0", + "babel-preset-stage-2": "^6.17.0", "catw": "^1.0.1", "cpx": "^1.3.2", "css-raw-loader": "^0.1.1", diff --git a/scripts/babelcheck.js b/scripts/babelcheck.js new file mode 100644 index 0000000000..89f5cac554 --- /dev/null +++ b/scripts/babelcheck.js @@ -0,0 +1,26 @@ +#!/usr/bin/env node + +var exec = require('child_process').exec; + +// Makes sure the babel executable in the path is babel 6 (or greater), not +// babel 5, which it is if you upgrade from an older version of react-sdk and +// run 'npm install' since the package has changed to babel-cli, so 'babel' +// remains installed and the executable in node_modules/.bin remains as babel +// 5. + +// This script is duplicated from matrix-react-sdk because it can't reliably +// be pulled in from react-sdk while npm install is failing, as it will do +// if the environment is in the erroneous state this script checks for. + +exec("babel -V", function (error, stdout, stderr) { + if ((error && error.code) || parseInt(stdout.substr(0,1), 10) < 6) { + console.log("\033[31m\033[1m"+ + '*****************************************\n'+ + '* vector-web has moved to babel 6 *\n'+ + '* Please "rm -rf node_modules && npm i" *\n'+ + '* then restore links as appropriate *\n'+ + '*****************************************\n'+ + "\033[91m"); + process.exit(1); + } +}); diff --git a/src/component-index.js b/src/component-index.js index ec597609a7..3141087ce6 100644 --- a/src/component-index.js +++ b/src/component-index.js @@ -26,32 +26,61 @@ limitations under the License. module.exports.components = require('matrix-react-sdk/lib/component-index').components; -module.exports.components['structures.BottomLeftMenu'] = require('./components/structures/BottomLeftMenu'); -module.exports.components['structures.CompatibilityPage'] = require('./components/structures/CompatibilityPage'); -module.exports.components['structures.LeftPanel'] = require('./components/structures/LeftPanel'); -module.exports.components['structures.RightPanel'] = require('./components/structures/RightPanel'); -module.exports.components['structures.RoomDirectory'] = require('./components/structures/RoomDirectory'); -module.exports.components['structures.RoomSubList'] = require('./components/structures/RoomSubList'); -module.exports.components['structures.SearchBox'] = require('./components/structures/SearchBox'); -module.exports.components['structures.ViewSource'] = require('./components/structures/ViewSource'); -module.exports.components['views.context_menus.MessageContextMenu'] = require('./components/views/context_menus/MessageContextMenu'); -module.exports.components['views.context_menus.NotificationStateContextMenu'] = require('./components/views/context_menus/NotificationStateContextMenu'); -module.exports.components['views.context_menus.RoomTagContextMenu'] = require('./components/views/context_menus/RoomTagContextMenu'); -module.exports.components['views.dialogs.ChangelogDialog'] = require('./components/views/dialogs/ChangelogDialog'); -module.exports.components['views.directory.NetworkDropdown'] = require('./components/views/directory/NetworkDropdown'); -module.exports.components['views.elements.ImageView'] = require('./components/views/elements/ImageView'); -module.exports.components['views.elements.Spinner'] = require('./components/views/elements/Spinner'); -module.exports.components['views.globals.GuestWarningBar'] = require('./components/views/globals/GuestWarningBar'); -module.exports.components['views.globals.MatrixToolbar'] = require('./components/views/globals/MatrixToolbar'); -module.exports.components['views.globals.NewVersionBar'] = require('./components/views/globals/NewVersionBar'); -module.exports.components['views.login.VectorCustomServerDialog'] = require('./components/views/login/VectorCustomServerDialog'); -module.exports.components['views.login.VectorLoginFooter'] = require('./components/views/login/VectorLoginFooter'); -module.exports.components['views.login.VectorLoginHeader'] = require('./components/views/login/VectorLoginHeader'); -module.exports.components['views.messages.DateSeparator'] = require('./components/views/messages/DateSeparator'); -module.exports.components['views.messages.MessageTimestamp'] = require('./components/views/messages/MessageTimestamp'); -module.exports.components['views.rooms.DNDRoomTile'] = require('./components/views/rooms/DNDRoomTile'); -module.exports.components['views.rooms.RoomDropTarget'] = require('./components/views/rooms/RoomDropTarget'); -module.exports.components['views.rooms.RoomTooltip'] = require('./components/views/rooms/RoomTooltip'); -module.exports.components['views.rooms.SearchBar'] = require('./components/views/rooms/SearchBar'); -module.exports.components['views.settings.IntegrationsManager'] = require('./components/views/settings/IntegrationsManager'); -module.exports.components['views.settings.Notifications'] = require('./components/views/settings/Notifications'); +import structures$BottomLeftMenu from './components/structures/BottomLeftMenu'; +module.exports.components['structures.BottomLeftMenu'] = structures$BottomLeftMenu; +import structures$CompatibilityPage from './components/structures/CompatibilityPage'; +module.exports.components['structures.CompatibilityPage'] = structures$CompatibilityPage; +import structures$LeftPanel from './components/structures/LeftPanel'; +module.exports.components['structures.LeftPanel'] = structures$LeftPanel; +import structures$RightPanel from './components/structures/RightPanel'; +module.exports.components['structures.RightPanel'] = structures$RightPanel; +import structures$RoomDirectory from './components/structures/RoomDirectory'; +module.exports.components['structures.RoomDirectory'] = structures$RoomDirectory; +import structures$RoomSubList from './components/structures/RoomSubList'; +module.exports.components['structures.RoomSubList'] = structures$RoomSubList; +import structures$SearchBox from './components/structures/SearchBox'; +module.exports.components['structures.SearchBox'] = structures$SearchBox; +import structures$ViewSource from './components/structures/ViewSource'; +module.exports.components['structures.ViewSource'] = structures$ViewSource; +import views$context_menus$MessageContextMenu from './components/views/context_menus/MessageContextMenu'; +module.exports.components['views.context_menus.MessageContextMenu'] = views$context_menus$MessageContextMenu; +import views$context_menus$NotificationStateContextMenu from './components/views/context_menus/NotificationStateContextMenu'; +module.exports.components['views.context_menus.NotificationStateContextMenu'] = views$context_menus$NotificationStateContextMenu; +import views$context_menus$RoomTagContextMenu from './components/views/context_menus/RoomTagContextMenu'; +module.exports.components['views.context_menus.RoomTagContextMenu'] = views$context_menus$RoomTagContextMenu; +import views$dialogs$ChangelogDialog from './components/views/dialogs/ChangelogDialog'; +module.exports.components['views.dialogs.ChangelogDialog'] = views$dialogs$ChangelogDialog; +import views$directory$NetworkDropdown from './components/views/directory/NetworkDropdown'; +module.exports.components['views.directory.NetworkDropdown'] = views$directory$NetworkDropdown; +import views$elements$ImageView from './components/views/elements/ImageView'; +module.exports.components['views.elements.ImageView'] = views$elements$ImageView; +import views$elements$Spinner from './components/views/elements/Spinner'; +module.exports.components['views.elements.Spinner'] = views$elements$Spinner; +import views$globals$GuestWarningBar from './components/views/globals/GuestWarningBar'; +module.exports.components['views.globals.GuestWarningBar'] = views$globals$GuestWarningBar; +import views$globals$MatrixToolbar from './components/views/globals/MatrixToolbar'; +module.exports.components['views.globals.MatrixToolbar'] = views$globals$MatrixToolbar; +import views$globals$NewVersionBar from './components/views/globals/NewVersionBar'; +module.exports.components['views.globals.NewVersionBar'] = views$globals$NewVersionBar; +import views$login$VectorCustomServerDialog from './components/views/login/VectorCustomServerDialog'; +module.exports.components['views.login.VectorCustomServerDialog'] = views$login$VectorCustomServerDialog; +import views$login$VectorLoginFooter from './components/views/login/VectorLoginFooter'; +module.exports.components['views.login.VectorLoginFooter'] = views$login$VectorLoginFooter; +import views$login$VectorLoginHeader from './components/views/login/VectorLoginHeader'; +module.exports.components['views.login.VectorLoginHeader'] = views$login$VectorLoginHeader; +import views$messages$DateSeparator from './components/views/messages/DateSeparator'; +module.exports.components['views.messages.DateSeparator'] = views$messages$DateSeparator; +import views$messages$MessageTimestamp from './components/views/messages/MessageTimestamp'; +module.exports.components['views.messages.MessageTimestamp'] = views$messages$MessageTimestamp; +import views$rooms$DNDRoomTile from './components/views/rooms/DNDRoomTile'; +module.exports.components['views.rooms.DNDRoomTile'] = views$rooms$DNDRoomTile; +import views$rooms$RoomDropTarget from './components/views/rooms/RoomDropTarget'; +module.exports.components['views.rooms.RoomDropTarget'] = views$rooms$RoomDropTarget; +import views$rooms$RoomTooltip from './components/views/rooms/RoomTooltip'; +module.exports.components['views.rooms.RoomTooltip'] = views$rooms$RoomTooltip; +import views$rooms$SearchBar from './components/views/rooms/SearchBar'; +module.exports.components['views.rooms.SearchBar'] = views$rooms$SearchBar; +import views$settings$IntegrationsManager from './components/views/settings/IntegrationsManager'; +module.exports.components['views.settings.IntegrationsManager'] = views$settings$IntegrationsManager; +import views$settings$Notifications from './components/views/settings/Notifications'; +module.exports.components['views.settings.Notifications'] = views$settings$Notifications; diff --git a/src/vector/index.js b/src/vector/index.js index acad100ba0..b33693f6b4 100644 --- a/src/vector/index.js +++ b/src/vector/index.js @@ -18,6 +18,14 @@ limitations under the License. // for ES6 stuff like startsWith() that Safari doesn't handle // and babel doesn't do by default +// Note we use this, as well as the babel transform-runtime plugin +// since transform-runtime does not cover instance methods +// such as "foobar".includes("foo") which bits of our library +// code use, but the babel transform-runtime plugin allows the +// regenerator runtime to be injected early enough in the process +// (it can't be here as it's too late: the alternative is to put +// the babel-polyfill as the first 'entry' in the webpack config). +// https://babeljs.io/docs/plugins/transform-runtime/ require('babel-polyfill'); // CSS requires: just putting them here for now as CSS is going to be