From 9c6d94ada0f2b401aeb5c41b3dbf31a912a80840 Mon Sep 17 00:00:00 2001 From: Brian Jacobel <bjacobel@gmail.com> Date: Mon, 8 May 2017 17:07:35 -0400 Subject: [PATCH] Require and Webpack can eat the same files --- cms/static/cms/js/main.js | 2 +- .../js/features/import/factories/import.js | 2 +- .../common/js/components/views/feedback.js | 357 +++++++++--------- .../components/views/feedback_notification.js | 56 +-- .../acceptance/pages/studio/import_export.py | 18 - .../tests/studio/test_import_export.py | 10 - package.json | 2 + pavelib/assets.py | 18 +- scripts/safe_template_linter.py | 2 + webpack.config.js | 32 +- 10 files changed, 256 insertions(+), 243 deletions(-) diff --git a/cms/static/cms/js/main.js b/cms/static/cms/js/main.js index 0e1a36911d3..a126bc01687 100644 --- a/cms/static/cms/js/main.js +++ b/cms/static/cms/js/main.js @@ -8,7 +8,7 @@ 'underscore.string', 'backbone', 'gettext', - '../../../../common/static/common/js/components/views/feedback_notification', + '../../common/js/components/views/feedback_notification', 'jquery.cookie' ], function(domReady, $, str, Backbone, gettext, NotificationView) { var main, sendJSON; diff --git a/cms/static/js/features/import/factories/import.js b/cms/static/js/features/import/factories/import.js index 7a5e4f02468..28bee92cec9 100644 --- a/cms/static/js/features/import/factories/import.js +++ b/cms/static/js/features/import/factories/import.js @@ -116,7 +116,7 @@ define([ Import.reset(); onComplete(); - alert(gettext('Your import has failed.') + '\n\n' + errMsg); + alert(gettext('Your import has failed.') + '\n\n' + errMsg); // eslint-disable-line max-len, no-alert } } }); diff --git a/common/static/common/js/components/views/feedback.js b/common/static/common/js/components/views/feedback.js index dce22284834..65dff2bda7b 100644 --- a/common/static/common/js/components/views/feedback.js +++ b/common/static/common/js/components/views/feedback.js @@ -1,197 +1,202 @@ -define(['jquery', +(function(define) { + 'use strict'; + define([ + 'jquery', 'underscore', 'underscore.string', 'backbone', - 'text!../../../../common/templates/components/system-feedback.underscore'], - function($, _, str, Backbone, systemFeedbackTemplate) { - var tabbable_elements = [ - "a[href]:not([tabindex='-1'])", - "area[href]:not([tabindex='-1'])", - "input:not([disabled]):not([tabindex='-1'])", - "select:not([disabled]):not([tabindex='-1'])", - "textarea:not([disabled]):not([tabindex='-1'])", - "button:not([disabled]):not([tabindex='-1'])", - "iframe:not([tabindex='-1'])", - "[tabindex]:not([tabindex='-1'])", - "[contentEditable=true]:not([tabindex='-1'])" - ]; - var SystemFeedback = Backbone.View.extend({ - options: { - title: '', - message: '', - intent: null, // "warning", "confirmation", "error", "announcement", "step-required", etc - type: null, // "alert", "notification", or "prompt": set by subclass - shown: true, // is this view currently being shown? - icon: true, // should we render an icon related to the message intent? - closeIcon: true, // should we render a close button in the top right corner? - minShown: 0, // length of time after this view has been shown before it can be hidden (milliseconds) - maxShown: Infinity, // length of time after this view has been shown before it will be automatically hidden (milliseconds) - outFocusElement: null // element to send focus to on hide + 'edx-ui-toolkit/js/utils/html-utils', + 'text!../../../../common/templates/components/system-feedback.underscore' + ], + function($, _, str, Backbone, HtmlUtils, systemFeedbackTemplate) { + var tabbableElements = [ + "a[href]:not([tabindex='-1'])", + "area[href]:not([tabindex='-1'])", + "input:not([disabled]):not([tabindex='-1'])", + "select:not([disabled]):not([tabindex='-1'])", + "textarea:not([disabled]):not([tabindex='-1'])", + "button:not([disabled]):not([tabindex='-1'])", + "iframe:not([tabindex='-1'])", + "[tabindex]:not([tabindex='-1'])", + "[contentEditable=true]:not([tabindex='-1'])" + ]; + var SystemFeedback = Backbone.View.extend({ + options: { + title: '', + message: '', + intent: null, // "warning", "confirmation", "error", "announcement", "step-required", etc + type: null, // "alert", "notification", or "prompt": set by subclass + shown: true, // is this view currently being shown? + icon: true, // should we render an icon related to the message intent? + closeIcon: true, // should we render a close button in the top right corner? + minShown: 0, // ms after this view has been shown before it can be hidden + maxShown: Infinity, // ms after this view has been shown before it will be automatically hidden + outFocusElement: null // element to send focus to on hide - /* Could also have an "actions" hash: here is an example demonstrating - the expected structure. For each action, by default the framework - will call preventDefault on the click event before the function is - run; to make it not do that, just pass `preventDefault: false` in - the action object. + /* Could also have an "actions" hash: here is an example demonstrating + the expected structure. For each action, by default the framework + will call preventDefault on the click event before the function is + run; to make it not do that, just pass `preventDefault: false` in + the action object. - actions: { - primary: { - "text": "Save", - "class": "action-save", - "click": function(view) { - // do something when Save is clicked - } - }, - secondary: [ - { - "text": "Cancel", - "class": "action-cancel", - "click": function(view) {} - }, { - "text": "Discard Changes", - "class": "action-discard", - "click": function(view) {} - } - ] - } - */ - }, - - initialize: function(options) { - this.options = _.extend({}, this.options, options); - if (!this.options.type) { - throw 'SystemFeedback: type required (given ' + - JSON.stringify(this.options) + ')'; - } - if (!this.options.intent) { - throw 'SystemFeedback: intent required (given ' + - JSON.stringify(this.options) + ')'; - } - this.setElement($('#page-' + this.options.type)); - // handle single "secondary" action - if (this.options.actions && this.options.actions.secondary && - !_.isArray(this.options.actions.secondary)) { - this.options.actions.secondary = [this.options.actions.secondary]; + actions: { + primary: { + "text": "Save", + "class": "action-save", + "click": function(view) { + // do something when Save is clicked + } + }, + secondary: [ + { + "text": "Cancel", + "class": "action-cancel", + "click": function(view) {} + }, { + "text": "Discard Changes", + "class": "action-discard", + "click": function(view) {} + } + ] } - return this; - }, - - inFocus: function(wrapperElementSelector) { - var wrapper = wrapperElementSelector || '.wrapper', - tabbables; - this.options.outFocusElement = this.options.outFocusElement || document.activeElement; - - // Set focus to the container. - this.$(wrapper).first().focus(); + */ + }, - // Make tabs within the prompt loop rather than setting focus - // back to the main content of the page. - tabbables = this.$(tabbable_elements.join()); - tabbables.on('keydown', function(event) { - // On tab backward from the first tabbable item in the prompt - if (event.which === 9 && event.shiftKey && event.target === tabbables.first()[0]) { - event.preventDefault(); - tabbables.last().focus(); + initialize: function(options) { + this.options = _.extend({}, this.options, options); + if (!this.options.type) { + throw 'SystemFeedback: type required (given ' + // eslint-disable-line no-throw-literal + JSON.stringify(this.options) + ')'; } - // On tab forward from the last tabbable item in the prompt - else if (event.which === 9 && !event.shiftKey && event.target === tabbables.last()[0]) { - event.preventDefault(); - tabbables.first().focus(); + if (!this.options.intent) { + throw 'SystemFeedback: intent required (given ' + // eslint-disable-line no-throw-literal + JSON.stringify(this.options) + ')'; } - }); + this.setElement($('#page-' + this.options.type)); + // handle single "secondary" action + if (this.options.actions && this.options.actions.secondary && + !_.isArray(this.options.actions.secondary)) { + this.options.actions.secondary = [this.options.actions.secondary]; + } + return this; + }, - return this; - }, + inFocus: function(wrapperElementSelector) { + var wrapper = wrapperElementSelector || '.wrapper', + tabbables; + this.options.outFocusElement = this.options.outFocusElement || document.activeElement; - outFocus: function() { - var tabbables = this.$(tabbable_elements.join()).off('keydown'); - if (this.options.outFocusElement) { - this.options.outFocusElement.focus(); - } - return this; - }, + // Set focus to the container. + this.$(wrapper).first().focus(); - // public API: show() and hide() - show: function() { - clearTimeout(this.hideTimeout); - this.options.shown = true; - this.shownAt = new Date(); - this.render(); - if ($.isNumeric(this.options.maxShown)) { - this.hideTimeout = setTimeout(_.bind(this.hide, this), - this.options.maxShown); - } - return this; - }, + // Make tabs within the prompt loop rather than setting focus + // back to the main content of the page. + tabbables = this.$(tabbableElements.join()); + tabbables.on('keydown', function(event) { + // On tab backward from the first tabbable item in the prompt + if (event.which === 9 && event.shiftKey && event.target === tabbables.first()[0]) { + event.preventDefault(); + tabbables.last().focus(); + } else if (event.which === 9 && !event.shiftKey && event.target === tabbables.last()[0]) { + // On tab forward from the last tabbable item in the prompt + event.preventDefault(); + tabbables.first().focus(); + } + }); + + return this; + }, - hide: function() { - if (this.shownAt && $.isNumeric(this.options.minShown) && - this.options.minShown > new Date() - this.shownAt) { + outFocus: function() { + this.$(tabbableElements.join()).off('keydown'); + if (this.options.outFocusElement) { + this.options.outFocusElement.focus(); + } + return this; + }, + + // public API: show() and hide() + show: function() { clearTimeout(this.hideTimeout); - this.hideTimeout = setTimeout(_.bind(this.hide, this), - this.options.minShown - (new Date() - this.shownAt)); - } else { - this.options.shown = false; - delete this.shownAt; + this.options.shown = true; + this.shownAt = new Date(); this.render(); - } - return this; - }, + if ($.isNumeric(this.options.maxShown)) { + this.hideTimeout = setTimeout(_.bind(this.hide, this), + this.options.maxShown); + } + return this; + }, - // the rest of the API should be considered semi-private - events: { - 'click .action-close': 'hide', - 'click .action-primary': 'primaryClick', - 'click .action-secondary': 'secondaryClick' - }, + hide: function() { + if (this.shownAt && $.isNumeric(this.options.minShown) && + this.options.minShown > new Date() - this.shownAt) { + clearTimeout(this.hideTimeout); + this.hideTimeout = setTimeout(_.bind(this.hide, this), + this.options.minShown - (new Date() - this.shownAt)); + } else { + this.options.shown = false; + delete this.shownAt; + this.render(); + } + return this; + }, - render: function() { - // there can be only one active view of a given type at a time: only - // one alert, only one notification, only one prompt. Therefore, we'll - // use a singleton approach. - var singleton = SystemFeedback['active_' + this.options.type]; - if (singleton && singleton !== this) { - singleton.stopListening(); - singleton.undelegateEvents(); - } - this.$el.html(_.template(systemFeedbackTemplate)(this.options)); - SystemFeedback['active_' + this.options.type] = this; - return this; - }, + // the rest of the API should be considered semi-private + events: { + 'click .action-close': 'hide', + 'click .action-primary': 'primaryClick', + 'click .action-secondary': 'secondaryClick' + }, - primaryClick: function(event) { - var actions, primary; - actions = this.options.actions; - if (!actions) { return; } - primary = actions.primary; - if (!primary) { return; } - if (primary.preventDefault !== false) { - event.preventDefault(); - } - if (primary.click) { - primary.click.call(event.target, this, event); - } - }, + render: function() { + // there can be only one active view of a given type at a time: only + // one alert, only one notification, only one prompt. Therefore, we'll + // use a singleton approach. + var singleton = SystemFeedback['active_' + this.options.type]; + if (singleton && singleton !== this) { + singleton.stopListening(); + singleton.undelegateEvents(); + } + HtmlUtils.setHtml(this.$el, HtmlUtils.template(systemFeedbackTemplate)(this.options)); + SystemFeedback['active_' + this.options.type] = this; + return this; + }, - secondaryClick: function(event) { - var actions, secondaryList, secondary, i; - actions = this.options.actions; - if (!actions) { return; } - secondaryList = actions.secondary; - if (!secondaryList) { return; } - // which secondary action was clicked? - i = 0; // default to the first secondary action (easier for testing) - if (event && event.target) { - i = _.indexOf(this.$('.action-secondary'), event.target); - } - secondary = secondaryList[i]; - if (secondary.preventDefault !== false) { - event.preventDefault(); - } - if (secondary.click) { - secondary.click.call(event.target, this, event); + primaryClick: function(event) { + var actions, primary; + actions = this.options.actions; + if (!actions) { return; } + primary = actions.primary; + if (!primary) { return; } + if (primary.preventDefault !== false) { + event.preventDefault(); + } + if (primary.click) { + primary.click.call(event.target, this, event); + } + }, + + secondaryClick: function(event) { + var actions, secondaryList, secondary, i; + actions = this.options.actions; + if (!actions) { return; } + secondaryList = actions.secondary; + if (!secondaryList) { return; } + // which secondary action was clicked? + i = 0; // default to the first secondary action (easier for testing) + if (event && event.target) { + i = _.indexOf(this.$('.action-secondary'), event.target); + } + secondary = secondaryList[i]; + if (secondary.preventDefault !== false) { + event.preventDefault(); + } + if (secondary.click) { + secondary.click.call(event.target, this, event); + } } - } + }); + return SystemFeedback; }); - return SystemFeedback; - }); +}).call(this, define || RequireJS.define); diff --git a/common/static/common/js/components/views/feedback_notification.js b/common/static/common/js/components/views/feedback_notification.js index 9450a1ce4b8..79ff850ccbf 100644 --- a/common/static/common/js/components/views/feedback_notification.js +++ b/common/static/common/js/components/views/feedback_notification.js @@ -1,30 +1,34 @@ -define(['jquery', 'underscore', 'underscore.string', '../../../../common/js/components/views/feedback'], - function($, _, str, SystemFeedbackView) { - var Notification = SystemFeedbackView.extend({ - options: $.extend({}, SystemFeedbackView.prototype.options, { - type: 'notification', - closeIcon: false - }) - }); - - // create Notification.Warning, Notification.Confirmation, etc - var capitalCamel, intents; - capitalCamel = _.compose(str.capitalize, str.camelize); - intents = ['warning', 'error', 'confirmation', 'announcement', 'step-required', 'help', 'mini']; - _.each(intents, function(intent) { - var subclass; - subclass = Notification.extend({ - options: $.extend({}, Notification.prototype.options, { - intent: intent +(function(define) { + 'use strict'; + define(['jquery', 'underscore', 'underscore.string', './feedback'], + function($, _, str, SystemFeedbackView) { + var Notification = SystemFeedbackView.extend({ + options: $.extend({}, SystemFeedbackView.prototype.options, { + type: 'notification', + closeIcon: false }) }); - Notification[capitalCamel(intent)] = subclass; - }); - // set more sensible defaults for Notification.Mini views - var miniOptions = Notification.Mini.prototype.options; - miniOptions.minShown = 1250; - miniOptions.closeIcon = false; + // create Notification.Warning, Notification.Confirmation, etc + var capitalCamel, intents, miniOptions; + capitalCamel = _.compose(str.capitalize, str.camelize); + intents = ['warning', 'error', 'confirmation', 'announcement', 'step-required', 'help', 'mini']; + _.each(intents, function(intent) { + var subclass; + subclass = Notification.extend({ + options: $.extend({}, Notification.prototype.options, { + intent: intent + }) + }); + Notification[capitalCamel(intent)] = subclass; + }); + + // set more sensible defaults for Notification.Mini views + miniOptions = Notification.Mini.prototype.options; + miniOptions.minShown = 1250; + miniOptions.closeIcon = false; - return Notification; - }); + return Notification; + } + ); +}).call(this, define || RequireJS.define); diff --git a/common/test/acceptance/pages/studio/import_export.py b/common/test/acceptance/pages/studio/import_export.py index 62e9f3ced9c..d49f66704b4 100644 --- a/common/test/acceptance/pages/studio/import_export.py +++ b/common/test/acceptance/pages/studio/import_export.py @@ -253,17 +253,6 @@ class ImportMixin(ImportExportMixin): """ return self.q(css='.choose-file-button').present - def is_click_handler_registered(self): - """ - Check if the click handler for the file selector button has been registered yet - """ - script = """ - var $ = require('jquery'), - buttonEvents = $._data($('a.choose-file-button')[0], 'events'); - return buttonEvents && buttonEvents.hasOwnProperty('click');""" - stripped_script = ''.join([line.strip() for line in script.split('\n')]) - return self.browser.execute_script(stripped_script) - @staticmethod def file_path(filename): """ @@ -325,13 +314,6 @@ class ImportMixin(ImportExportMixin): """ return self.q(css='#fileupload .error-block').visible - def wait_for_choose_file_click_handler(self): - """ - Wait for the choose file button click handler to be registered - """ - EmptyPromise(self.is_click_handler_registered, 'Choose File Button Click Handler Registered', - timeout=30).fulfill() - def wait_for_filename_error(self): """ Wait for the upload field to display an error. diff --git a/common/test/acceptance/tests/studio/test_import_export.py b/common/test/acceptance/tests/studio/test_import_export.py index de1a4a09c9f..1cfeb2ae302 100644 --- a/common/test/acceptance/tests/studio/test_import_export.py +++ b/common/test/acceptance/tests/studio/test_import_export.py @@ -168,7 +168,6 @@ class ImportTestMixin(object): I can select the file and upload it And the page will give me confirmation that it uploaded successfully """ - self.import_page.wait_for_choose_file_click_handler() self.import_page.upload_tarball(self.tarball_name) self.import_page.wait_for_upload() @@ -184,7 +183,6 @@ class ImportTestMixin(object): # import_page timestamp is in (MM/DD/YYYY at HH:mm) so replacing (second, microsecond) to # keep the comparison consistent upload_start_time = datetime.utcnow().replace(microsecond=0, second=0) - self.import_page.wait_for_choose_file_click_handler() self.import_page.upload_tarball(self.tarball_name) self.import_page.wait_for_upload() @@ -218,7 +216,6 @@ class ImportTestMixin(object): Given that I upload a library or course A button will appear that contains the URL to the library or course's main page """ - self.import_page.wait_for_choose_file_click_handler() self.import_page.upload_tarball(self.tarball_name) self.assertEqual(self.import_page.finished_target_url(), self.landing_page.url) @@ -228,7 +225,6 @@ class ImportTestMixin(object): Given that I select a file that is an .mp4 for upload An error message will appear """ - self.import_page.wait_for_choose_file_click_handler() self.import_page.upload_tarball('funny_cat_video.mp4') self.import_page.wait_for_filename_error() @@ -244,7 +240,6 @@ class ImportTestMixin(object): # The task list shouldn't be visible to start. self.assertFalse(self.import_page.is_task_list_showing(), "Task list shown too early.") self.import_page.wait_for_tasks() - self.import_page.wait_for_choose_file_click_handler() self.import_page.upload_tarball(self.tarball_name) self.import_page.wait_for_tasks(completed=True) self.assertTrue(self.import_page.is_task_list_showing(), "Task list did not display.") @@ -258,7 +253,6 @@ class ImportTestMixin(object): And the 'Updating' task should be marked failed And the remaining tasks should not be marked as started """ - self.import_page.wait_for_choose_file_click_handler() self.import_page.upload_tarball(self.bad_tarball_name) self.import_page.wait_for_tasks(fail_on='Updating') @@ -296,7 +290,6 @@ class TestEntranceExamCourseImport(ImportTestMixin, StudioCourseTest): self.assertRaises(IndexError, self.landing_page.section, "Section") self.assertRaises(IndexError, self.landing_page.section, "Entrance Exam") self.import_page.visit() - self.import_page.wait_for_choose_file_click_handler() self.import_page.upload_tarball(self.tarball_name) self.import_page.wait_for_upload() self.landing_page.visit() @@ -346,7 +339,6 @@ class TestCourseImport(ImportTestMixin, StudioCourseTest): # Should not exist yet. self.assertRaises(IndexError, self.landing_page.section, "Section") self.import_page.visit() - self.import_page.wait_for_choose_file_click_handler() self.import_page.upload_tarball(self.tarball_name) self.import_page.wait_for_upload() self.landing_page.visit() @@ -373,7 +365,6 @@ class TestCourseImport(ImportTestMixin, StudioCourseTest): Then timestamp is not visible """ self.import_page.visit() - self.import_page.wait_for_choose_file_click_handler() self.import_page.upload_tarball(self.tarball_name) self.import_page.wait_for_upload() self.assertTrue(self.import_page.is_timestamp_visible()) @@ -419,7 +410,6 @@ class TestLibraryImport(ImportTestMixin, StudioLibraryTest): # No items should be in the library to start. self.assertEqual(len(self.landing_page.xblocks), 0) self.import_page.visit() - self.import_page.wait_for_choose_file_click_handler() self.import_page.upload_tarball(self.tarball_name) self.import_page.wait_for_upload() self.landing_page.visit() diff --git a/package.json b/package.json index 0ad73a2a70c..832ce7d89bf 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "picturefill": "~3.0.2", "raw-loader": "^0.5.1", "requirejs": "~2.3.2", + "string-replace-webpack-plugin": "^0.1.3", "uglify-js": "2.7.0", "underscore": "~1.8.3", "underscore.string": "~3.3.4", @@ -32,6 +33,7 @@ "edx-custom-a11y-rules": "0.1.3", "eslint-config-edx": "^2.0.1", "eslint-config-edx-es5": "^2.0.0", + "eslint-import-resolver-webpack": "^0.8.1", "jasmine-core": "^2.4.1", "jasmine-jquery": "^2.1.1", "karma": "^0.13.22", diff --git a/pavelib/assets.py b/pavelib/assets.py index 28bbf2aa4fc..f86cc37b365 100644 --- a/pavelib/assets.py +++ b/pavelib/assets.py @@ -708,11 +708,11 @@ def execute_webpack(prod, settings=None): sh( cmd( "NODE_ENV={node_env} STATIC_ROOT_LMS={static_root_lms} STATIC_ROOT_CMS={static_root_cms} $(npm bin)/webpack" - .format( - node_env="production" if prod else "development", - static_root_lms=Env.get_django_setting("STATIC_ROOT", "lms", settings=settings), - static_root_cms=Env.get_django_setting("STATIC_ROOT", "cms", settings=settings) - ) + .format( + node_env="production" if prod else "development", + static_root_lms=Env.get_django_setting("STATIC_ROOT", "lms", settings=settings), + static_root_cms=Env.get_django_setting("STATIC_ROOT", "cms", settings=settings) + ) ) ) @@ -720,10 +720,10 @@ def execute_webpack(prod, settings=None): def execute_webpack_watch(settings=None): run_background_process( "STATIC_ROOT_LMS={static_root_lms} STATIC_ROOT_CMS={static_root_cms} $(npm bin)/webpack --watch --watch-poll=200" - .format( - static_root_lms=Env.get_django_setting("STATIC_ROOT", "lms", settings=settings), - static_root_cms=Env.get_django_setting("STATIC_ROOT", "cms", settings=settings) - ) + .format( + static_root_lms=Env.get_django_setting("STATIC_ROOT", "lms", settings=settings), + static_root_cms=Env.get_django_setting("STATIC_ROOT", "cms", settings=settings) + ) ) diff --git a/scripts/safe_template_linter.py b/scripts/safe_template_linter.py index 9a50339278a..b2ebf182aa5 100755 --- a/scripts/safe_template_linter.py +++ b/scripts/safe_template_linter.py @@ -2378,6 +2378,8 @@ class MakoTemplateLinter(BaseLinter): </script> | # script tag end <%static:require_module(_async)?.*?> | # require js script tag start (optionally the _async version) </%static:require_module(_async)?> | # require js script tag end (optionally the _async version) + <%static:webpack.*?> | # webpack script tag start + </%static:webpack> | # webpack script tag end <%block[ ]*name=['"]requirejs['"]\w*> | # require js tag start </%block> # require js tag end """, diff --git a/webpack.config.js b/webpack.config.js index 58770212320..7c33a7defdb 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -5,9 +5,15 @@ var path = require('path'); var webpack = require('webpack'); var BundleTracker = require('webpack-bundle-tracker'); +var StringReplace = require('string-replace-webpack-plugin'); var isProd = process.env.NODE_ENV === 'production'; +var namespacedRequireFiles = [ + path.resolve(__dirname, 'common/static/common/js/components/views/feedback_notification.js'), + path.resolve(__dirname, 'common/static/common/js/components/views/feedback.js') +]; + var wpconfig = { context: __dirname, @@ -51,9 +57,30 @@ var wpconfig = { module: { rules: [ + { + test: namespacedRequireFiles, + loader: StringReplace.replace( + ['babel-loader'], + { + replacements: [ + { + pattern: /\(function ?\(define\) ?\{/, + replacement: function() { return ''; } + }, + { + pattern: /\}\)\.call\(this, define \|\| RequireJS\.define\);/, + replacement: function() { return ''; } + } + ] + } + ) + }, { test: /\.js$/, - exclude: /node_modules/, + exclude: [ + /node_modules/, + namespacedRequireFiles + ], use: 'babel-loader' }, { @@ -72,7 +99,8 @@ var wpconfig = { use: { loader: 'imports-loader', options: { - AjaxPrefix: 'exports-loader?this.AjaxPrefix!../../../../common/static/coffee/src/ajax_prefix.coffee' + AjaxPrefix: + 'exports-loader?this.AjaxPrefix!../../../../common/static/coffee/src/ajax_prefix.coffee' } } } -- GitLab