diff --git a/.gitignore b/.gitignore index 3367cdfe57facc5bbfc21b25201f778fba23d8cf..08d3037e0fd63c7357449e3bb137fb75f2217754 100644 --- a/.gitignore +++ b/.gitignore @@ -2,12 +2,18 @@ __pycache__ *.json +*.log *~ +# Package managers venv* +node_modules/ +*webpack-stats.json + .python-version + media/temp SCIPOST_JOURNALS @@ -16,4 +22,4 @@ UPLOADS docs/_build local_files -whoosh_index \ No newline at end of file +whoosh_index diff --git a/README.md b/README.md index 68c8f64bb480dd555f384ce3796a0a3d6af0be53..9bb43e0733105923388167cd35fb02d0892ddd43 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ The complete scientific publication portal ## Dependencies SciPost is written in Python 3.5 using Django and requires PostgreSQL 9.3 or -higher. Python dependencies are listed in `requirements.txt`. +higher. Python dependencies are listed in `requirements.txt`. Frontend dependencies are managed by [NPM](https://www.npmjs.com/) in package.json. ## Getting started @@ -28,6 +28,27 @@ Now install dependencies: (scipostenv) $ pip install -r requirements.txt ``` +### Frontend dependencies +[NPM](https://www.npmjs.com/) will take care of frontend dependencies. To install all packages now run: + +```shell +(scipostenv) $ npm install +``` + +### Module bundler +[Webpack](http://webpack.github.io/docs/what-is-webpack.html) takes care of assets in the `scipost/static/scipost/assets` folder. To (re)compile all assets, simply run: + +```shell +(scipostenv) $ npm run webpack +``` + +While editing assets, it is helpfull to put webpack in _watch_ mode. This will recompile your assets every time you edit them. To do so, instead of the above command, run: + +```shell +(scipostenv) $ npm run webpack-live +``` + + ### Host-specific settings In this project, host-specific settings are defined in the `scipost-host-settings.json` file in the directory *above* the project root. The structure is as follows: diff --git a/SciPost_v1/settings.py b/SciPost_v1/settings.py index 66601f8063a94a36a6fb7b0024f3d14241da9ae5..e29c39cd4a59cddf46b5cfce84a26ae00f24cd1e 100644 --- a/SciPost_v1/settings.py +++ b/SciPost_v1/settings.py @@ -80,6 +80,7 @@ INSTALLED_APPS = ( 'scipost', 'submissions', 'theses', + 'webpack_loader' ) HAYSTACK_CONNECTIONS = { @@ -175,6 +176,21 @@ USE_TZ = True STATIC_URL = host_settings["STATIC_URL"] STATIC_ROOT = host_settings["STATIC_ROOT"] +STATICFILES_DIRS = ( + os.path.join(BASE_DIR, 'static'), +) + +# Webpack handling the static bundles +WEBPACK_LOADER = { + 'DEFAULT': { + 'CACHE': not DEBUG, + 'BUNDLE_DIR_NAME': 'bundles/', + 'STATS_FILE': os.path.join(BASE_DIR, 'webpack-stats.json'), + 'POLL_INTERVAL': 0.1, + 'TIMEOUT': None, + 'IGNORE': ['.+\.hot-update.js', '.+\.map'] + } +} # Email EMAIL_BACKEND = host_settings["EMAIL_BACKEND"] diff --git a/requirements.txt b/requirements.txt index 896a004561e886d51cf0dd50fda51b359dd34b95..a68b81195e9b923cdab7a7310edd8ff9a28ae769 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,6 +10,7 @@ django-mathjax==0.0.5 django-mptt==0.8.6 django-simple-captcha==0.5.3 django-sphinxdoc==1.5.1 +django-webpack-loader==0.4.1 djangorestframework==3.5.3 docutils==0.12 feedparser==5.2.1 diff --git a/scipost/static/scipost/assets/css/style.css b/scipost/static/scipost/assets/css/style.css new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/scipost/templates/scipost/base.html b/scipost/templates/scipost/base.html index 23a60758b0fdf262600e580d527bc61a30306e2e..ace0fe23bc2cb14db9e7b57de194ccb879fec9e1 100644 --- a/scipost/templates/scipost/base.html +++ b/scipost/templates/scipost/base.html @@ -1,9 +1,13 @@ +{% load render_bundle from webpack_loader %} + <!DOCTYPE html> <html lang="en"> <head> {% load staticfiles %} <link rel="stylesheet" type="text/css" href="{% static 'scipost/SciPost.css' %}" /> + {% render_bundle 'main' 'css' %} + <link rel="shortcut icon" href="{% static 'scipost/images/scipost_favicon.png' %}"/> <script src="https://code.jquery.com/jquery-2.2.0.min.js"></script> @@ -34,6 +38,8 @@ {% endblock content %} {% include 'scipost/footer.html' %} + + {% render_bundle 'main' 'js' %} </body> </html> diff --git a/static/bundles/css/main-74c70b907a6530bfb5dd.css b/static/bundles/css/main-74c70b907a6530bfb5dd.css new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/static/bundles/js/main-74c70b907a6530bfb5dd.js b/static/bundles/js/main-74c70b907a6530bfb5dd.js new file mode 100644 index 0000000000000000000000000000000000000000..e99d5573e922460823d91e4481531580de97e891 --- /dev/null +++ b/static/bundles/js/main-74c70b907a6530bfb5dd.js @@ -0,0 +1,57 @@ +/******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; + +/******/ // The require function +/******/ function __webpack_require__(moduleId) { + +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) +/******/ return installedModules[moduleId].exports; + +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ exports: {}, +/******/ id: moduleId, +/******/ loaded: false +/******/ }; + +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); + +/******/ // Flag the module as loaded +/******/ module.loaded = true; + +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } + + +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; + +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; + +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = "/static/bundles/"; + +/******/ // Load entry module and return exports +/******/ return __webpack_require__(0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ function(module, exports, __webpack_require__) { + + module.exports = __webpack_require__(1); + + +/***/ }, +/* 1 */ +/***/ function(module, exports) { + + // removed by extract-text-webpack-plugin + +/***/ } +/******/ ]); \ No newline at end of file diff --git a/webpack.config.js b/webpack.config.js new file mode 100644 index 0000000000000000000000000000000000000000..57789e0dee28a59ad704306e7762c469cfd316d6 --- /dev/null +++ b/webpack.config.js @@ -0,0 +1,40 @@ +var BundleTracker = require('webpack-bundle-tracker'); +var CleanWebpackPlugin = require('clean-webpack-plugin'); +var ExtractTextPlugin = require("extract-text-webpack-plugin"); +var glob = require("glob"); +var path_bundles = __dirname + '/static/bundles/'; + +module.exports = { + context: __dirname, + entry: { + main: glob.sync("./scipost/static/scipost/assets/css/*.css") + }, + output: { + path: path_bundles, + publicPath: '/static/bundles/', + filename: "js/[name]-[hash].js", + }, + module: { + loaders: [ + { + test: /\.css$/, + loader: ExtractTextPlugin.extract("style-loader", "css-loader") + }, + // Optionally extract less files (yeay!) + { + test: /\.less$/, + loader: ExtractTextPlugin.extract("style-loader", "css-loader!less-loader") + } + ] + }, + plugins: [ + new BundleTracker({filename: './webpack-stats.json'}), + new ExtractTextPlugin('css/[name]-[hash].css'), + new CleanWebpackPlugin(['css', 'js'], { + root: path_bundles, + verbose: true, + dry: false, + exclude: [] + }) + ] +}