From 8a10c04f42a1e4509c13905d2f61d65ca3679379 Mon Sep 17 00:00:00 2001
From: Paul Kaplan <pkaplan@media.mit.edu>
Date: Thu, 20 Jul 2017 10:41:54 -0400
Subject: [PATCH] Add import/export rules and fix lint errors

---
 package.json                                  |  1 +
 src/.eslintrc.js                              |  8 ++-
 src/components/asset-panel/asset-panel.jsx    |  2 +-
 src/components/asset-panel/selector.jsx       |  2 +-
 .../audio-trimmer/audio-trimmer.jsx           |  2 +-
 src/components/blocks/blocks.jsx              |  2 +-
 src/components/box/box.jsx                    |  2 +-
 .../buffered-input/buffered-input.jsx         |  2 +-
 src/components/button/button.jsx              |  2 +-
 src/components/close-button/close-button.jsx  |  2 +-
 .../costume-canvas/costume-canvas.jsx         |  2 +-
 src/components/filter/filter.jsx              |  2 +-
 src/components/green-flag/green-flag.jsx      |  2 +-
 src/components/gui/gui.jsx                    |  2 +-
 .../language-selector/language-selector.jsx   |  2 +-
 src/components/library-item/library-item.jsx  |  2 +-
 src/components/library/library.jsx            |  2 +-
 src/components/load-button/load-button.jsx    |  2 +-
 src/components/menu-bar/menu-bar.jsx          |  2 +-
 src/components/meter/meter.jsx                |  2 +-
 src/components/modal/modal.jsx                |  2 +-
 src/components/monitor-list/monitor-list.jsx  |  2 +-
 src/components/monitor/monitor.jsx            |  2 +-
 src/components/prompt/prompt.jsx              |  2 +-
 src/components/record-modal/playback-step.jsx |  2 +-
 src/components/record-modal/record-modal.jsx  |  2 +-
 .../record-modal/recording-step.jsx           |  2 +-
 src/components/sprite-info/sprite-info.jsx    |  2 +-
 .../sprite-selector-item.jsx                  |  2 +-
 .../sprite-selector/sprite-selector.jsx       |  2 +-
 .../stage-selector/stage-selector.jsx         |  2 +-
 src/components/stage/stage.jsx                |  2 +-
 src/components/stop-all/stop-all.jsx          |  2 +-
 src/components/target-pane/target-pane.jsx    |  2 +-
 src/components/waveform/waveform.jsx          |  2 +-
 src/containers/audio-trimmer.jsx              |  2 +-
 src/containers/backdrop-library.jsx           |  2 +-
 src/containers/blocks.jsx                     |  2 +-
 src/containers/costume-library.jsx            |  2 +-
 src/containers/costume-tab.jsx                |  6 +-
 src/containers/green-flag.jsx                 |  2 +-
 src/containers/gui.jsx                        |  2 +-
 src/containers/language-selector.jsx          |  2 +-
 src/containers/load-button.jsx                |  2 +-
 src/containers/monitor-list.jsx               |  2 +-
 src/containers/monitor.jsx                    |  2 +-
 src/containers/playback-step.jsx              |  2 +-
 src/containers/prompt.jsx                     |  2 +-
 src/containers/record-modal.jsx               |  6 +-
 src/containers/recording-step.jsx             |  2 +-
 src/containers/save-button.jsx                |  2 +-
 src/containers/sound-library.jsx              |  2 +-
 src/containers/sound-tab.jsx                  |  6 +-
 src/containers/sprite-info.jsx                |  2 +-
 src/containers/sprite-library.jsx             |  2 +-
 src/containers/sprite-selector-item.jsx       |  2 +-
 src/containers/stage-selector.jsx             |  2 +-
 src/containers/stage.jsx                      |  2 +-
 src/containers/stop-all.jsx                   |  2 +-
 src/containers/target-pane.jsx                |  6 +-
 src/lib/audio/audio-buffer-player.js          |  2 +-
 src/lib/audio/audio-recorder.js               |  2 +-
 src/lib/audio/shared-audio-context.js         |  4 +-
 src/lib/blocks.js                             |  4 +-
 src/lib/log.js                                |  2 +-
 src/lib/monitor-adapter.js                    |  4 +-
 src/lib/opcode-labels.js                      |  4 +-
 src/lib/project-loader.js                     |  5 +-
 src/lib/storage.js                            |  2 +-
 src/lib/vm-listener-hoc.jsx                   |  2 +-
 src/reducers/gui.js                           |  2 +-
 src/reducers/intl.js                          |  7 ++-
 src/reducers/modals.js                        | 58 +++++++++++--------
 src/reducers/monitors.js                      |  7 ++-
 src/reducers/targets.js                       | 10 +++-
 src/reducers/vm.js                            |  7 ++-
 76 files changed, 149 insertions(+), 114 deletions(-)

diff --git a/package.json b/package.json
index 4d41d6b2b..d2578d9a3 100644
--- a/package.json
+++ b/package.json
@@ -43,6 +43,7 @@
     "enzyme": "^2.8.2",
     "eslint": "^3.16.1",
     "eslint-config-scratch": "^3.0.0",
+    "eslint-plugin-import": "^2.7.0",
     "eslint-plugin-react": "^7.0.1",
     "gh-pages": "github:rschamp/gh-pages#publish-branch-to-subfolder",
     "html-webpack-plugin": "2.28.0",
diff --git a/src/.eslintrc.js b/src/.eslintrc.js
index 0abd74d67..e558dde26 100644
--- a/src/.eslintrc.js
+++ b/src/.eslintrc.js
@@ -1,10 +1,16 @@
 module.exports = {
     root: true,
-    extends: ['scratch', 'scratch/es6', 'scratch/react'],
+    extends: ['scratch', 'scratch/es6', 'scratch/react', 'import'],
     env: {
         browser: true
     },
     globals: {
         process: true
+    },
+    rules: {
+        'import/no-mutable-exports': 'error',
+        'import/no-commonjs': 'error',
+        'import/no-amd': 'error',
+        'import/no-nodejs-modules': 'error'
     }
 };
diff --git a/src/components/asset-panel/asset-panel.jsx b/src/components/asset-panel/asset-panel.jsx
index 743256294..a33c8d209 100644
--- a/src/components/asset-panel/asset-panel.jsx
+++ b/src/components/asset-panel/asset-panel.jsx
@@ -20,4 +20,4 @@ AssetPanel.propTypes = {
     ...Selector.propTypes
 };
 
-module.exports = AssetPanel;
+export default AssetPanel;
diff --git a/src/components/asset-panel/selector.jsx b/src/components/asset-panel/selector.jsx
index d37cca757..51b1b6a82 100644
--- a/src/components/asset-panel/selector.jsx
+++ b/src/components/asset-panel/selector.jsx
@@ -68,4 +68,4 @@ Selector.propTypes = {
     selectedItemIndex: PropTypes.number.isRequired
 };
 
-module.exports = Selector;
+export default Selector;
diff --git a/src/components/audio-trimmer/audio-trimmer.jsx b/src/components/audio-trimmer/audio-trimmer.jsx
index 840b240f5..d414f3ae2 100644
--- a/src/components/audio-trimmer/audio-trimmer.jsx
+++ b/src/components/audio-trimmer/audio-trimmer.jsx
@@ -67,4 +67,4 @@ AudioTrimmer.propTypes = {
     trimStart: PropTypes.number.isRequired
 };
 
-module.exports = AudioTrimmer;
+export default AudioTrimmer;
diff --git a/src/components/blocks/blocks.jsx b/src/components/blocks/blocks.jsx
index 8afcad5e9..683da23c1 100644
--- a/src/components/blocks/blocks.jsx
+++ b/src/components/blocks/blocks.jsx
@@ -19,4 +19,4 @@ const BlocksComponent = props => {
 BlocksComponent.propTypes = {
     componentRef: PropTypes.func
 };
-module.exports = BlocksComponent;
+export default BlocksComponent;
diff --git a/src/components/box/box.jsx b/src/components/box/box.jsx
index cd4a202b0..4e9c8cdb8 100644
--- a/src/components/box/box.jsx
+++ b/src/components/box/box.jsx
@@ -136,4 +136,4 @@ Box.defaultProps = {
     element: 'div',
     style: {}
 };
-module.exports = Box;
+export default Box;
diff --git a/src/components/buffered-input/buffered-input.jsx b/src/components/buffered-input/buffered-input.jsx
index b66d80eb9..13645956e 100644
--- a/src/components/buffered-input/buffered-input.jsx
+++ b/src/components/buffered-input/buffered-input.jsx
@@ -49,4 +49,4 @@ BufferedInput.propTypes = {
     onSubmit: PropTypes.func.isRequired,
     value: PropTypes.oneOfType([PropTypes.string, PropTypes.number])
 };
-module.exports = BufferedInput;
+export default BufferedInput;
diff --git a/src/components/button/button.jsx b/src/components/button/button.jsx
index 59609cf76..ae322d10f 100644
--- a/src/components/button/button.jsx
+++ b/src/components/button/button.jsx
@@ -28,4 +28,4 @@ ButtonComponent.propTypes = {
     className: PropTypes.string,
     onClick: PropTypes.func.isRequired
 };
-module.exports = ButtonComponent;
+export default ButtonComponent;
diff --git a/src/components/close-button/close-button.jsx b/src/components/close-button/close-button.jsx
index 688e991b6..416adec8e 100644
--- a/src/components/close-button/close-button.jsx
+++ b/src/components/close-button/close-button.jsx
@@ -37,4 +37,4 @@ CloseButton.defaultProps = {
     size: CloseButton.SIZE_LARGE
 };
 
-module.exports = CloseButton;
+export default CloseButton;
diff --git a/src/components/costume-canvas/costume-canvas.jsx b/src/components/costume-canvas/costume-canvas.jsx
index 5a4a0342e..eafe92930 100644
--- a/src/components/costume-canvas/costume-canvas.jsx
+++ b/src/components/costume-canvas/costume-canvas.jsx
@@ -127,4 +127,4 @@ CostumeCanvas.propTypes = {
     width: PropTypes.number
 };
 
-module.exports = CostumeCanvas;
+export default CostumeCanvas;
diff --git a/src/components/filter/filter.jsx b/src/components/filter/filter.jsx
index d88f2f301..5363ef081 100644
--- a/src/components/filter/filter.jsx
+++ b/src/components/filter/filter.jsx
@@ -54,4 +54,4 @@ FilterComponent.propTypes = {
 FilterComponent.defaultProps = {
     placeholderText: 'what are you looking for?'
 };
-module.exports = FilterComponent;
+export default FilterComponent;
diff --git a/src/components/green-flag/green-flag.jsx b/src/components/green-flag/green-flag.jsx
index 0e9267389..692a347cd 100644
--- a/src/components/green-flag/green-flag.jsx
+++ b/src/components/green-flag/green-flag.jsx
@@ -34,4 +34,4 @@ GreenFlagComponent.defaultProps = {
     active: false,
     title: 'Go'
 };
-module.exports = GreenFlagComponent;
+export default GreenFlagComponent;
diff --git a/src/components/gui/gui.jsx b/src/components/gui/gui.jsx
index 3eafbb71c..f15a5c9a9 100644
--- a/src/components/gui/gui.jsx
+++ b/src/components/gui/gui.jsx
@@ -121,4 +121,4 @@ GUIComponent.propTypes = {
 GUIComponent.defaultProps = {
     basePath: './'
 };
-module.exports = GUIComponent;
+export default GUIComponent;
diff --git a/src/components/language-selector/language-selector.jsx b/src/components/language-selector/language-selector.jsx
index 6c6ffd829..febf81645 100644
--- a/src/components/language-selector/language-selector.jsx
+++ b/src/components/language-selector/language-selector.jsx
@@ -41,4 +41,4 @@ LanguageSelector.propTypes = {
     onChange: PropTypes.func
 };
 
-module.exports = LanguageSelector;
+export default LanguageSelector;
diff --git a/src/components/library-item/library-item.jsx b/src/components/library-item/library-item.jsx
index d96ea0251..5e0fa5edc 100644
--- a/src/components/library-item/library-item.jsx
+++ b/src/components/library-item/library-item.jsx
@@ -56,4 +56,4 @@ LibraryItem.propTypes = {
     onSelect: PropTypes.func.isRequired
 };
 
-module.exports = LibraryItem;
+export default LibraryItem;
diff --git a/src/components/library/library.jsx b/src/components/library/library.jsx
index e878ebc73..f5c0ae30c 100644
--- a/src/components/library/library.jsx
+++ b/src/components/library/library.jsx
@@ -97,4 +97,4 @@ LibraryComponent.propTypes = {
     visible: PropTypes.bool.isRequired
 };
 
-module.exports = LibraryComponent;
+export default LibraryComponent;
diff --git a/src/components/load-button/load-button.jsx b/src/components/load-button/load-button.jsx
index 37519e993..dd94a2a11 100644
--- a/src/components/load-button/load-button.jsx
+++ b/src/components/load-button/load-button.jsx
@@ -33,4 +33,4 @@ LoadButtonComponent.propTypes = {
 LoadButtonComponent.defaultProps = {
     title: 'Load'
 };
-module.exports = LoadButtonComponent;
+export default LoadButtonComponent;
diff --git a/src/components/menu-bar/menu-bar.jsx b/src/components/menu-bar/menu-bar.jsx
index 35ced7049..661153f8d 100644
--- a/src/components/menu-bar/menu-bar.jsx
+++ b/src/components/menu-bar/menu-bar.jsx
@@ -29,4 +29,4 @@ const MenuBar = function MenuBar () {
     );
 };
 
-module.exports = MenuBar;
+export default MenuBar;
diff --git a/src/components/meter/meter.jsx b/src/components/meter/meter.jsx
index de8f3da93..b2878a8dd 100644
--- a/src/components/meter/meter.jsx
+++ b/src/components/meter/meter.jsx
@@ -59,4 +59,4 @@ Meter.propTypes = {
     width: PropTypes.number
 };
 
-module.exports = Meter;
+export default Meter;
diff --git a/src/components/modal/modal.jsx b/src/components/modal/modal.jsx
index da4c62027..4b2711f51 100644
--- a/src/components/modal/modal.jsx
+++ b/src/components/modal/modal.jsx
@@ -72,4 +72,4 @@ ModalComponent.propTypes = {
     visible: PropTypes.bool.isRequired
 };
 
-module.exports = ModalComponent;
+export default ModalComponent;
diff --git a/src/components/monitor-list/monitor-list.jsx b/src/components/monitor-list/monitor-list.jsx
index 36337e7c2..e28f8e098 100644
--- a/src/components/monitor-list/monitor-list.jsx
+++ b/src/components/monitor-list/monitor-list.jsx
@@ -30,4 +30,4 @@ MonitorList.propTypes = {
     onMonitorChange: PropTypes.func.isRequired
 };
 
-module.exports = MonitorList;
+export default MonitorList;
diff --git a/src/components/monitor/monitor.jsx b/src/components/monitor/monitor.jsx
index dbd86226c..5d03b1ee4 100644
--- a/src/components/monitor/monitor.jsx
+++ b/src/components/monitor/monitor.jsx
@@ -53,4 +53,4 @@ MonitorComponent.defaultProps = {
     y: 0
 };
 
-module.exports = MonitorComponent;
+export default MonitorComponent;
diff --git a/src/components/prompt/prompt.jsx b/src/components/prompt/prompt.jsx
index 7ea82374f..d43002b41 100644
--- a/src/components/prompt/prompt.jsx
+++ b/src/components/prompt/prompt.jsx
@@ -53,4 +53,4 @@ PromptComponent.propTypes = {
     title: PropTypes.string.isRequired
 };
 
-module.exports = PromptComponent;
+export default PromptComponent;
diff --git a/src/components/record-modal/playback-step.jsx b/src/components/record-modal/playback-step.jsx
index 0eddd9142..636d2ac99 100644
--- a/src/components/record-modal/playback-step.jsx
+++ b/src/components/record-modal/playback-step.jsx
@@ -83,4 +83,4 @@ PlaybackStep.propTypes = {
     trimStart: PropTypes.number.isRequired
 };
 
-module.exports = PlaybackStep;
+export default PlaybackStep;
diff --git a/src/components/record-modal/record-modal.jsx b/src/components/record-modal/record-modal.jsx
index 92bc0e38e..b215ad17f 100644
--- a/src/components/record-modal/record-modal.jsx
+++ b/src/components/record-modal/record-modal.jsx
@@ -63,4 +63,4 @@ RecordModal.propTypes = {
     trimStart: PropTypes.number.isRequired
 };
 
-module.exports = RecordModal;
+export default RecordModal;
diff --git a/src/components/record-modal/recording-step.jsx b/src/components/record-modal/recording-step.jsx
index ef78768c4..624a2e2b2 100644
--- a/src/components/record-modal/recording-step.jsx
+++ b/src/components/record-modal/recording-step.jsx
@@ -80,4 +80,4 @@ RecordingStep.propTypes = {
     recording: PropTypes.bool
 };
 
-module.exports = RecordingStep;
+export default RecordingStep;
diff --git a/src/components/sprite-info/sprite-info.jsx b/src/components/sprite-info/sprite-info.jsx
index f9e3e73bd..73c550c2c 100644
--- a/src/components/sprite-info/sprite-info.jsx
+++ b/src/components/sprite-info/sprite-info.jsx
@@ -190,4 +190,4 @@ SpriteInfo.propTypes = {
     ])
 };
 
-module.exports = SpriteInfo;
+export default SpriteInfo;
diff --git a/src/components/sprite-selector-item/sprite-selector-item.jsx b/src/components/sprite-selector-item/sprite-selector-item.jsx
index f9e3b5b1b..d1be3c3dc 100644
--- a/src/components/sprite-selector-item/sprite-selector-item.jsx
+++ b/src/components/sprite-selector-item/sprite-selector-item.jsx
@@ -46,4 +46,4 @@ SpriteSelectorItem.propTypes = {
     selected: PropTypes.bool.isRequired
 };
 
-module.exports = SpriteSelectorItem;
+export default SpriteSelectorItem;
diff --git a/src/components/sprite-selector/sprite-selector.jsx b/src/components/sprite-selector/sprite-selector.jsx
index b5c8ee844..6fc0a5bbc 100644
--- a/src/components/sprite-selector/sprite-selector.jsx
+++ b/src/components/sprite-selector/sprite-selector.jsx
@@ -98,4 +98,4 @@ SpriteSelectorComponent.propTypes = {
     })
 };
 
-module.exports = SpriteSelectorComponent;
+export default SpriteSelectorComponent;
diff --git a/src/components/stage-selector/stage-selector.jsx b/src/components/stage-selector/stage-selector.jsx
index eabb692e3..09ddb9a23 100644
--- a/src/components/stage-selector/stage-selector.jsx
+++ b/src/components/stage-selector/stage-selector.jsx
@@ -53,4 +53,4 @@ StageSelector.propTypes = {
     selected: PropTypes.bool.isRequired,
     url: PropTypes.string
 };
-module.exports = StageSelector;
+export default StageSelector;
diff --git a/src/components/stage/stage.jsx b/src/components/stage/stage.jsx
index 63a27bf56..92ef79f21 100644
--- a/src/components/stage/stage.jsx
+++ b/src/components/stage/stage.jsx
@@ -38,4 +38,4 @@ StageComponent.defaultProps = {
     width: 480,
     height: 360
 };
-module.exports = StageComponent;
+export default StageComponent;
diff --git a/src/components/stop-all/stop-all.jsx b/src/components/stop-all/stop-all.jsx
index 4d85e2c46..aba3ed424 100644
--- a/src/components/stop-all/stop-all.jsx
+++ b/src/components/stop-all/stop-all.jsx
@@ -37,4 +37,4 @@ StopAllComponent.defaultProps = {
     title: 'Stop'
 };
 
-module.exports = StopAllComponent;
+export default StopAllComponent;
diff --git a/src/components/target-pane/target-pane.jsx b/src/components/target-pane/target-pane.jsx
index 0d48924af..a6b7f2368 100644
--- a/src/components/target-pane/target-pane.jsx
+++ b/src/components/target-pane/target-pane.jsx
@@ -166,4 +166,4 @@ TargetPane.propTypes = {
     vm: PropTypes.instanceOf(VM)
 };
 
-module.exports = TargetPane;
+export default TargetPane;
diff --git a/src/components/waveform/waveform.jsx b/src/components/waveform/waveform.jsx
index 502bbb280..7b46760ac 100644
--- a/src/components/waveform/waveform.jsx
+++ b/src/components/waveform/waveform.jsx
@@ -48,4 +48,4 @@ Waveform.propTypes = {
     width: PropTypes.number
 };
 
-module.exports = Waveform;
+export default Waveform;
diff --git a/src/containers/audio-trimmer.jsx b/src/containers/audio-trimmer.jsx
index d9409b225..07ba2154d 100644
--- a/src/containers/audio-trimmer.jsx
+++ b/src/containers/audio-trimmer.jsx
@@ -69,4 +69,4 @@ AudioTrimmer.propTypes = {
     trimStart: PropTypes.number
 };
 
-module.exports = AudioTrimmer;
+export default AudioTrimmer;
diff --git a/src/containers/backdrop-library.jsx b/src/containers/backdrop-library.jsx
index 72e2a1c76..e455a0a25 100644
--- a/src/containers/backdrop-library.jsx
+++ b/src/containers/backdrop-library.jsx
@@ -43,4 +43,4 @@ BackdropLibrary.propTypes = {
     vm: PropTypes.instanceOf(VM).isRequired
 };
 
-module.exports = BackdropLibrary;
+export default BackdropLibrary;
diff --git a/src/containers/blocks.jsx b/src/containers/blocks.jsx
index bc8e3ff38..c922b6885 100644
--- a/src/containers/blocks.jsx
+++ b/src/containers/blocks.jsx
@@ -263,4 +263,4 @@ Blocks.defaultProps = {
     options: Blocks.defaultOptions
 };
 
-module.exports = Blocks;
+export default Blocks;
diff --git a/src/containers/costume-library.jsx b/src/containers/costume-library.jsx
index 168d4b950..ee5526752 100644
--- a/src/containers/costume-library.jsx
+++ b/src/containers/costume-library.jsx
@@ -43,4 +43,4 @@ CostumeLibrary.propTypes = {
     vm: PropTypes.instanceOf(VM).isRequired
 };
 
-module.exports = CostumeLibrary;
+export default CostumeLibrary;
diff --git a/src/containers/costume-tab.jsx b/src/containers/costume-tab.jsx
index dcef1fa1e..594f1a7b9 100644
--- a/src/containers/costume-tab.jsx
+++ b/src/containers/costume-tab.jsx
@@ -9,10 +9,10 @@ import addCostumeIcon from '../components/asset-panel/icon--add-costume-lib.svg'
 
 import {connect} from 'react-redux';
 
-const {
+import {
     openCostumeLibrary,
     openBackdropLibrary
-} = require('../reducers/modals');
+} from '../reducers/modals';
 
 class CostumeTab extends React.Component {
     constructor (props) {
@@ -134,7 +134,7 @@ const mapDispatchToProps = dispatch => ({
     }
 });
 
-module.exports = connect(
+export default connect(
     mapStateToProps,
     mapDispatchToProps
 )(CostumeTab);
diff --git a/src/containers/green-flag.jsx b/src/containers/green-flag.jsx
index e4f852053..b1f6acabf 100644
--- a/src/containers/green-flag.jsx
+++ b/src/containers/green-flag.jsx
@@ -69,4 +69,4 @@ GreenFlag.propTypes = {
     vm: PropTypes.instanceOf(VM)
 };
 
-module.exports = GreenFlag;
+export default GreenFlag;
diff --git a/src/containers/gui.jsx b/src/containers/gui.jsx
index 89f251639..87f195aab 100644
--- a/src/containers/gui.jsx
+++ b/src/containers/gui.jsx
@@ -56,4 +56,4 @@ GUI.propTypes = {
 
 GUI.defaultProps = GUIComponent.defaultProps;
 
-module.exports = vmListenerHOC(GUI);
+export default vmListenerHOC(GUI);
diff --git a/src/containers/language-selector.jsx b/src/containers/language-selector.jsx
index 9412b0c53..ae0d2405c 100644
--- a/src/containers/language-selector.jsx
+++ b/src/containers/language-selector.jsx
@@ -14,7 +14,7 @@ const mapDispatchToProps = dispatch => ({
     }
 });
 
-module.exports = connect(
+export default connect(
     mapStateToProps,
     mapDispatchToProps
 )(LanguageSelectorComponent);
diff --git a/src/containers/load-button.jsx b/src/containers/load-button.jsx
index d07e5e105..a7b78a638 100644
--- a/src/containers/load-button.jsx
+++ b/src/containers/load-button.jsx
@@ -49,7 +49,7 @@ const mapStateToProps = state => ({
     loadProject: state.vm.fromJSON.bind(state.vm)
 });
 
-module.exports = connect(
+export default connect(
     mapStateToProps,
     () => ({}) // omit dispatch prop
 )(LoadButton);
diff --git a/src/containers/monitor-list.jsx b/src/containers/monitor-list.jsx
index adfc2ea5a..d8becdc66 100644
--- a/src/containers/monitor-list.jsx
+++ b/src/containers/monitor-list.jsx
@@ -30,7 +30,7 @@ const mapStateToProps = state => ({
 });
 const mapDispatchToProps = () => ({});
 
-module.exports = connect(
+export default connect(
     mapStateToProps,
     mapDispatchToProps
 )(MonitorList);
diff --git a/src/containers/monitor.jsx b/src/containers/monitor.jsx
index 297649fa6..cbacffe7d 100644
--- a/src/containers/monitor.jsx
+++ b/src/containers/monitor.jsx
@@ -39,4 +39,4 @@ Monitor.propTypes = {
     value: PropTypes.string.isRequired // eslint-disable-line react/no-unused-prop-types
 };
 
-module.exports = Monitor;
+export default Monitor;
diff --git a/src/containers/playback-step.jsx b/src/containers/playback-step.jsx
index 8b0ba283d..ce61bcc04 100644
--- a/src/containers/playback-step.jsx
+++ b/src/containers/playback-step.jsx
@@ -53,4 +53,4 @@ PlaybackStep.propTypes = {
     ...PlaybackStepComponent.propTypes
 };
 
-module.exports = PlaybackStep;
+export default PlaybackStep;
diff --git a/src/containers/prompt.jsx b/src/containers/prompt.jsx
index 556caf949..78158fd05 100644
--- a/src/containers/prompt.jsx
+++ b/src/containers/prompt.jsx
@@ -51,4 +51,4 @@ Prompt.propTypes = {
     title: PropTypes.string.isRequired
 };
 
-module.exports = Prompt;
+export default Prompt;
diff --git a/src/containers/record-modal.jsx b/src/containers/record-modal.jsx
index a59adaafa..2f7cff84c 100644
--- a/src/containers/record-modal.jsx
+++ b/src/containers/record-modal.jsx
@@ -7,9 +7,9 @@ import {connect} from 'react-redux';
 
 import RecordModalComponent from '../components/record-modal/record-modal.jsx';
 
-const {
+import {
     closeSoundRecorder
-} = require('../reducers/modals');
+} from '../reducers/modals';
 
 class RecordModal extends React.Component {
     constructor (props) {
@@ -139,7 +139,7 @@ const mapDispatchToProps = dispatch => ({
     }
 });
 
-module.exports = connect(
+export default connect(
     mapStateToProps,
     mapDispatchToProps
 )(RecordModal);
diff --git a/src/containers/recording-step.jsx b/src/containers/recording-step.jsx
index ed9601635..d1fc3302b 100644
--- a/src/containers/recording-step.jsx
+++ b/src/containers/recording-step.jsx
@@ -68,4 +68,4 @@ class RecordingStep extends React.Component {
 
 RecordingStep.propTypes = RecordingStepComponent.propTypes;
 
-module.exports = RecordingStep;
+export default RecordingStep;
diff --git a/src/containers/save-button.jsx b/src/containers/save-button.jsx
index 08585d0f0..12585ab70 100644
--- a/src/containers/save-button.jsx
+++ b/src/containers/save-button.jsx
@@ -56,7 +56,7 @@ const mapStateToProps = state => ({
     saveProjectSb3: state.vm.saveProjectSb3.bind(state.vm)
 });
 
-module.exports = connect(
+export default connect(
     mapStateToProps,
     () => ({}) // omit dispatch prop
 )(SaveButton);
diff --git a/src/containers/sound-library.jsx b/src/containers/sound-library.jsx
index 3de7f7053..9c1608fb7 100644
--- a/src/containers/sound-library.jsx
+++ b/src/containers/sound-library.jsx
@@ -91,4 +91,4 @@ SoundLibrary.propTypes = {
     vm: PropTypes.instanceOf(VM).isRequired
 };
 
-module.exports = SoundLibrary;
+export default SoundLibrary;
diff --git a/src/containers/sound-tab.jsx b/src/containers/sound-tab.jsx
index d0c41fe73..4aa43db97 100644
--- a/src/containers/sound-tab.jsx
+++ b/src/containers/sound-tab.jsx
@@ -13,10 +13,10 @@ import RecordModal from './record-modal.jsx';
 
 import {connect} from 'react-redux';
 
-const {
+import {
     openSoundLibrary,
     openSoundRecorder
-} = require('../reducers/modals');
+} from '../reducers/modals';
 
 class SoundTab extends React.Component {
     constructor (props) {
@@ -153,7 +153,7 @@ const mapDispatchToProps = dispatch => ({
     }
 });
 
-module.exports = connect(
+export default connect(
     mapStateToProps,
     mapDispatchToProps
 )(SoundTab);
diff --git a/src/containers/sprite-info.jsx b/src/containers/sprite-info.jsx
index 1b63c2e00..532fb37e5 100644
--- a/src/containers/sprite-info.jsx
+++ b/src/containers/sprite-info.jsx
@@ -48,4 +48,4 @@ SpriteInfo.propTypes = {
     y: PropTypes.number
 };
 
-module.exports = SpriteInfo;
+export default SpriteInfo;
diff --git a/src/containers/sprite-library.jsx b/src/containers/sprite-library.jsx
index 17befee57..cb1126420 100644
--- a/src/containers/sprite-library.jsx
+++ b/src/containers/sprite-library.jsx
@@ -82,4 +82,4 @@ SpriteLibrary.propTypes = {
     vm: PropTypes.instanceOf(VM).isRequired
 };
 
-module.exports = SpriteLibrary;
+export default SpriteLibrary;
diff --git a/src/containers/sprite-selector-item.jsx b/src/containers/sprite-selector-item.jsx
index d662b15f4..aa19efc1f 100644
--- a/src/containers/sprite-selector-item.jsx
+++ b/src/containers/sprite-selector-item.jsx
@@ -58,6 +58,6 @@ const mapStateToProps = (state, {assetId, costumeURL}) => ({
     costumeURL: costumeURL || (assetId && state.vm.runtime.storage.get(assetId).encodeDataURI())
 });
 
-module.exports = connect(
+export default connect(
     mapStateToProps
 )(SpriteSelectorItem);
diff --git a/src/containers/stage-selector.jsx b/src/containers/stage-selector.jsx
index 5bb779e32..1c2018584 100644
--- a/src/containers/stage-selector.jsx
+++ b/src/containers/stage-selector.jsx
@@ -44,7 +44,7 @@ const mapStateToProps = (state, {assetId}) => ({
     url: assetId && state.vm.runtime.storage.get(assetId).encodeDataURI()
 });
 
-module.exports = connect(
+export default connect(
     mapStateToProps,
     () => ({}) // omit dispatch prop
 )(StageSelector);
diff --git a/src/containers/stage.jsx b/src/containers/stage.jsx
index 0c161023b..f0545c088 100644
--- a/src/containers/stage.jsx
+++ b/src/containers/stage.jsx
@@ -195,4 +195,4 @@ Stage.propTypes = {
     vm: PropTypes.instanceOf(VM).isRequired
 };
 
-module.exports = Stage;
+export default Stage;
diff --git a/src/containers/stop-all.jsx b/src/containers/stop-all.jsx
index 4f80a2eaf..0f7641a20 100644
--- a/src/containers/stop-all.jsx
+++ b/src/containers/stop-all.jsx
@@ -52,4 +52,4 @@ StopAll.propTypes = {
     vm: PropTypes.instanceOf(VM)
 };
 
-module.exports = StopAll;
+export default StopAll;
diff --git a/src/containers/target-pane.jsx b/src/containers/target-pane.jsx
index 0d8a3a15c..3445e49ef 100644
--- a/src/containers/target-pane.jsx
+++ b/src/containers/target-pane.jsx
@@ -3,14 +3,14 @@ import React from 'react';
 
 import {connect} from 'react-redux';
 
-const {
+import {
     openBackdropLibrary,
     openSpriteLibrary,
     closeBackdropLibrary,
     closeCostumeLibrary,
     closeSoundLibrary,
     closeSpriteLibrary
-} = require('../reducers/modals');
+} from '../reducers/modals';
 
 import TargetPaneComponent from '../components/target-pane/target-pane.jsx';
 
@@ -117,7 +117,7 @@ const mapDispatchToProps = dispatch => ({
     }
 });
 
-module.exports = connect(
+export default connect(
     mapStateToProps,
     mapDispatchToProps
 )(TargetPane);
diff --git a/src/lib/audio/audio-buffer-player.js b/src/lib/audio/audio-buffer-player.js
index ba333f1f9..5d643c846 100644
--- a/src/lib/audio/audio-buffer-player.js
+++ b/src/lib/audio/audio-buffer-player.js
@@ -50,4 +50,4 @@ class AudioBufferPlayer {
     }
 }
 
-module.exports = AudioBufferPlayer;
+export default AudioBufferPlayer;
diff --git a/src/lib/audio/audio-recorder.js b/src/lib/audio/audio-recorder.js
index ace2b9807..e10ff81ce 100644
--- a/src/lib/audio/audio-recorder.js
+++ b/src/lib/audio/audio-recorder.js
@@ -136,4 +136,4 @@ class AudioRecorder {
     }
 }
 
-module.exports = AudioRecorder;
+export default AudioRecorder;
diff --git a/src/lib/audio/shared-audio-context.js b/src/lib/audio/shared-audio-context.js
index c76e79667..f0b5c3ccf 100644
--- a/src/lib/audio/shared-audio-context.js
+++ b/src/lib/audio/shared-audio-context.js
@@ -1,6 +1,6 @@
 // Wrap browser AudioContext because we shouldn't create more than one
 const AUDIO_CONTEXT = new (window.AudioContext || window.webkitAudioContext)();
 
-module.exports = function () {
+export default function () {
     return AUDIO_CONTEXT;
-};
+}
diff --git a/src/lib/blocks.js b/src/lib/blocks.js
index b966846a6..7c6b10b21 100644
--- a/src/lib/blocks.js
+++ b/src/lib/blocks.js
@@ -1,6 +1,6 @@
 import ScratchBlocks from 'scratch-blocks';
 
-module.exports = function (vm) {
+export default function (vm) {
 
     const jsonForMenuBlock = function (name, menuOptionsFn, colors, start) {
         return {
@@ -137,4 +137,4 @@ module.exports = function (vm) {
     };
 
     return ScratchBlocks;
-};
+}
diff --git a/src/lib/log.js b/src/lib/log.js
index 839dc372d..6d1cb725f 100644
--- a/src/lib/log.js
+++ b/src/lib/log.js
@@ -1,4 +1,4 @@
 import minilog from 'minilog';
 minilog.enable();
 
-module.exports = minilog('gui');
+export default minilog('gui');
diff --git a/src/lib/monitor-adapter.js b/src/lib/monitor-adapter.js
index 0fc7efbc5..4a05cf328 100644
--- a/src/lib/monitor-adapter.js
+++ b/src/lib/monitor-adapter.js
@@ -10,7 +10,7 @@ const MONITOR_HEIGHT = 23;
 
 const isUndefined = a => typeof a === 'undefined';
 
-module.exports = function ({id, index, opcode, params, value, x, y}) {
+export default function ({id, index, opcode, params, value, x, y}) {
     let {label, category, labelFn} = OpcodeLabels(opcode);
 
     // Use labelFn if provided for dynamic labelling (e.g. variables)
@@ -23,4 +23,4 @@ module.exports = function ({id, index, opcode, params, value, x, y}) {
     if (isUndefined(y)) y = PADDING + (index * (PADDING + MONITOR_HEIGHT));
 
     return {id, label, category, value, x, y};
-};
+}
diff --git a/src/lib/opcode-labels.js b/src/lib/opcode-labels.js
index bebe14743..6acc4109b 100644
--- a/src/lib/opcode-labels.js
+++ b/src/lib/opcode-labels.js
@@ -66,10 +66,10 @@ const opcodeMap = {
     }
 };
 
-module.exports = function (opcode) {
+export default function (opcode) {
     if (opcode in opcodeMap) return opcodeMap[opcode];
     return {
         category: 'data',
         label: opcode
     };
-};
+}
diff --git a/src/lib/project-loader.js b/src/lib/project-loader.js
index 5b15929dc..050607320 100644
--- a/src/lib/project-loader.js
+++ b/src/lib/project-loader.js
@@ -1,6 +1,7 @@
 import xhr from 'xhr';
 
 import log from './log';
+import emptyProject from './empty-project.json';
 
 class ProjectLoader {
     constructor () {
@@ -17,6 +18,6 @@ class ProjectLoader {
     }
 }
 
-ProjectLoader.DEFAULT_PROJECT_DATA = require('./empty-project.json');
+ProjectLoader.DEFAULT_PROJECT_DATA = emptyProject;
 
-module.exports = new ProjectLoader();
+export default new ProjectLoader();
diff --git a/src/lib/storage.js b/src/lib/storage.js
index 6b3f4877c..e1dc91bd6 100644
--- a/src/lib/storage.js
+++ b/src/lib/storage.js
@@ -26,4 +26,4 @@ class Storage extends ScratchStorage {
     }
 }
 
-module.exports = Storage;
+export default Storage;
diff --git a/src/lib/vm-listener-hoc.jsx b/src/lib/vm-listener-hoc.jsx
index 8cbf05c50..e0f2bcb5d 100644
--- a/src/lib/vm-listener-hoc.jsx
+++ b/src/lib/vm-listener-hoc.jsx
@@ -113,4 +113,4 @@ const vmListenerHOC = function (WrappedComponent) {
     )(VMListener);
 };
 
-module.exports = vmListenerHOC;
+export default vmListenerHOC;
diff --git a/src/reducers/gui.js b/src/reducers/gui.js
index c08306e99..c83dd7fca 100644
--- a/src/reducers/gui.js
+++ b/src/reducers/gui.js
@@ -6,7 +6,7 @@ import targetReducer from './targets';
 import vmReducer from './vm';
 
 
-module.exports = combineReducers({
+export default combineReducers({
     intl: intlReducer,
     modals: modalReducer,
     monitors: monitorReducer,
diff --git a/src/reducers/intl.js b/src/reducers/intl.js
index 14fa64ef5..dda310dfb 100644
--- a/src/reducers/intl.js
+++ b/src/reducers/intl.js
@@ -22,4 +22,9 @@ const updateIntl = locale => superUpdateIntl({
     messages: messages[locale] || messages.en
 });
 
-export {intlReducer as default, IntlProvider, intlInitialState, updateIntl};
+export {
+    intlReducer as default,
+    IntlProvider,
+    intlInitialState,
+    updateIntl
+};
diff --git a/src/reducers/modals.js b/src/reducers/modals.js
index 2e59b144a..e651f0517 100644
--- a/src/reducers/modals.js
+++ b/src/reducers/modals.js
@@ -30,46 +30,58 @@ const reducer = function (state, action) {
         return state;
     }
 };
-reducer.openModal = function (modal) {
+const openModal = function (modal) {
     return {
         type: OPEN_MODAL,
         modal: modal
     };
 };
-reducer.closeModal = function (modal) {
+const closeModal = function (modal) {
     return {
         type: CLOSE_MODAL,
         modal: modal
     };
 };
-reducer.openBackdropLibrary = function () {
-    return reducer.openModal(MODAL_BACKDROP_LIBRARY);
+const openBackdropLibrary = function () {
+    return openModal(MODAL_BACKDROP_LIBRARY);
 };
-reducer.openCostumeLibrary = function () {
-    return reducer.openModal(MODAL_COSTUME_LIBRARY);
+const openCostumeLibrary = function () {
+    return openModal(MODAL_COSTUME_LIBRARY);
 };
-reducer.openSoundLibrary = function () {
-    return reducer.openModal(MODAL_SOUND_LIBRARY);
+const openSoundLibrary = function () {
+    return openModal(MODAL_SOUND_LIBRARY);
 };
-reducer.openSpriteLibrary = function () {
-    return reducer.openModal(MODAL_SPRITE_LIBRARY);
+const openSpriteLibrary = function () {
+    return openModal(MODAL_SPRITE_LIBRARY);
 };
-reducer.openSoundRecorder = function () {
-    return reducer.openModal(MODAL_SOUND_RECORDER);
+const openSoundRecorder = function () {
+    return openModal(MODAL_SOUND_RECORDER);
 };
-reducer.closeBackdropLibrary = function () {
-    return reducer.closeModal(MODAL_BACKDROP_LIBRARY);
+const closeBackdropLibrary = function () {
+    return closeModal(MODAL_BACKDROP_LIBRARY);
 };
-reducer.closeCostumeLibrary = function () {
-    return reducer.closeModal(MODAL_COSTUME_LIBRARY);
+const closeCostumeLibrary = function () {
+    return closeModal(MODAL_COSTUME_LIBRARY);
 };
-reducer.closeSpriteLibrary = function () {
-    return reducer.closeModal(MODAL_SPRITE_LIBRARY);
+const closeSpriteLibrary = function () {
+    return closeModal(MODAL_SPRITE_LIBRARY);
 };
-reducer.closeSoundLibrary = function () {
-    return reducer.closeModal(MODAL_SOUND_LIBRARY);
+const closeSoundLibrary = function () {
+    return closeModal(MODAL_SOUND_LIBRARY);
 };
-reducer.closeSoundRecorder = function () {
-    return reducer.closeModal(MODAL_SOUND_RECORDER);
+const closeSoundRecorder = function () {
+    return closeModal(MODAL_SOUND_RECORDER);
+};
+export {
+    reducer as default,
+    openBackdropLibrary,
+    openCostumeLibrary,
+    openSoundLibrary,
+    openSpriteLibrary,
+    openSoundRecorder,
+    closeBackdropLibrary,
+    closeCostumeLibrary,
+    closeSpriteLibrary,
+    closeSoundLibrary,
+    closeSoundRecorder
 };
-module.exports = reducer;
diff --git a/src/reducers/monitors.js b/src/reducers/monitors.js
index e1428c2c6..1b1b1f436 100644
--- a/src/reducers/monitors.js
+++ b/src/reducers/monitors.js
@@ -13,7 +13,7 @@ const reducer = function (state, action) {
     }
 };
 
-reducer.updateMonitors = function (monitors) {
+const updateMonitors = function (monitors) {
     return {
         type: UPDATE_MONITORS,
         monitors: monitors,
@@ -23,4 +23,7 @@ reducer.updateMonitors = function (monitors) {
     };
 };
 
-module.exports = reducer;
+export {
+    reducer as default,
+    updateMonitors
+};
diff --git a/src/reducers/targets.js b/src/reducers/targets.js
index 0ed67cf2d..6df9632d9 100644
--- a/src/reducers/targets.js
+++ b/src/reducers/targets.js
@@ -29,7 +29,7 @@ const reducer = function (state, action) {
         return state;
     }
 };
-reducer.updateTargets = function (targetList) {
+const updateTargets = function (targetList) {
     return {
         type: UPDATE_TARGET_LIST,
         targets: targetList,
@@ -38,7 +38,7 @@ reducer.updateTargets = function (targetList) {
         }
     };
 };
-reducer.updateEditingTarget = function (editingTarget) {
+const updateEditingTarget = function (editingTarget) {
     return {
         type: UPDATE_EDITING_TARGET,
         target: editingTarget,
@@ -47,4 +47,8 @@ reducer.updateEditingTarget = function (editingTarget) {
         }
     };
 };
-module.exports = reducer;
+export {
+    reducer as default,
+    updateTargets,
+    updateEditingTarget
+};
diff --git a/src/reducers/vm.js b/src/reducers/vm.js
index 2ac5c1c92..5d0e6f91f 100644
--- a/src/reducers/vm.js
+++ b/src/reducers/vm.js
@@ -15,10 +15,13 @@ const reducer = function (state, action) {
         return state;
     }
 };
-reducer.setVM = function (vm) {
+const setVM = function (vm) {
     return {
         type: SET_VM,
         vm: vm
     };
 };
-module.exports = reducer;
+export {
+    reducer as default,
+    setVM
+};
-- 
GitLab