I have a webapp that uses the following tech stack :
- Apache running on Amazon EC2 Instance
- Django, serving via WSGI
- Javascript compiled via webpack / babel
Things are working great on a desktop environment, but on mobile, it is completely non-functional. When I navigate to the home page, mobile browsers try to initiate a download rather than serving the page.
I’ve been beating my head against the wall for a few days trying to figure out what is going on, but I don’t have any leads.
Here is my webpack.config.js, since I think that’s the most likely place for a problem :
const path = require('path');
const webpack = require('webpack');
const autoprefixer = require('autoprefixer');
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
const BundleTracker = require('webpack-bundle-tracker');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const SentryCliPlugin = require('@sentry/webpack-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const devMode = process.env.NODE_ENV !== 'production';
const hotReload = process.env.HOT_RELOAD === '1';
const styleRule = {
test: /.(sa|sc|c)ss$/,
use: [
MiniCssExtractPlugin.loader,
{ loader: 'css-loader', options: { sourceMap: true } },
{
loader: 'postcss-loader',
options: {
plugins: () => [autoprefixer({
overrideBrowserslist: [
'last 2 Chrome versions',
'not Chrome < 60',
'last 2 Safari versions',
'not Safari < 10.1',
'last 2 iOS versions',
'not iOS < 10.3',
'last 2 Firefox versions',
'not Firefox < 54',
'last 2 Edge versions',
'not Edge < 15',
],
})],
},
},
'sass-loader',
],
};
const jsRule = {
test: /.js$/,
include: [
path.resolve('./'),
],
exclude: [/node_modules/, /lib/],
use: [
'babel-loader',
{
loader: 'eslint-loader',
options: {
fix: true,
presets: ['@babel/preset-es2015'],
},
},
],
};
const assetRule = {
test: /.(jpg|png|woff(2)?|eot|ttf|svg)$/,
loader: 'file-loader',
};
const plugins = [
new webpack.ProvidePlugin({
'window.jQuery': 'jquery',
jQuery: 'jquery',
$: 'jquery',
}),
new BundleTracker({ filename: './webpack-stats.json' }),
new MiniCssExtractPlugin({
filename: devMode ? '[name].css' : '[name].[hash].css',
chunkFilename: devMode ? '[id].css' : '[id].[hash].css',
}),
new BundleAnalyzerPlugin({ analyzerMode: 'static', openAnalyzer: false }),
new webpack.HotModuleReplacementPlugin(),
new CleanWebpackPlugin(),
// new CleanWebpackPlugin(['./static/dist']),
new CopyWebpackPlugin([
{ from: './static/src/images/**/*', to: path.resolve('./static/dist/images/[name].[ext]'), toType: 'template' },
]),
];
if (devMode) {
styleRule.use = ['css-hot-loader', ...styleRule.use];
} else {
plugins.push(
new webpack.EnvironmentPlugin(['NODE_ENV']),
);
if (process.env.SENTRY_DSN) {
plugins.push(
new SentryCliPlugin({
include: '.',
release: process.env.SOURCE_VERSION,
ignore: ['node_modules', 'webpack.config.js'],
}),
);
}
}
module.exports = {
context: __dirname,
entry: {
app: './wzapp/global_web_source/app.js',
main: './main/web_src/app.js',
coop: './coop/web_src/app.js',
wdns: './wdns/web_src/app.js',
},
output: {
path: path.resolve('./static/dist/'),
filename: '[name]-[hash].js',
publicPath: hotReload ? 'https://localhost:8080/' : '',
},
devtool: devMode ? 'cheap-eval-source-map' : 'source-map',
devServer: {
hot: true,
quiet: false,
https: {
key: 'server.key',
cert: 'server.crt',
},
headers: { 'Access-Control-Allow-Origin': '*' },
},
module: { rules: [jsRule, styleRule, assetRule] },
plugins,
optimization: {
minimizer: [
new UglifyJsPlugin({
cache: true,
parallel: true,
sourceMap: true, // set to true if you want JS source maps
}),
new OptimizeCSSAssetsPlugin({}),
],
splitChunks: {
cacheGroups: {
commons: {
name: 'commons',
chunks: 'initial',
minChunks: 2,
},
},
},
// splitChunks: {
// cacheGroups: {
// commons: {
// test: /[\/]node_modules[\/]/,
// name: 'vendor',
// chunks: 'initial',
// },
// }
// }
},
};
2
Answers
Thanks to @yoomama for pointing me in the right direction. It turns out the issue was with my wsgi configuration, and some headers that mobile sites needed. I modified my wsgi.py to add a Middleware config to fix it, as follows :
Scratch all of my previous comments. Here is a curl request:
Notice the Content-Type… Something is wrong with your Apache configuration. I believe it’s because Django can’t serve subdomains unless you download a package. I’m on Safari OSX and it downloaded file but on Google Chrome it didn’t.
Edit 1: Here is your current website not on a subdomain. I think your Babel configuration is supposed to redirect me to this