Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configure webpack-dev-server #5786

Merged
merged 13 commits into from
Sep 4, 2018
41 changes: 35 additions & 6 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -261,23 +261,52 @@ To parse and generate bundled files for superset, run either of the
following commands. The `dev` flag will keep the npm script running and
re-run it upon any changes within the assets directory.

```
```bash
# Copies a conf file from the frontend to the backend
npm run sync-backend

# Compiles the production / optimized js & css
npm run prod

# Start a web server that manages and updates your assets as you modify them
# Start a watcher that rebundle your assets as you modify them
npm run dev

# Start a web server that manages and updates your assets as you modify them
npm run dev-server
```

For every development session you will have to start a flask dev server
as well as an npm watcher
For every development session you will have to

```
1. Start a flask dev server

```bash
superset runserver -d
# or specify port
superset runserver -d -p 8081
npm run dev
```

2. Start webpack dev server

```bash
npm run dev-server
```

This will start `webpack-dev-server` at port 9000 and you can access Superset at localhost:9000.
By default, `webpack-dev-server` is configured for flask running at port 8088.

If you start flask server at another port (e.g. 8081), you have to pass an extra argument
`supersetPort` to `webpack-dev-server`

```bash
npm run dev-server -- --supersetPort=8081
```

You can also specify port for `webpack-dev-server`

```bash
npm run dev-server -- --port=9001
# or with both dev-server port and superset port
npm run dev-server -- --port=9001 --supersetPort=8081
```

#### Upgrading npm packages
Expand Down
3 changes: 3 additions & 0 deletions superset/assets/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"test:one": "mocha --require ignore-styles --compilers js:babel-core/register --require spec/helpers/browser.js",
"cover": "babel-node node_modules/.bin/babel-istanbul cover _mocha -- --compilers babel-core/register --require spec/helpers/browser.js --require ignore-styles 'spec/**/*_spec.*'",
"dev": "webpack --mode=development --colors --progress --debug --watch",
"dev-server": "webpack-dev-server --mode=development --progress",
"prod": "node --max_old_space_size=4096 webpack --mode=production --colors --progress",
"build": "webpack --mode=production --colors --progress",
"lint": "eslint --ignore-path=.eslintignore --ext .js,.jsx .",
Expand Down Expand Up @@ -155,6 +156,7 @@
"less": "^2.6.1",
"less-loader": "^4.1.0",
"mini-css-extract-plugin": "^0.4.0",
"minimist": "^1.2.0",
"mocha": "^3.5.3",
"npm-check-updates": "^2.14.0",
"po2json": "^0.4.5",
Expand All @@ -170,6 +172,7 @@
"webpack": "^4.17.1",
"webpack-assets-manifest": "^3.0.1",
"webpack-cli": "^2.0.10",
"webpack-dev-server": "^3.1.7",
"webpack-sources": "^1.1.0"
}
}
98 changes: 75 additions & 23 deletions superset/assets/webpack.config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
const path = require('path');
const webpack = require('webpack');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const WebpackAssetsManifest = require('webpack-assets-manifest');
// Parse command-line arguments
const parsedArgs = require('minimist')(process.argv.slice(2));

// input dir
const APP_DIR = path.resolve(__dirname, './');
Expand All @@ -11,6 +14,54 @@ const BUILD_DIR = path.resolve(__dirname, './dist');

const isDevMode = process.env.NODE_ENV !== 'production';
Copy link
Contributor

@williaster williaster Aug 31, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

one comment here is that I may have broken this flag when moving to webpack 4 which introduced the concept of mode=production/development (I was trying to use redux dev tools recently and it wasn't working locally, so I thought of this). I thought that also set a NODE_ENV (because webpack 4 was supposed to be all about smart defaults) but it seems like that might not be true.

So I think we either need to

  • reference the mode variable (ie argv.mode === 'production')
    OR
  • explicitly define the NODE_ENV in our npm webpack scripts (NODE_ENV=production webpack ...)

I can fix this in a separate PR as well if you prefer because it might have implications for the other logic in this file that relies on isDevMode (which I think is always true right now)


const devserverPort = parsedArgs.port || 9000;
const supersetPort = parsedArgs.supersetPort || 8088;

const plugins = [
// creates a manifest.json mapping of name to hashed output used in template files
new WebpackAssetsManifest({
publicPath: true,
// This enables us to include all relevant files for an entry
entrypoints: true,
// Also write to disk when using devServer
// instead of only keeping manifest.json in memory
// This is required to make devServer work with flask.
writeToDisk: true,
}),

// create fresh dist/ upon build
new CleanWebpackPlugin(['dist']),
];

if (isDevMode) {
// Enable hot module replacement
plugins.push(new webpack.HotModuleReplacementPlugin());
// text loading (webpack 4+)
plugins.push(new MiniCssExtractPlugin({
filename: '[name].[hash:8].entry.css',
chunkFilename: '[name].[hash:8].chunk.css',
}));
} else {
// text loading (webpack 4+)
plugins.push(new MiniCssExtractPlugin({
filename: '[name].[chunkhash].entry.css',
chunkFilename: '[name].[chunkhash].chunk.css',
}));
}

const output = {
path: BUILD_DIR,
publicPath: '/static/assets/dist/', // necessary for lazy-loaded chunks
};

if (isDevMode) {
output.filename = '[name].[hash:8].entry.js';
output.chunkFilename = '[name].[hash:8].chunk.js';
} else {
output.filename = '[name].[chunkhash].entry.js';
output.chunkFilename = '[name].[chunkhash].chunk.js';
}

const config = {
node: {
fs: 'empty',
Expand All @@ -25,12 +76,7 @@ const config = {
welcome: ['babel-polyfill', APP_DIR + '/src/welcome/index.jsx'],
profile: ['babel-polyfill', APP_DIR + '/src/profile/index.jsx'],
},
output: {
path: BUILD_DIR,
publicPath: '/static/assets/dist/', // necessary for lazy-loaded chunks
filename: '[name].[chunkhash].entry.js',
chunkFilename: '[name].[chunkhash].chunk.js',
},
output,
optimization: {
splitChunks: {
chunks: 'all',
Expand All @@ -57,7 +103,10 @@ const config = {
{
test: /\.css$/,
include: APP_DIR,
use: [isDevMode ? MiniCssExtractPlugin.loader : 'style-loader', 'css-loader'],
use: [
isDevMode ? MiniCssExtractPlugin.loader : 'style-loader',
'css-loader',
],
},
{
test: /\.less$/,
Expand Down Expand Up @@ -97,22 +146,25 @@ const config = {
'react/lib/ExecutionEnvironment': true,
'react/lib/ReactContext': true,
},
plugins: [
// creates a manifest.json mapping of name to hashed output used in template files
new WebpackAssetsManifest({
publicPath: true,
entrypoints: true, // this enables us to include all relevant files for an entry
}),

// create fresh dist/ upon build
new CleanWebpackPlugin(['dist']),

// text loading (webpack 4+)
new MiniCssExtractPlugin({
filename: '[name].[chunkhash].entry.css',
chunkFilename: '[name].[chunkhash].chunk.css',
}),
],
plugins,
devtool: isDevMode ? 'cheap-module-eval-source-map' : false,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

devServer: {
historyApiFallback: true,
hot: true,
index: '', // This line is needed to enable root proxying
inline: true,
stats: { colors: true },
overlay: true,
port: devserverPort,
// Only serves bundled files from webpack-dev-server
// and proxy everything else to Superset backend
proxy: {
context: () => true,
'/': `http://localhost:${supersetPort}`,
target: `http://localhost:${supersetPort}`,
},
contentBase: path.join(process.cwd(), '../static/assets/dist'),
},
};

module.exports = config;
Loading