Commit 480a3ca6 by Brian Jacobel

Move course import JS to Webpack

parent 49b11cb6
...@@ -116,6 +116,7 @@ GITHUB_REPO_ROOT = ENV_TOKENS.get('GITHUB_REPO_ROOT', GITHUB_REPO_ROOT) ...@@ -116,6 +116,7 @@ GITHUB_REPO_ROOT = ENV_TOKENS.get('GITHUB_REPO_ROOT', GITHUB_REPO_ROOT)
STATIC_ROOT_BASE = ENV_TOKENS.get('STATIC_ROOT_BASE', None) STATIC_ROOT_BASE = ENV_TOKENS.get('STATIC_ROOT_BASE', None)
if STATIC_ROOT_BASE: if STATIC_ROOT_BASE:
STATIC_ROOT = path(STATIC_ROOT_BASE) / EDX_PLATFORM_REVISION STATIC_ROOT = path(STATIC_ROOT_BASE) / EDX_PLATFORM_REVISION
WEBPACK_LOADER['DEFAULT']['STATS_FILE'] = STATIC_ROOT / "webpack-stats.json"
EMAIL_BACKEND = ENV_TOKENS.get('EMAIL_BACKEND', EMAIL_BACKEND) EMAIL_BACKEND = ENV_TOKENS.get('EMAIL_BACKEND', EMAIL_BACKEND)
EMAIL_FILE_PATH = ENV_TOKENS.get('EMAIL_FILE_PATH', None) EMAIL_FILE_PATH = ENV_TOKENS.get('EMAIL_FILE_PATH', None)
......
...@@ -100,7 +100,6 @@ ...@@ -100,7 +100,6 @@
"SERVER_EMAIL": "devops@example.com", "SERVER_EMAIL": "devops@example.com",
"SESSION_COOKIE_DOMAIN": null, "SESSION_COOKIE_DOMAIN": null,
"SITE_NAME": "localhost", "SITE_NAME": "localhost",
"STATIC_ROOT_BASE": "** OVERRIDDEN **",
"STATIC_URL_BASE": "/static/", "STATIC_URL_BASE": "/static/",
"SYSLOG_SERVER": "", "SYSLOG_SERVER": "",
"TECH_SUPPORT_EMAIL": "technical@example.com", "TECH_SUPPORT_EMAIL": "technical@example.com",
......
...@@ -64,6 +64,8 @@ STATICFILES_DIRS = [ ...@@ -64,6 +64,8 @@ STATICFILES_DIRS = [
(TEST_ROOT / "staticfiles" / "cms").abspath(), (TEST_ROOT / "staticfiles" / "cms").abspath(),
] ]
WEBPACK_LOADER['DEFAULT']['STATS_FILE'] = TEST_ROOT / "staticfiles" / "cms" / "webpack-stats.json"
# Silence noisy logs # Silence noisy logs
import logging import logging
LOG_OVERRIDES = [ LOG_OVERRIDES = [
......
...@@ -747,6 +747,15 @@ REQUIRE_EXCLUDE = ("build.txt",) ...@@ -747,6 +747,15 @@ REQUIRE_EXCLUDE = ("build.txt",)
# returns a list with the command arguments to execute. # returns a list with the command arguments to execute.
REQUIRE_ENVIRONMENT = "node" REQUIRE_ENVIRONMENT = "node"
########################## DJANGO WEBPACK LOADER ##############################
WEBPACK_LOADER = {
'DEFAULT': {
'BUNDLE_DIR_NAME': 'bundles/',
'STATS_FILE': os.path.join(STATIC_ROOT, 'webpack-stats.json')
}
}
################################# CELERY ###################################### ################################# CELERY ######################################
# Message configuration # Message configuration
...@@ -881,6 +890,7 @@ INSTALLED_APPS = ( ...@@ -881,6 +890,7 @@ INSTALLED_APPS = (
'pipeline', 'pipeline',
'static_replace', 'static_replace',
'require', 'require',
'webpack_loader',
# Theming # Theming
'openedx.core.djangoapps.theming', 'openedx.core.djangoapps.theming',
......
...@@ -66,6 +66,7 @@ TEST_ROOT = path('test_root') ...@@ -66,6 +66,7 @@ TEST_ROOT = path('test_root')
# Want static files in the same dir for running on jenkins. # Want static files in the same dir for running on jenkins.
STATIC_ROOT = TEST_ROOT / "staticfiles" STATIC_ROOT = TEST_ROOT / "staticfiles"
WEBPACK_LOADER['DEFAULT']['STATS_FILE'] = STATIC_ROOT / "webpack-stats.json"
GITHUB_REPO_ROOT = TEST_ROOT / "data" GITHUB_REPO_ROOT = TEST_ROOT / "data"
DATA_DIR = TEST_ROOT / "data" DATA_DIR = TEST_ROOT / "data"
......
...@@ -40,6 +40,7 @@ LOG_DIR = (TEST_ROOT / "log").abspath() ...@@ -40,6 +40,7 @@ LOG_DIR = (TEST_ROOT / "log").abspath()
# Store the static files under test root so that they don't overwrite existing static assets # Store the static files under test root so that they don't overwrite existing static assets
STATIC_ROOT = (TEST_ROOT / "staticfiles" / "cms").abspath() STATIC_ROOT = (TEST_ROOT / "staticfiles" / "cms").abspath()
WEBPACK_LOADER['DEFAULT']['STATS_FILE'] = STATIC_ROOT / "webpack-stats.json"
# Disable uglify when tests are running (used by build.js). # Disable uglify when tests are running (used by build.js).
# 1. Uglify is by far the slowest part of the build process # 1. Uglify is by far the slowest part of the build process
......
...@@ -41,7 +41,6 @@ ...@@ -41,7 +41,6 @@
'js/factories/export', 'js/factories/export',
'js/factories/group_configurations', 'js/factories/group_configurations',
'js/certificates/factories/certificates_page_factory', 'js/certificates/factories/certificates_page_factory',
'js/factories/import',
'js/factories/index', 'js/factories/index',
'js/factories/library', 'js/factories/library',
'js/factories/login', 'js/factories/login',
......
...@@ -2,10 +2,15 @@ ...@@ -2,10 +2,15 @@
(function(AjaxPrefix) { (function(AjaxPrefix) {
'use strict'; 'use strict';
define(['domReady', 'jquery', 'underscore.string', 'backbone', 'gettext', define([
'common/js/components/views/feedback_notification', 'coffee/src/ajax_prefix', 'domReady',
'jquery.cookie'], 'jquery',
function(domReady, $, str, Backbone, gettext, NotificationView) { 'underscore.string',
'backbone',
'gettext',
'../../../../common/static/common/js/components/views/feedback_notification',
'jquery.cookie'
], function(domReady, $, str, Backbone, gettext, NotificationView) {
var main, sendJSON; var main, sendJSON;
main = function() { main = function() {
AjaxPrefix.addAjaxPrefix(jQuery, function() { AjaxPrefix.addAjaxPrefix(jQuery, function() {
......
define([ define([
'domReady', 'js/views/import', 'jquery', 'gettext', 'jquery.fileupload', 'jquery.cookie' 'domReady',
'../views/import',
'jquery',
'gettext',
'jQuery-File-Upload/js/jquery.fileupload',
'jquery.cookie',
'../../../../cms/js/main'
], function(domReady, Import, $, gettext) { ], function(domReady, Import, $, gettext) {
'use strict'; 'use strict';
return function(feedbackUrl, library) { return {
var dbError; Import: function(feedbackUrl, library) {
var dbError,
if (library) { $bar = $('.progress-bar'),
dbError = gettext('There was an error while importing the new library to our database.'); $fill = $('.progress-fill'),
} else { $submitBtn = $('.submit-button'),
dbError = gettext('There was an error while importing the new course to our database.'); $chooseBtn = $('.view-import .choose-file-button'),
}
var bar = $('.progress-bar'),
fill = $('.progress-fill'),
submitBtn = $('.submit-button'),
chooseBtn = $('.view-import .choose-file-button'),
defaults = [ defaults = [
gettext('There was an error during the upload process.') + '\n', gettext('There was an error during the upload process.') + '\n',
gettext('There was an error while unpacking the file.') + '\n', gettext('There was an error while unpacking the file.') + '\n',
...@@ -24,16 +24,39 @@ define([ ...@@ -24,16 +24,39 @@ define([
], ],
unloading = false, unloading = false,
previousImport = Import.storedImport(), previousImport = Import.storedImport(),
file; file,
onComplete = function() {
var onComplete = function() { $bar.hide();
bar.hide(); $chooseBtn
chooseBtn
.find('.copy').text(gettext('Choose new file')).end() .find('.copy').text(gettext('Choose new file')).end()
.show(); .show();
},
showImportSubmit = function() {
var filepath = $(this).val(),
msg;
if (filepath.substr(filepath.length - 6, 6) === 'tar.gz') {
$('.error-block').hide();
$('.file-name').text($(this).val().replace('C:\\fakepath\\', ''));
$('.file-name-block').show();
$chooseBtn.hide();
$submitBtn.show();
$('.progress').show();
} else {
msg = gettext('File format not supported. Please upload a file with a {ext} extension.')
.replace('{ext}', '<code>tar.gz</code>');
$('.error-block').text(msg).show();
}
}; };
$(window).on('beforeunload', function(event) { unloading = true; }); if (library) {
dbError = gettext('There was an error while importing the new library to our database.');
} else {
dbError = gettext('There was an error while importing the new course to our database.');
}
$(window).on('beforeunload', function() { unloading = true; });
// Display the status of last file upload on page load // Display the status of last file upload on page load
if (previousImport) { if (previousImport) {
...@@ -44,7 +67,7 @@ define([ ...@@ -44,7 +67,7 @@ define([
.show(); .show();
if (previousImport.completed !== true) { if (previousImport.completed !== true) {
chooseBtn.hide(); $chooseBtn.hide();
} }
Import.resume().then(onComplete); Import.resume().then(onComplete);
...@@ -57,12 +80,12 @@ define([ ...@@ -57,12 +80,12 @@ define([
autoUpload: false, autoUpload: false,
add: function(e, data) { add: function(e, data) {
Import.reset(); Import.reset();
submitBtn.unbind('click'); $submitBtn.unbind('click');
file = data.files[0]; file = data.files[0];
if (file.name.match(/tar\.gz$/)) { if (file.name.match(/tar\.gz$/)) {
submitBtn.click(function(event) { $submitBtn.click(function(event) {
event.preventDefault(); event.preventDefault();
Import.start( Import.start(
...@@ -70,14 +93,13 @@ define([ ...@@ -70,14 +93,13 @@ define([
feedbackUrl.replace('fillerName', file.name) feedbackUrl.replace('fillerName', file.name)
).then(onComplete); ).then(onComplete);
submitBtn.hide(); $submitBtn.hide();
data.submit().complete(function(result, textStatus, xhr) { data.submit().complete(function(result, textStatus, xhr) {
if (xhr.status !== 200) {
var serverMsg, errMsg, stage; var serverMsg, errMsg, stage;
if (xhr.status !== 200) {
try { try {
serverMsg = $.parseJSON(result.responseText) || {}; serverMsg = $.parseJSON(result.responseText) || {};
} catch (e) { } catch (err) {
return; return;
} }
...@@ -86,10 +108,9 @@ define([ ...@@ -86,10 +108,9 @@ define([
if (serverMsg.hasOwnProperty('Stage')) { if (serverMsg.hasOwnProperty('Stage')) {
stage = Math.abs(serverMsg.Stage); stage = Math.abs(serverMsg.Stage);
Import.cancel(defaults[stage] + errMsg, stage); Import.cancel(defaults[stage] + errMsg, stage);
} } else if (!unloading) {
// It could be that the user is simply refreshing the page // It could be that the user is simply refreshing the page
// so we need to be sure this is an actual error from the server // so we need to be sure this is an actual error from the server
else if (!unloading) {
$(window).off('beforeunload.import'); $(window).off('beforeunload.import');
Import.reset(); Import.reset();
...@@ -101,7 +122,9 @@ define([ ...@@ -101,7 +122,9 @@ define([
}); });
}); });
} else { } else {
data.files = []; // Can't fix this lint error without major structural changes, which I'm not comfortable
// doing given this file's test coverage
data.files = []; // eslint-disable-line no-param-reassign
} }
}, },
...@@ -118,46 +141,29 @@ define([ ...@@ -118,46 +141,29 @@ define([
doneAt = 99; doneAt = 99;
} }
if (percentInt >= doneAt) { if (percentInt >= doneAt) {
bar.hide(); $bar.hide();
// Start feedback with delay so that current stage of // Start feedback with delay so that current stage of
// import properly updates in session // import properly updates in session
setTimeout(function() { Import.pollStatus(); }, 3000); setTimeout(function() { Import.pollStatus(); }, 3000);
} else { } else {
bar.show(); $bar.show();
fill.width(percentVal).text(percentVal); $fill.width(percentVal).text(percentVal);
} }
}, },
sequentialUploads: true, sequentialUploads: true,
notifyOnError: false notifyOnError: false
}); });
var showImportSubmit = function(e) {
var filepath = $(this).val();
if (filepath.substr(filepath.length - 6, 6) === 'tar.gz') {
$('.error-block').hide();
$('.file-name').text($(this).val().replace('C:\\fakepath\\', ''));
$('.file-name-block').show();
chooseBtn.hide();
submitBtn.show();
$('.progress').show();
} else {
var msg = gettext('File format not supported. Please upload a file with a {file_extension} extension.')
.replace('{file_extension}', '<code>tar.gz</code>');
$('.error-block').text(msg).show();
}
};
domReady(function() { domReady(function() {
// import form setup // import form setup
$('.view-import .file-input').bind('change', showImportSubmit); $('.view-import .file-input').bind('change', showImportSubmit);
$('.view-import .choose-file-button, .view-import .choose-file-button-inline').bind('click', function(e) { $('.view-import .choose-file-button, .view-import .choose-file-button-inline')
.bind('click', function(e) {
e.preventDefault(); e.preventDefault();
$('.view-import .file-input').click(); $('.view-import .file-input').click();
}); });
}); });
}
}; };
}); });
...@@ -11,18 +11,18 @@ define( ...@@ -11,18 +11,18 @@ define(
var COOKIE_NAME = 'lastimportupload'; var COOKIE_NAME = 'lastimportupload';
var STAGE = { var STAGE = {
'UPLOADING': 0, UPLOADING: 0,
'UNPACKING': 1, UNPACKING: 1,
'VERIFYING': 2, VERIFYING: 2,
'UPDATING': 3, UPDATING: 3,
'SUCCESS': 4 SUCCESS: 4
}; };
var STATE = { var STATE = {
'READY': 1, READY: 1,
'IN_PROGRESS': 2, IN_PROGRESS: 2,
'SUCCESS': 3, SUCCESS: 3,
'ERROR': 4 ERROR: 4
}; };
var current = {stage: 0, state: STATE.READY}; var current = {stage: 0, state: STATE.READY};
...@@ -35,6 +35,8 @@ define( ...@@ -35,6 +35,8 @@ define(
wrapper: $('div.wrapper-status') wrapper: $('div.wrapper-status')
}; };
var CourseImport;
/** ******** Private functions *****************************************/ /** ******** Private functions *****************************************/
/** /**
...@@ -55,32 +57,11 @@ define( ...@@ -55,32 +57,11 @@ define(
}; };
/** /**
* Sets the Import in the "error" status.
*
* Immediately stops any further polling from the server.
* Displays the error message at the list element that corresponds
* to the stage where the error occurred.
*
* @param {string} msg Error message to display.
* @param {int} [stage=current.stage] Stage of import process at which error occurred.
*/
var error = function(msg, stage) {
current.stage = Math.abs(stage || current.stage); // Could be negative
current.state = STATE.ERROR;
destroyEventListeners();
clearTimeout(timeout.id);
updateFeedbackList(msg);
deferred.resolve();
};
/**
* Initializes the event listeners * Initializes the event listeners
* *
*/ */
var initEventListeners = function() { var initEventListeners = function() {
$(window).on('beforeunload.import', function() { $(window).on('beforeunload.import', function() { // eslint-disable-line consistent-return
if (current.stage < STAGE.UNPACKING) { if (current.stage < STAGE.UNPACKING) {
return gettext('Your import is in progress; navigating away will abort it.'); return gettext('Your import is in progress; navigating away will abort it.');
} }
...@@ -101,25 +82,6 @@ define( ...@@ -101,25 +82,6 @@ define(
}; };
/** /**
* Sets the Import on the "success" status
*
* If it wasn't already, marks the stored import as "completed",
* and updates its date timestamp
*/
var success = function() {
current.state = STATE.SUCCESS;
if (CourseImport.storedImport().completed !== true) {
storeImport(true);
}
destroyEventListeners();
updateFeedbackList();
deferred.resolve();
};
/**
* Updates the Import feedback status list * Updates the Import feedback status list
* *
* @param {string} [currStageMsg=''] The message to show on the * @param {string} [currStageMsg=''] The message to show on the
...@@ -158,8 +120,11 @@ define( ...@@ -158,8 +120,11 @@ define(
$(stage) $(stage)
.removeClass('is-complete is-started has-error') .removeClass('is-complete is-started has-error')
.addClass('is-not-started') .addClass('is-not-started')
.find('p.error').remove().end() .find('p.error')
.find('p.copy').show(); .remove()
.end()
.find('p.copy')
.show();
} }
switch (current.state) { switch (current.state) {
...@@ -201,6 +166,9 @@ define( ...@@ -201,6 +166,9 @@ define(
errorStage($curr); errorStage($curr);
break; break;
default:
break;
} }
if (current.state === STATE.SUCCESS) { if (current.state === STATE.SUCCESS) {
...@@ -210,9 +178,49 @@ define( ...@@ -210,9 +178,49 @@ define(
} }
}; };
/**
* Sets the Import in the "error" status.
*
* Immediately stops any further polling from the server.
* Displays the error message at the list element that corresponds
* to the stage where the error occurred.
*
* @param {string} msg Error message to display.
* @param {int} [stage=current.stage] Stage of import process at which error occurred.
*/
var error = function(msg, stage) {
current.stage = Math.abs(stage || current.stage); // Could be negative
current.state = STATE.ERROR;
destroyEventListeners();
clearTimeout(timeout.id);
updateFeedbackList(msg);
deferred.resolve();
};
/**
* Sets the Import on the "success" status
*
* If it wasn't already, marks the stored import as "completed",
* and updates its date timestamp
*/
var success = function() {
current.state = STATE.SUCCESS;
if (CourseImport.storedImport().completed !== true) {
storeImport(true);
}
destroyEventListeners();
updateFeedbackList();
deferred.resolve();
};
/** ******** Public functions ******************************************/ /** ******** Public functions ******************************************/
var CourseImport = { CourseImport = {
/** /**
* Cancels the import and sets the Object to the error state * Cancels the import and sets the Object to the error state
......
...@@ -239,13 +239,8 @@ else: ...@@ -239,13 +239,8 @@ else:
%endif %endif
</section> </section>
</div> </div>
<%static:webpack entry="Import">
Import('${import_status_url | n, js_escaped_string}', ${library | n, dump_js_escaped_json});
</%static:webpack>
</%block> </%block>
<%block name="requirejs">
require(["js/factories/import"], function(ImportFactory) {
ImportFactory(
"${import_status_url | n, js_escaped_string}",
${library | n, dump_js_escaped_json}
);
});
</%block>
(function(define) { define(['jquery',
'use strict';
define(['jquery',
'underscore', 'underscore',
'underscore.string', 'underscore.string',
'backbone', 'backbone',
'text!common/templates/components/system-feedback.underscore'], 'text!../../../../common/templates/components/system-feedback.underscore'],
function($, _, str, Backbone, systemFeedbackTemplate) { function($, _, str, Backbone, systemFeedbackTemplate) {
var tabbable_elements = [ var tabbable_elements = [
"a[href]:not([tabindex='-1'])", "a[href]:not([tabindex='-1'])",
...@@ -197,4 +195,3 @@ ...@@ -197,4 +195,3 @@
}); });
return SystemFeedback; return SystemFeedback;
}); });
}).call(this, define || RequireJS.define);
(function(define) { define(['jquery', 'underscore', 'underscore.string', '../../../../common/js/components/views/feedback'],
'use strict';
define(['jquery', 'underscore', 'underscore.string', 'common/js/components/views/feedback'],
function($, _, str, SystemFeedbackView) { function($, _, str, SystemFeedbackView) {
var Notification = SystemFeedbackView.extend({ var Notification = SystemFeedbackView.extend({
options: $.extend({}, SystemFeedbackView.prototype.options, { options: $.extend({}, SystemFeedbackView.prototype.options, {
...@@ -30,4 +28,3 @@ ...@@ -30,4 +28,3 @@
return Notification; return Notification;
}); });
}).call(this, define || RequireJS.define);
module.exports = { module.exports = {
extends: 'eslint-config-edx', extends: 'eslint-config-edx',
root: true, root: true,
settings: {
'import/resolver': 'webpack',
},
}; };
/* globals Logger */ /* globals Logger */
import { keys } from 'edx-ui-toolkit/src/js/utils/constants'; import { keys } from 'edx-ui-toolkit/js/utils/constants';
// @TODO: Figure out how to make webpack handle default exports when libraryTarget: 'window' // @TODO: Figure out how to make webpack handle default exports when libraryTarget: 'window'
export class CourseOutline { // eslint-disable-line import/prefer-default-export export class CourseOutline { // eslint-disable-line import/prefer-default-export
......
/* globals Logger, loadFixtures */ /* globals Logger, loadFixtures */
import { keys } from 'edx-ui-toolkit/src/js/utils/constants'; import { keys } from 'edx-ui-toolkit/js/utils/constants';
import { CourseOutline } from '../CourseOutline'; import { CourseOutline } from '../CourseOutline';
......
...@@ -7,16 +7,20 @@ ...@@ -7,16 +7,20 @@
"babel-preset-env": "^1.2.1", "babel-preset-env": "^1.2.1",
"backbone": "~1.3.2", "backbone": "~1.3.2",
"backbone.paginator": "~2.0.3", "backbone.paginator": "~2.0.3",
"coffee-loader": "^0.7.3",
"coffee-script": "1.6.1", "coffee-script": "1.6.1",
"edx-pattern-library": "0.18.1", "edx-pattern-library": "0.18.1",
"edx-ui-toolkit": "1.5.2", "edx-ui-toolkit": "1.5.2",
"exports-loader": "^0.6.4",
"hls.js": "0.7.2", "hls.js": "0.7.2",
"imports-loader": "^0.7.1",
"jquery": "~2.2.0", "jquery": "~2.2.0",
"jquery-migrate": "^1.4.1", "jquery-migrate": "^1.4.1",
"jquery.scrollto": "~2.1.2", "jquery.scrollto": "~2.1.2",
"moment": "^2.15.1", "moment": "^2.15.1",
"moment-timezone": "~0.5.5", "moment-timezone": "~0.5.5",
"picturefill": "~3.0.2", "picturefill": "~3.0.2",
"raw-loader": "^0.5.1",
"requirejs": "~2.3.2", "requirejs": "~2.3.2",
"uglify-js": "2.7.0", "uglify-js": "2.7.0",
"underscore": "~1.8.3", "underscore": "~1.8.3",
......
...@@ -705,16 +705,26 @@ def execute_compile_sass(args): ...@@ -705,16 +705,26 @@ def execute_compile_sass(args):
def execute_webpack(prod, settings=None): def execute_webpack(prod, settings=None):
sh(cmd("NODE_ENV={node_env} STATIC_ROOT={static_root} $(npm bin)/webpack".format( 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", node_env="production" if prod else "development",
static_root=Env.get_django_setting("STATIC_ROOT", "lms", settings=settings) static_root_lms=Env.get_django_setting("STATIC_ROOT", "lms", settings=settings),
))) static_root_cms=Env.get_django_setting("STATIC_ROOT", "cms", settings=settings)
)
)
)
def execute_webpack_watch(settings=None): def execute_webpack_watch(settings=None):
run_background_process("STATIC_ROOT={static_root} $(npm bin)/webpack --watch --watch-poll=200".format( run_background_process(
static_root=Env.get_django_setting("STATIC_ROOT", "lms", settings=settings) "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)
)
)
def get_parsed_option(command_opts, opt_key, default=None): def get_parsed_option(command_opts, opt_key, default=None):
......
...@@ -41,11 +41,12 @@ EXPECTED_RUN_SERVER_COMMAND = ( ...@@ -41,11 +41,12 @@ EXPECTED_RUN_SERVER_COMMAND = (
EXPECTED_INDEX_COURSE_COMMAND = ( EXPECTED_INDEX_COURSE_COMMAND = (
u"python manage.py {system} --settings={settings} reindex_course --setup" u"python manage.py {system} --settings={settings} reindex_course --setup"
) )
EXPECTED_PRINT_SETTINGS_COMMAND = ( EXPECTED_PRINT_SETTINGS_COMMAND = [
u"python manage.py {system} --settings={settings} print_settings STATIC_ROOT --format=value 2>/dev/null" u"python manage.py lms --settings={settings} print_settings STATIC_ROOT --format=value 2>/dev/null",
) u"python manage.py cms --settings={settings} print_settings STATIC_ROOT --format=value 2>/dev/null"
]
EXPECTED_WEBPACK_COMMAND = ( EXPECTED_WEBPACK_COMMAND = (
u"NODE_ENV={node_env} STATIC_ROOT={static_root} $(npm bin)/webpack" u"NODE_ENV={node_env} STATIC_ROOT_LMS={static_root_lms} STATIC_ROOT_CMS={static_root_cms} $(npm bin)/webpack"
) )
...@@ -240,13 +241,11 @@ class TestPaverServerTasks(PaverTestCase): ...@@ -240,13 +241,11 @@ class TestPaverServerTasks(PaverTestCase):
expected_messages.append(u"xmodule_assets common/static/xmodule") expected_messages.append(u"xmodule_assets common/static/xmodule")
expected_messages.append(u"install npm_assets") expected_messages.append(u"install npm_assets")
expected_messages.append(EXPECTED_COFFEE_COMMAND.format(platform_root=self.platform_root)) expected_messages.append(EXPECTED_COFFEE_COMMAND.format(platform_root=self.platform_root))
expected_messages.append(EXPECTED_PRINT_SETTINGS_COMMAND.format( expected_messages.extend([c.format(settings=expected_asset_settings) for c in EXPECTED_PRINT_SETTINGS_COMMAND])
system="lms",
settings=expected_asset_settings
))
expected_messages.append(EXPECTED_WEBPACK_COMMAND.format( expected_messages.append(EXPECTED_WEBPACK_COMMAND.format(
node_env="production" if expected_asset_settings != "devstack" else "development", node_env="production" if expected_asset_settings != "devstack" else "development",
static_root=None static_root_lms=None,
static_root_cms=None
)) ))
expected_messages.extend(self.expected_sass_commands(system=system, asset_settings=expected_asset_settings)) expected_messages.extend(self.expected_sass_commands(system=system, asset_settings=expected_asset_settings))
if expected_collect_static: if expected_collect_static:
...@@ -285,10 +284,11 @@ class TestPaverServerTasks(PaverTestCase): ...@@ -285,10 +284,11 @@ class TestPaverServerTasks(PaverTestCase):
expected_messages.append(u"xmodule_assets common/static/xmodule") expected_messages.append(u"xmodule_assets common/static/xmodule")
expected_messages.append(u"install npm_assets") expected_messages.append(u"install npm_assets")
expected_messages.append(EXPECTED_COFFEE_COMMAND.format(platform_root=self.platform_root)) expected_messages.append(EXPECTED_COFFEE_COMMAND.format(platform_root=self.platform_root))
expected_messages.append(EXPECTED_PRINT_SETTINGS_COMMAND.format(system="lms", settings=expected_asset_settings)) expected_messages.extend([c.format(settings=expected_asset_settings) for c in EXPECTED_PRINT_SETTINGS_COMMAND])
expected_messages.append(EXPECTED_WEBPACK_COMMAND.format( expected_messages.append(EXPECTED_WEBPACK_COMMAND.format(
node_env="production" if expected_asset_settings != "devstack" else "development", node_env="production" if expected_asset_settings != "devstack" else "development",
static_root=None static_root_lms=None,
static_root_cms=None
)) ))
expected_messages.extend(self.expected_sass_commands(asset_settings=expected_asset_settings)) expected_messages.extend(self.expected_sass_commands(asset_settings=expected_asset_settings))
if expected_collect_static: if expected_collect_static:
......
...@@ -12,7 +12,8 @@ var wpconfig = { ...@@ -12,7 +12,8 @@ var wpconfig = {
context: __dirname, context: __dirname,
entry: { entry: {
CourseOutline: './openedx/features/course_experience/static/course_experience/js/CourseOutline.js' CourseOutline: './openedx/features/course_experience/static/course_experience/js/CourseOutline.js',
Import: './cms/static/js/features/import/factories/import.js'
}, },
output: { output: {
...@@ -21,7 +22,7 @@ var wpconfig = { ...@@ -21,7 +22,7 @@ var wpconfig = {
libraryTarget: 'window' libraryTarget: 'window'
}, },
devtool: isProd ? false : 'eval-source-map', devtool: isProd ? false : 'source-map',
plugins: [ plugins: [
new webpack.NoEmitOnErrorsPlugin(), new webpack.NoEmitOnErrorsPlugin(),
...@@ -33,8 +34,18 @@ var wpconfig = { ...@@ -33,8 +34,18 @@ var wpconfig = {
debug: !isProd debug: !isProd
}), }),
new BundleTracker({ new BundleTracker({
path: process.env.STATIC_ROOT, path: process.env.STATIC_ROOT_CMS,
filename: 'webpack-stats.json' filename: 'webpack-stats.json'
}),
new BundleTracker({
path: process.env.STATIC_ROOT_LMS,
filename: 'webpack-stats.json'
}),
new webpack.ProvidePlugin({
_: 'underscore',
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery'
}) })
], ],
...@@ -44,12 +55,51 @@ var wpconfig = { ...@@ -44,12 +55,51 @@ var wpconfig = {
test: /\.js$/, test: /\.js$/,
exclude: /node_modules/, exclude: /node_modules/,
use: 'babel-loader' use: 'babel-loader'
},
{
test: /\.coffee$/,
exclude: /node_modules/,
use: 'coffee-loader'
},
{
test: /\.underscore$/,
use: 'raw-loader'
},
{
// This file is used by both RequireJS and Webpack and depends on window globals
// This is a dirty hack and shouldn't be replicated for other files.
test: path.resolve(__dirname, 'cms/static/cms/js/main.js'),
use: {
loader: 'imports-loader',
options: {
AjaxPrefix: 'exports-loader?this.AjaxPrefix!../../../../common/static/coffee/src/ajax_prefix.coffee'
}
}
} }
] ]
}, },
resolve: { resolve: {
extensions: ['.js', '.json'] extensions: ['.js', '.json', '.coffee'],
alias: {
'edx-ui-toolkit': 'edx-ui-toolkit/src/', // @TODO: some paths in toolkit are not valid relative paths
'jquery.ui': 'jQuery-File-Upload/js/vendor/jquery.ui.widget.js',
jquery: 'jquery/src/jquery' // Use the non-dist form of jQuery for better debugging + optimization
},
modules: [
'node_modules',
'common/static/js/vendor/'
]
},
resolveLoader: {
alias: {
text: 'raw-loader' // Compatibility with RequireJSText's text! loader, uses raw-loader under the hood
}
},
externals: {
gettext: 'gettext'
}, },
watchOptions: { watchOptions: {
...@@ -59,7 +109,7 @@ var wpconfig = { ...@@ -59,7 +109,7 @@ var wpconfig = {
if (isProd) { if (isProd) {
wpconfig.plugins = wpconfig.plugins.concat([ wpconfig.plugins = wpconfig.plugins.concat([
new webpack.LoaderOptionsPlugin({ new webpack.LoaderOptionsPlugin({ // This may not be needed; legacy option for loaders written for webpack 1
minimize: true minimize: true
}), }),
new webpack.optimize.UglifyJsPlugin() new webpack.optimize.UglifyJsPlugin()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment