Commit 25da372c authored by Florent Chehab's avatar Florent Chehab
Browse files

Hot Module reloading (frontend) operationnal

parent 04c716cf
Pipeline #34817 failed with stages
in 3 minutes and 19 seconds
...@@ -18,8 +18,27 @@ import sys ...@@ -18,8 +18,27 @@ import sys
# Build paths inside the project like this: os.path.join(BASE_DIR, ...) # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = dirname(dirname(dirname(os.path.abspath(__file__)))) BASE_DIR = dirname(dirname(dirname(os.path.abspath(__file__))))
# Application definition ##########
# Webpack loader related
WEBPACK_LOADER = {
"DEFAULT": {
"BUNDLE_DIR_NAME": "frontend_app/bundles/",
"STATS_FILE": os.path.join(BASE_DIR, "../frontend/webpack-stats.json"),
}
}
STATICFILES_DIRS = (
os.path.join(
BASE_DIR, "static/frontend_app/bundles/"
), # We do this so that django's collectstatic copies or our bundles to the STATIC_ROOT or syncs them to whatever storage we use.
)
# End of webpack loader related
###########
# Application definition
INSTALLED_APPS = [ INSTALLED_APPS = [
"django.contrib.admin", "django.contrib.admin",
"django.contrib.auth", "django.contrib.auth",
...@@ -34,6 +53,7 @@ INSTALLED_APPS = [ ...@@ -34,6 +53,7 @@ INSTALLED_APPS = [
"rest_framework.authtoken", "rest_framework.authtoken",
"backend_app", "backend_app",
"frontend_app", "frontend_app",
"webpack_loader",
] ]
MIDDLEWARE = [ MIDDLEWARE = [
......
{% load render_bundle from webpack_loader %}
<!DOCTYPE html> <!DOCTYPE html>
<html style="font-size:14"> <html style="font-size:14">
...@@ -20,9 +21,12 @@ ...@@ -20,9 +21,12 @@
<!-- <script src="{% static '/frontend_app/react-dist/react.production.min.js' %}"></script> --> <!-- <script src="{% static '/frontend_app/react-dist/react.production.min.js' %}"></script> -->
<link rel="stylesheet" href="{% static '/frontend_app/leaflet-dist/leaflet.css' %}"/> <link rel="stylesheet" href="{% static '/frontend_app/leaflet-dist/leaflet.css' %}"/>
<link rel="stylesheet" href="{% static '/frontend_app/custom_leaflet.css' %}"/> <link rel="stylesheet" href="{% static '/frontend_app/custom_leaflet.css' %}"/>
<link rel="stylesheet" href="{% static '/frontend_app/main.css' %}"/> <!-- <link rel="stylesheet" href="{% static '/frontend_app/main.css' %}"/> -->
<!-- <script src="{% static '/frontend_app/leaflet-dist/leaflet.js' %}"></script> --> <!-- <script src="{% static '/frontend_app/leaflet-dist/leaflet.js' %}"></script> -->
<!-- <script src="{% static '/frontend_app/react-leaflet-dist/react-leaflet.js' %}"></script> --> <!-- <script src="{% static '/frontend_app/react-leaflet-dist/react-leaflet.js' %}"></script> -->
<script src="{% static '/frontend_app/main.js' %}"></script> <!-- <script src="{% static '/frontend_app/main.js' %}"></script> -->
{% render_bundle 'main' %}
{% render_bundle 'vendor' %}
<noscript>Cette application nécessite Javascript... Merci de l'activer ou d'utiliser un navigateur approprié.</noscript> <noscript>Cette application nécessite Javascript... Merci de l'activer ou d'utiliser un navigateur approprié.</noscript>
</html> </html>
...@@ -17,3 +17,4 @@ pyyaml ...@@ -17,3 +17,4 @@ pyyaml
git+https://github.com/FloChehab/django-extensions.git@30c1a807aeb985739358d70907496e98d1857abb#egg=django-extensions git+https://github.com/FloChehab/django-extensions.git@30c1a807aeb985739358d70907496e98d1857abb#egg=django-extensions
uwsgi uwsgi
dotmap dotmap
django-webpack-loader==0.6.0
\ No newline at end of file
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
"stage-1" "stage-1"
], ],
"plugins": [ "plugins": [
"transform-class-properties" "transform-class-properties",
"react-hot-loader/babel"
] ]
} }
\ No newline at end of file
node_modules node_modules
webpack-stats.json
\ No newline at end of file
main.js
main.css
fonts/ fonts/
stats.json stats.json
bundles
\ No newline at end of file
This diff is collapsed.
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
"scripts": { "scripts": {
"lint": "eslint \"./src/**/*.js\"", "lint": "eslint \"./src/**/*.js\"",
"lint-fix": "eslint \"./src/**/*.js\" --fix", "lint-fix": "eslint \"./src/**/*.js\" --fix",
"dev": "webpack --mode development", "dev": "node server.js",
"build": "webpack --mode production", "build": "webpack --mode production",
"test": "echo \"Error: no test specified\" && exit 1", "test": "echo \"Error: no test specified\" && exit 1",
"stats": "webpack --profile --json > frontend/static/frontend/stats.json", "stats": "webpack --profile --json > frontend/static/frontend/stats.json",
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
"@material-ui/core": "^3.1.0", "@material-ui/core": "^3.1.0",
"@material-ui/icons": "^2.0.3", "@material-ui/icons": "^2.0.3",
"@material-ui/lab": "^3.0.0-alpha.16", "@material-ui/lab": "^3.0.0-alpha.16",
"babel-polyfill": "^6.26.0",
"babel-preset-stage-0": "^6.24.1", "babel-preset-stage-0": "^6.24.1",
"date-fns": "^2.0.0-alpha.16", "date-fns": "^2.0.0-alpha.16",
"downshift": "^2.2.0", "downshift": "^2.2.0",
...@@ -50,6 +49,7 @@ ...@@ -50,6 +49,7 @@
"babel-eslint": "^10.0.1", "babel-eslint": "^10.0.1",
"babel-loader": "^7.1.5", "babel-loader": "^7.1.5",
"babel-plugin-transform-class-properties": "^6.24.1", "babel-plugin-transform-class-properties": "^6.24.1",
"babel-polyfill": "^6.26.0",
"babel-preset-env": "^1.7.0", "babel-preset-env": "^1.7.0",
"babel-preset-es2015": "^6.24.1", "babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1", "babel-preset-react": "^6.24.1",
...@@ -64,11 +64,15 @@ ...@@ -64,11 +64,15 @@
"node-sass": "^4.9.3", "node-sass": "^4.9.3",
"postcss-loader": "^3.0.0", "postcss-loader": "^3.0.0",
"prop-types": "^15.6.2", "prop-types": "^15.6.2",
"react-hot-loader": "^4.6.5",
"react-lorem-component": "^0.13.0", "react-lorem-component": "^0.13.0",
"react-script": "^2.0.5", "react-script": "^2.0.5",
"sass-loader": "^7.1.0", "sass-loader": "^7.1.0",
"webpack": "^4.17.0", "webpack": "^4.17.0",
"webpack-bundle-analyzer": "^3.0.2", "webpack-bundle-analyzer": "^3.0.2",
"webpack-cli": "^3.1.0" "webpack-bundle-tracker": "^0.4.2-beta",
"webpack-cli": "^3.1.0",
"webpack-dev-server": "^3.1.14",
"webpack-merge": "^4.2.1"
} }
} }
var webpack = require("webpack");
var WebpackDevServer = require("webpack-dev-server");
var config = require("./webpack.config.dev");
new WebpackDevServer(webpack(config), {
publicPath: config.output.publicPath,
hot: true,
inline: true,
//progress: true,
historyApiFallback: true,
headers: { "Access-Control-Allow-Origin": "*" }
}).listen(3000, "0.0.0.0", (err) => {
if (err) {
// eslint-disable-next-line no-console
console.log(err);
}
// eslint-disable-next-line no-console
console.log("Listening at 0.0.0.0:3000");
});
import "babel-polyfill";
import React from "react"; import React from "react";
import ReactDOM from "react-dom"; import ReactDOM from "react-dom";
import { Provider } from "react-redux"; import { Provider } from "react-redux";
...@@ -19,7 +17,10 @@ const MainReactEntry = () => ( ...@@ -19,7 +17,10 @@ const MainReactEntry = () => (
</Provider> </Provider>
); );
const wrapper = document.getElementById("app"); const wrapper = document.getElementById("app");
wrapper ? ReactDOM.render(<MainReactEntry />, wrapper) : null; wrapper ? ReactDOM.render(<MainReactEntry />, wrapper) : null;
if(module.hot) {
module.hot.accept();
}
\ No newline at end of file
const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const BundleTracker = require("webpack-bundle-tracker");
const config = { const config = {
entry: { entry: {
main: "./src/index.js", main: [
"./src/index",
],
vendor: [
"babel-polyfill",
]
}, },
output: { output: {
path: __dirname + "/dist", path: __dirname + "/dist/bundles",
filename: "[name].js" filename: "[name]-[hash].js"
}, },
module: { module: {
rules: [ rules: [
{ {
test: /\.js$/, test: /\.js$/,
exclude: /node_modules/, exclude: /node_modules/,
loader: 'babel-loader', loader: "babel-loader",
options: { options: {
presets: ['es2015', 'react', 'stage-0'], presets: ["es2015", "react", "stage-0"],
compact: true
}, },
}, },
{ {
...@@ -26,38 +33,41 @@ const config = { ...@@ -26,38 +33,41 @@ const config = {
options: { options: {
// you can specify a publicPath here // you can specify a publicPath here
// by default it use publicPath in webpackOptions.output // by default it use publicPath in webpackOptions.output
publicPath: '../' publicPath: "../"
} }
}, },
'css-loader', "css-loader",
'postcss-loader', "postcss-loader",
'sass-loader', "sass-loader",
] ]
}, },
{ {
test: /\.yml/, test: /\.yml/,
use: 'js-yaml-loader' use: "js-yaml-loader"
}, },
{ {
test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/, test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
use: [{ use: [{
loader: 'file-loader', loader: "file-loader",
options: { options: {
name: '[name].[ext]', name: "[name].[ext]",
publicPath: './fonts/', publicPath: "./fonts/",
outputPath: 'fonts/' outputPath: "fonts/"
} }
}] }]
} }
], ],
}, },
plugins: [ plugins: [
// TODO add hash to css files
new MiniCssExtractPlugin({ new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output // Options similar to the same options in webpackOptions.output
// both options are optional // both options are optional
filename: "[name].css", filename: "[name]-[hash].css",
chunkFilename: "[id].css" chunkFilename: "[id]-[hash].css"
}) }),
new BundleTracker({ filename: "./webpack-stats.json" }),
], ],
}; };
......
const merge = require("webpack-merge");
const webpackConfig = require("./webpack.config");
module.exports = merge(webpackConfig, {
devtool: "source-map",
});
\ No newline at end of file
const merge = require("webpack-merge");
const webpackConfig = require("./webpack.config.base");
const webpack = require("webpack");
const devConfig = merge(webpackConfig, {
devtool: "eval",
mode: "development",
entry: {
main: [
"webpack-dev-server/client?http://localhost:3000",
"webpack/hot/only-dev-server",
]
},
output: {
publicPath: "http://localhost:3000/dist/bundles/",
path: __dirname + "/dist/bundles",
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin(),
new webpack.NoEmitOnErrorsPlugin(), // don't reload if there is an error
],
});
module.exports = devConfig;
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