Commit fdd5bf23 by Clinton Blackburn

Installed Webpack

ECOM-5776
parent e251012e
...@@ -89,3 +89,5 @@ course_discovery/media/ ...@@ -89,3 +89,5 @@ course_discovery/media/
course_discovery/static/bower_components/ course_discovery/static/bower_components/
docs/_build/ docs/_build/
node_modules/ node_modules/
course_discovery/static/bundles/
webpack-stats.json
.DEFAULT_GOAL := test .DEFAULT_GOAL := test
NODE_BIN=./node_modules/.bin NODE_BIN=$(CURDIR)/node_modules/.bin
.PHONY: accept clean clean_static compile_translations detect_changed_source_translations dummy_translations extract_translations \ .PHONY: accept clean clean_static compile_translations detect_changed_source_translations dummy_translations extract_translations \
fake_translations help html_coverage migrate open-devstack production-requirements pull_translations quality requirements.js \ fake_translations help html_coverage migrate open-devstack production-requirements pull_translations quality requirements.js \
requirements start-devstack static stop-devstack test validate validate_translations docs requirements start-devstack static stop-devstack test validate validate_translations docs static.dev static.watch
include .travis/docker.mk include .travis/docker.mk
...@@ -13,11 +13,18 @@ help: ## Display this help message ...@@ -13,11 +13,18 @@ help: ## Display this help message
@perl -nle'print $& if m{^[\.a-zA-Z_-]+:.*?## .*$$}' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m %-25s\033[0m %s\n", $$1, $$2}' @perl -nle'print $& if m{^[\.a-zA-Z_-]+:.*?## .*$$}' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m %-25s\033[0m %s\n", $$1, $$2}'
static: ## Gather all static assets for production static: ## Gather all static assets for production
$(NODE_BIN)/webpack --config webpack.config.js --display-error-details --progress --optimize-minimize
python manage.py collectstatic --noinput python manage.py collectstatic --noinput
python manage.py compress -v3 --force python manage.py compress -v3 --force
static.dev:
$(NODE_BIN)/webpack --config webpack.config.js --display-error-details --progress
static.watch:
$(NODE_BIN)/webpack --config webpack.config.js --display-error-details --progress --watch
clean_static: ## Remove all generated static files clean_static: ## Remove all generated static files
rm -rf course_discovery/assets/ course_discovery/static/build/ rm -rf course_discovery/assets/ course_discovery/static/bundles/
clean: ## Delete generated byte code and coverage reports clean: ## Delete generated byte code and coverage reports
find . -name '*.pyc' -delete find . -name '*.pyc' -delete
......
...@@ -5,8 +5,8 @@ from os.path import abspath, dirname, join ...@@ -5,8 +5,8 @@ from os.path import abspath, dirname, join
from sys import path from sys import path
here = lambda *x: join(abspath(dirname(__file__)), *x) here = lambda *x: join(abspath(dirname(__file__)), *x)
PROJECT_ROOT = here("..") PROJECT_ROOT = here('..')
root = lambda *x: join(abspath(PROJECT_ROOT), *x) root = lambda *x: abspath(join(abspath(PROJECT_ROOT), *x))
path.append(root('apps')) path.append(root('apps'))
...@@ -52,6 +52,7 @@ THIRD_PARTY_APPS = [ ...@@ -52,6 +52,7 @@ THIRD_PARTY_APPS = [
'taggit_autosuggest', 'taggit_autosuggest',
'taggit_serializer', 'taggit_serializer',
'solo', 'solo',
'webpack_loader',
] ]
PROJECT_APPS = [ PROJECT_APPS = [
...@@ -151,14 +152,12 @@ STATICFILES_FINDERS = ( ...@@ -151,14 +152,12 @@ STATICFILES_FINDERS = (
'compressor.finders.CompressorFinder', 'compressor.finders.CompressorFinder',
) )
COMPRESS_PRECOMPILERS = ( WEBPACK_LOADER = {
('text/x-scss', 'django_libsass.SassCompiler'), 'DEFAULT': {
) 'BUNDLE_DIR_NAME': 'bundles/',
'STATS_FILE': root('..', 'webpack-stats.json'),
# Minify CSS }
COMPRESS_CSS_FILTERS = [ }
'compressor.filters.css_default.CssAbsoluteFilter',
]
# TEMPLATE CONFIGURATION # TEMPLATE CONFIGURATION
# See: https://docs.djangoproject.com/en/1.8/ref/settings/#templates # See: https://docs.djangoproject.com/en/1.8/ref/settings/#templates
......
require('bootstrap-sass');
require('datatables.net-bs')();
var $alertNoResults, $alertQueryInvalid, $query, $table; var $alertNoResults, $alertQueryInvalid, $query, $table;
function processApiResponse(response) { function processApiResponse(response) {
...@@ -23,7 +26,7 @@ function getApiResponse(url) { ...@@ -23,7 +26,7 @@ function getApiResponse(url) {
* Form submission handler. Sends the query to the server and displays the list of courses.\ * Form submission handler. Sends the query to the server and displays the list of courses.\
*/ */
function onSubmit(e) { function onSubmit(e) {
var url = '/api/v1/course_runs/?q=' + encodeURIComponent($query.val()); var url = '/api/v1/course_runs/?limit=100&q=' + encodeURIComponent($query.val());
e.preventDefault(); e.preventDefault();
...@@ -83,6 +86,7 @@ $(document).ready(function () { ...@@ -83,6 +86,7 @@ $(document).ready(function () {
$table = $('#courses').DataTable({ $table = $('#courses').DataTable({
info: true, info: true,
paging: true, paging: true,
autoWidth: true,
columns: [ columns: [
{ {
title: 'Course Run Key', title: 'Course Run Key',
......
...@@ -15,13 +15,13 @@ ...@@ -15,13 +15,13 @@
// ------------------------------ // ------------------------------
// #LIB // #LIB
// ------------------------------ // ------------------------------
@import "lib"; @import 'lib';
@import '../bower_components/edx-pattern-library/pattern-library/sass/edx-pattern-library'; @import '~edx-pattern-library/pattern-library/sass/edx-pattern-library';
// ------------------------------ // ------------------------------
// #EXTENSIONS // #EXTENSIONS
// ------------------------------ // ------------------------------
@import "base"; @import 'base';
@import 'publisher/color-palette'; @import 'publisher/color-palette';
@import "publisher/lib"; @import "publisher/lib";
@import 'publisher/layout'; @import 'publisher/layout';
......
...@@ -6,4 +6,4 @@ ...@@ -6,4 +6,4 @@
// ------------------------------ // ------------------------------
// #VARIABLES // #VARIABLES
// ------------------------------ // ------------------------------
$pattern-library-path: '../bower_components/edx-pattern-library/pattern-library' !default; $pattern-library-path: '~edx-pattern-library/pattern-library' !default;
...@@ -2,4 +2,4 @@ ...@@ -2,4 +2,4 @@
// edX Course Discovery: Third Party Libraries // edX Course Discovery: Third Party Libraries
// About: third party libraries and dependencies import // About: third party libraries and dependencies import
@import '../bower_components/breakpoint-sass/stylesheets/breakpoint'; @import '~breakpoint-sass/stylesheets/breakpoint';
...@@ -16,4 +16,4 @@ $layout-direction: ltr; ...@@ -16,4 +16,4 @@ $layout-direction: ltr;
// ---------------------------- // ----------------------------
// #LIB // #LIB
// ---------------------------- // ----------------------------
@import '../bower_components/bi-app-sass/bi-app/bi-app-ltr'; @import '~bi-app-sass/bi-app/bi-app-ltr';
...@@ -16,4 +16,4 @@ $layout-direction: rtl; ...@@ -16,4 +16,4 @@ $layout-direction: rtl;
// ---------------------------- // ----------------------------
// #LIB // #LIB
// ---------------------------- // ----------------------------
@import '../bower_components/bi-app-sass/bi-app/bi-app-rtl'; @import '~bi-app-sass/bi-app/bi-app-rtl';
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
// About: Main left-to-right Sass compile for the edX Course Discovery styling. // About: Main left-to-right Sass compile for the edX Course Discovery styling.
@import '../bower_components/bourbon/app/assets/stylesheets/bourbon'; @import '~bourbon/app/assets/stylesheets/bourbon';
// ------------------------------ // ------------------------------
// #CONFIG - layout direction // #CONFIG - layout direction
// ------------------------------ // ------------------------------
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
// About: Main left-to-right Sass compile for the edX Course Discovery styling. // About: Main left-to-right Sass compile for the edX Course Discovery styling.
@import '../bower_components/bourbon/app/assets/stylesheets/bourbon'; @import '~bourbon/app/assets/stylesheets/bourbon';
// ------------------------------ // ------------------------------
// #CONFIG - layout direction // #CONFIG - layout direction
// ------------------------------ // ------------------------------
......
$icon-font-path: '~bootstrap-sass/assets/fonts/bootstrap/';
@import '~bootstrap-sass/assets/stylesheets/bootstrap';
@import '~datatables.net-bs/css/dataTables.bootstrap.css';
#queryForm { #queryForm {
margin: 25px 0; margin: 25px 0;
} }
.intro, .intro,
.examples, .examples,
.fields, .fields,
.preview { .preview {
margin-bottom: 30px; margin-bottom: 30px;
} }
{# Base template for edX-specific pages. #} {# Base template for edX-specific pages. #}
{% load compress %} {% load render_bundle from webpack_loader %}
{% load static %}
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head lang="{{ language_code }}"> <head lang="{{ language_code }}">
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}{% endblock title %} | {{ platform_name }}</title> <title>{% block title %}{% endblock title %} | {{ platform_name }}</title>
{% compress css %} {% block css %}
{% block stylesheets %} {% if language_bidi %}
{% if language_bidi %} {% render_bundle 'base.style-rtl' 'css' %}
<link rel="stylesheet" href="{% static 'sass/main-rtl.scss' %}" type="text/x-scss"> {% else %}
{% else %} {% render_bundle 'base.style' 'css' %}
<link rel="stylesheet" href="{% static 'sass/main-ltr.scss' %}" type="text/x-scss"> {% endif %}
{% endif %} {% endblock %}
{% endblock %}
{% endcompress %}
</head> </head>
<body> <body>
{% block content %}{% endblock content %} {% block content %}{% endblock content %}
{% block js %} {% block js %}
<script src="{% url 'javascript-catalog' %}"></script> <script src="{% url 'javascript-catalog' %}"></script>
{% endblock %} {% endblock %}
</body> </body>
</html> </html>
{% load static %} {% extends 'base.html' %}
{% load render_bundle from webpack_loader %}
<!DOCTYPE html> {% block title %}
<html lang="en"> Query Preview
<head> {% endblock title %}
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Query Preview | Course Discovery</title> {% block css %}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" {# NOTE: We are NOT loading base.scss to avoid loading the edX Pattern Library. #}
integrity="sha256-7s5uDGW3AHqw6xtJmNNtr+OBRJUlgkNJEo78P4b0yRw= sha512-nNo+yCHEyn0smMxSswnf/OnX6/KwJuZTlNZBjauKhTK0c+zT+q5JOCx0UFhXQ6rJR9jg6Es8gPuD2uZcYDLqSw==" {% render_bundle 'query-preview.style' 'css' %}
crossorigin="anonymous"> {% endblock %}
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.10/css/dataTables.bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="{% static 'css/catalog-preview.css' %}">
</head>
<body>
<div class="container">
<h1 class="page-header">Query Preview</h1>
<div class="intro"> {% block js %}
<div class="alert alert-warning" role="alert"> {{ block.super }}
Please take a moment to review the <a {% render_bundle 'query-preview' 'js' %}
href="https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html#query-string-syntax" {% endblock %}
target="_blank" class="alert-link">Elasticsearch query string syntax</a>.
</div>
<p>This page is a demonstration of the query language that will power dynamic course catalogs use for affiliates
and coupons.</p>
</div>
<div class="fields"> {% block content %}
<h3>Fields</h3> <div class="container">
<p>A number of fields can be used to search for courses. A complete list is below.</p> <h1 class="page-header">Query Preview</h1>
<p></p>
<table class="table table-striped table-bordered" id="fields"> <div class="intro">
<thead> <div class="alert alert-warning" role="alert">
<tr> Please take a moment to review the <a
<th>Name</th> href="https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html#query-string-syntax"
<th>Description</th> target="_blank" class="alert-link">Elasticsearch query string syntax</a>.
</tr> </div>
</thead> <p>This page is a demonstration of the query language that will power dynamic course catalogs use for affiliates
</table> and coupons.</p>
</div>
<div class="examples">
<h3>Example Queries</h3>
<div class="alert alert-info" role="alert">
Click an example to populate the query field with the example query.
</div> </div>
<table class="table table-striped table-bordered"> <div class="fields">
<thead> <h3>Fields</h3>
<tr> <p>A number of fields can be used to search for courses. A complete list is below.</p>
<th>Description</th> <p></p>
<th>Query</th>
</tr>
</thead>
<tbody>
<tr>
<td>Courses belonging to a specific organization</td>
<td><a class="example">org:(MITx OR HarvardX)</a></td>
</tr>
<tr>
<td>Courses NOT belonging to a specific organization</td>
<td><a class="example">org:(-MITx OR -HarvardX)</a></td>
</tr>
<tr>
<td>Courses starting in a specific time period</td>
<td><a class="example">start:[2016-01-01 TO 2016-12-31]</a></td>
</tr>
<tr>
<td>All runs of a particular course</td>
<td><a class="example">number:6.002x*</a></td>
</tr>
</tbody>
</table>
</div>
<div class="preview">
<h3>Preview</h3>
<form id="queryForm" class="form-horizontal">
<div class="input-group">
<input id="query" type="text" class="form-control" placeholder="Query">
<span class="input-group-btn">
<button class="btn btn-primary" type="submit">Search</button>
</span>
</div>
</form>
<div class="alert alert-warning alert-dismissible hidden" role="alert" id="alertNoResults"> <table class="table table-striped table-bordered" id="fields">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span <thead>
aria-hidden="true">&times;</span></button> <tr>
The query returned no results. <th>Name</th>
<th>Description</th>
</tr>
</thead>
</table>
</div> </div>
<div class="alert alert-danger alert-dismissible hidden" role="alert" id="alertQueryInvalid"> <div class="examples">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span <h3>Example Queries</h3>
aria-hidden="true">&times;</span></button> <div class="alert alert-info" role="alert">
The query is invalid. Click an example to populate the query field with the example query.
</div> </div>
<hr> <table class="table table-striped table-bordered">
<div class="results">
<table id="courses" class="table table-striped table-bordered" cellspacing="0">
<thead> <thead>
<tr> <tr>
<th>Course Run Key</th> <th>Description</th>
<th>Name</th> <th>Query</th>
</tr> </tr>
</thead> </thead>
<tbody>
<tr>
<td>Courses belonging to a specific organization</td>
<td><a class="example">org:(MITx OR HarvardX)</a></td>
</tr>
<tr>
<td>Courses NOT belonging to a specific organization</td>
<td><a class="example">org:(-MITx OR -HarvardX)</a></td>
</tr>
<tr>
<td>Courses starting in a specific time period</td>
<td><a class="example">start:[2016-01-01 TO 2016-12-31]</a></td>
</tr>
<tr>
<td>All runs of a particular course</td>
<td><a class="example">number:6.002x*</a></td>
</tr>
</tbody>
</table> </table>
</div> </div>
</div>
</div>
<script type="text/javascript" language="javascript" src="//code.jquery.com/jquery-3.2.1.min.js"></script> <div class="preview">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" <h3>Preview</h3>
integrity="sha256-KXn5puMvxCw+dAYznun+drMdG1IFl3agK0p/pqT9KAo= sha512-2e8qq0ETcfWRI4HJBzQiA3UoyFk6tbNyG+qSaIBZLyW9Xf3sWZHN/lxe9fTh1U45DpPf07yj94KsUHHWe4Yk1A==" <form id="queryForm" class="form-horizontal">
crossorigin="anonymous"></script> <div class="input-group">
<script type="text/javascript" language="javascript" <input id="query" type="text" class="form-control" placeholder="Query">
src="https://cdn.datatables.net/1.10.10/js/jquery.dataTables.min.js"></script> <span class="input-group-btn">
<script type="text/javascript" language="javascript" <button class="btn btn-primary" type="submit">Search</button>
src="https://cdn.datatables.net/1.10.10/js/dataTables.bootstrap.min.js"></script> </span>
</div>
</form>
<script src="{% static 'js/catalog-preview.js' %}"></script> <div class="alert alert-warning alert-dismissible hidden" role="alert" id="alertNoResults">
</body> <button type="button" class="close" data-dismiss="alert" aria-label="Close">
</html> <span aria-hidden="true">&times;</span>
</button>
The query returned no results.
</div>
<div class="alert alert-danger alert-dismissible hidden" role="alert" id="alertQueryInvalid">
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
The query is invalid.
</div>
<hr>
<div class="results">
<table id="courses" class="table table-striped table-bordered" cellspacing="0">
<thead>
<tr>
<th style="width: 35%">Course Run Key</th>
<th>Name</th>
</tr>
</thead>
</table>
</div>
</div>
</div>
{% endblock %}
...@@ -6,7 +6,22 @@ ...@@ -6,7 +6,22 @@
"url": "git://github.com/edx/course-discovery" "url": "git://github.com/edx/course-discovery"
}, },
"dependencies": { "dependencies": {
"bower": "^1.8.0" "bootstrap-sass": "^3.3.7",
"bower": "^1.8.0",
"css-loader": "^0.28.4",
"datatables.net": "^1.10.15",
"datatables.net-bs": "^1.10.15",
"edx-pattern-library": "^0.18.1",
"extract-text-webpack-plugin": "^3.0.0",
"file-loader": "^0.11.2",
"imports-loader": "^0.7.1",
"jquery": "^3.2.1",
"node-sass": "^4.5.3",
"sass-loader": "^6.0.6",
"style-loader": "^0.18.2",
"url-loader": "^0.5.9",
"webpack": "^3.3.0",
"webpack-bundle-tracker": "0.2.0"
}, },
"devDependencies": { "devDependencies": {
"gulp": "^3.9.1", "gulp": "^3.9.1",
......
...@@ -11,7 +11,6 @@ django-filter==1.0.4 ...@@ -11,7 +11,6 @@ django-filter==1.0.4
django-fsm==2.6.0 django-fsm==2.6.0
django-guardian==1.4.8 django-guardian==1.4.8
django-haystack==2.5.0 django-haystack==2.5.0
django-libsass==0.7
django-simple-history==1.8.1 django-simple-history==1.8.1
django-solo==1.1.2 django-solo==1.1.2
django-sortedm2m==1.4.0 django-sortedm2m==1.4.0
...@@ -21,6 +20,7 @@ django-taggit==0.22.1 ...@@ -21,6 +20,7 @@ django-taggit==0.22.1
django-taggit-autosuggest==0.3.0 django-taggit-autosuggest==0.3.0
django-taggit-serializer==0.1.5 django-taggit-serializer==0.1.5
django-waffle==0.11.1 django-waffle==0.11.1
django-webpack-loader==0.5.0
djangorestframework==3.6.3 djangorestframework==3.6.3
djangorestframework-csv==1.4.1 djangorestframework-csv==1.4.1
djangorestframework-jwt==1.8.0 djangorestframework-jwt==1.8.0
......
var BundleTracker = require('webpack-bundle-tracker'),
ExtractTextPlugin = require('extract-text-webpack-plugin'),
path = require('path'),
webpack = require('webpack'),
loaders = [
{
loader: 'css-loader',
options: {
minimize: true
}
},
{
loader: 'sass-loader',
options: {
includePaths: [path.resolve('./sass/')]
}
}
],
context = path.join(__dirname, 'course_discovery/static');
module.exports = {
context: context,
entry: {
'base.style': './sass/main-ltr.scss',
'base.style-rtl': './sass/main-rtl.scss',
'query-preview': './js/query-preview.js',
'query-preview.style': './sass/query-preview.scss'
},
output: {
path: path.join(context, './bundles/'),
filename: '[name]-[hash].js'
},
plugins: [
new BundleTracker({filename: './webpack-stats.json'}),
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery'
}),
new ExtractTextPlugin('[name]-[hash].css')
],
module: {
rules: [
{
test: /\.s?css$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: loaders
})
},
{
test: /\.woff2?$/,
// Inline small woff files and output them below font
use: [{
loader: 'url-loader',
options: {
name: 'font/[name]-[hash].[ext]',
limit: 5000,
mimetype: 'application/font-woff'
}
}]
},
{
test: /\.(ttf|eot|svg)$/,
use: [{
loader: 'file-loader',
options: {
name: 'font/[name]-[hash].[ext]'
}
}]
},
{
test: require.resolve('datatables.net'),
use: 'imports-loader?define=>false'
},
{
test: require.resolve('datatables.net-bs'),
use: 'imports-loader?define=>false'
}
]
},
resolve: {
modules: ['node_modules'],
extensions: ['.css', '.js', '.scss']
}
};
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