Skip to content

Instantly share code, notes, and snippets.

@jonesnc
Last active January 20, 2017 22:28
Show Gist options
  • Save jonesnc/83936d93441ece1ad96a2e5f05976e70 to your computer and use it in GitHub Desktop.
Save jonesnc/83936d93441ece1ad96a2e5f05976e70 to your computer and use it in GitHub Desktop.
A description of my app's environment, looking for the ideal webpack setup
I'm working on a React app which resides within an application called PowerSchool,
and I'm trying to create a webpack configuration that allows for both a development
environment that relies on webpack-dev-server and hot reloading, and a production version
of the build that creates my bundles and vendor files.
The general structure of this React app is the following:
* An HTML page within PowerSchool which contains an iframe whose src points to
* My React index.html page that references my bundle.js, bundle.css, vendor.js (refered to as app files going forward) files
The first problem is how I need to be authenticating with PowerSchool.
My data sources are only available by making AJAX requests to our PowerSchool server,
so the session cookies need to be passed along in each request.
This means that the iframe's src must be considered the same origin as the PowerSchool server's domain.
This would be true in both dev and prod environments.
The second problem is that within dev,
I would like my index.html page to import the local versions of my app files that are served by webpack-dev-server,
but within prod my index.html should import my app files from a path relative to my PowerSchool's domain.
So, for example, my bundle.js should be imported in dev and prod like this:
dev
-----
<script src="https://localhost:8080/bundle.js"></script>
prod
-----
<script src="/scripts/myapp/bundle.js"></script>
The third problem is that I'm not sure how I should be handling the different versions of React.
In dev, I'd like my index.html to import the dev version of React so I can see its
warning messages and other nice things that the prod version doesn't have.
dev
-----
<script src="https://unpkg.com/react@15/dist/react.js"></script>
<script src="https://unpkg.com/react-dom@15/dist/react-dom.js"></script>
prod
-----
<script src="https://unpkg.com/react@15/dist/react.min.js"></script>
<script src="https://unpkg.com/react-dom@15/dist/react-dom.min.js"></script>
Please see my webpack config below for what I have tried so far.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="https://bootswatch.com/flatly/bootstrap.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" />
<script>
window.iFrameResizer = {
targetOrigin: '<%= htmlWebpackPlugin.options.psHost %>'
};
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/iframe-resizer/3.5.5/iframeResizer.contentWindow.js"></script>
<!-- Webpack bundle -->
</head>
<body>
<!-- compiled content.html goes here -->
<div class="container-fluid">
<div id="profile-container"></div>
</div>
<!-- end .container-fluid -->
</body>
</html>
"scripts": {
"test": "",
"build:dev": "webpack-dev-server --progress --https --host 0.0.0.0 --port 8080 --host https://localhost:8080",
"build:prod": "webpack"
},
/* global process */
import path from 'path';
import webpack from 'webpack';
import ExtractTextPlugin from 'extract-text-webpack-plugin';
import WebpackMerge from 'webpack-merge';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import { argv } from 'yargs';
const TARGET = process.env.npm_lifecycle_event;
const { host } = argv;
const common = {
devtool: 'source-map',
entry: {
bundle: [
'./src/scripts/student-profile/js/react-index'
],
vendor: ['bootstrap', 'isomorphic-fetch', 'react', 'react-dom', 'react-router', 'urijs', 'jquery', 'he', 'address-format']
},
output: {
path: path.join(__dirname, 'dist/src/scripts/student-profile'),
filename: 'bundle.js',
publicPath: host
},
module: {
loaders: [{
test: /\.js$/,
loaders: ['react-hot', 'babel?presets[]=es2015'],
include: path.join(__dirname, 'src')
},
{
test: /\.scss$/,
loader: ExtractTextPlugin.extract('style', 'css?sourceMap!sass?sourceMap')
}
]
},
plugins: [
new ExtractTextPlugin('bundle.css'),
new webpack.optimize.CommonsChunkPlugin('vendor', 'vendor.js', Infinity),
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery'
})
],
resolve: {
modulesDirectories: ['node_modules'],
extensions: ['', '.js', '.jsx']
}
};
var config;
if (TARGET === 'build:dev') {
config = WebpackMerge.strategy({
entry: 'prepend',
'module.loaders': 'prepend'
})(common, {
plugins: [
new webpack.HotModuleReplacementPlugin(),
new HtmlWebpackPlugin({
host: 'https://localhost:8080',
psHost: 'https://powerschool.example.org',
template: 'src/scripts/student-profile/html/index.ejs'
})
],
entry: {
bundle: [
'webpack-dev-server/client?http://localhost:8080/',
'webpack/hot/only-dev-server'
]
}
});
} else {
config = WebpackMerge(common, {
plugins: [
new webpack.optimize.UglifyJsPlugin(),
new HtmlWebpackPlugin({
host: '/scripts/student-profile',
psHost: 'https://powerschool.example.org',
template: 'src/scripts/student-profile/html/index.ejs'
})
]
});
}
export default config;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment