Configure webpack-dev-server (#5786)

* setup devserver with correct proxy

* dev server wroking with written manifest

* add comments

* Change webpack to default port 9000 and minor js formatting

* Use hash in development.

* write to disk = true

* Take ports as argument for dev-server

* update instructions

* update instructions

* add devtools

* use mode instead of NODE_ENV

* use minicssextract for prod (like before)

* remove empty line
This commit is contained in:
Krist Wongsuphasawat 2018-09-04 10:39:05 -07:00 committed by Grace Guo
parent d43813ff09
commit eb41756e5e
4 changed files with 923 additions and 146 deletions

View File

@ -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 following commands. The `dev` flag will keep the npm script running and
re-run it upon any changes within the assets directory. re-run it upon any changes within the assets directory.
``` ```bash
# Copies a conf file from the frontend to the backend # Copies a conf file from the frontend to the backend
npm run sync-backend npm run sync-backend
# Compiles the production / optimized js & css # Compiles the production / optimized js & css
npm run prod npm run prod
# 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 # Start a web server that manages and updates your assets as you modify them
npm run dev npm run dev-server
``` ```
For every development session you will have to start a flask dev server For every development session you will have to
as well as an npm watcher
``` 1. Start a flask dev server
```bash
superset runserver -d
# or specify port
superset runserver -d -p 8081 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 #### Upgrading npm packages

View File

@ -12,6 +12,7 @@
"test:one": "mocha --require ignore-styles --compilers js:babel-core/register --require spec/helpers/browser.js", "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.*'", "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": "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", "prod": "node --max_old_space_size=4096 webpack --mode=production --colors --progress",
"build": "webpack --mode=production --colors --progress", "build": "webpack --mode=production --colors --progress",
"lint": "eslint --ignore-path=.eslintignore --ext .js,.jsx .", "lint": "eslint --ignore-path=.eslintignore --ext .js,.jsx .",
@ -155,6 +156,7 @@
"less": "^2.6.1", "less": "^2.6.1",
"less-loader": "^4.1.0", "less-loader": "^4.1.0",
"mini-css-extract-plugin": "^0.4.0", "mini-css-extract-plugin": "^0.4.0",
"minimist": "^1.2.0",
"mocha": "^3.5.3", "mocha": "^3.5.3",
"npm-check-updates": "^2.14.0", "npm-check-updates": "^2.14.0",
"po2json": "^0.4.5", "po2json": "^0.4.5",
@ -170,6 +172,7 @@
"webpack": "^4.17.1", "webpack": "^4.17.1",
"webpack-assets-manifest": "^3.0.1", "webpack-assets-manifest": "^3.0.1",
"webpack-cli": "^2.0.10", "webpack-cli": "^2.0.10",
"webpack-dev-server": "^3.1.7",
"webpack-sources": "^1.1.0" "webpack-sources": "^1.1.0"
} }
} }

View File

@ -1,15 +1,68 @@
const path = require('path'); const path = require('path');
const webpack = require('webpack');
const CleanWebpackPlugin = require('clean-webpack-plugin'); const CleanWebpackPlugin = require('clean-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const WebpackAssetsManifest = require('webpack-assets-manifest'); const WebpackAssetsManifest = require('webpack-assets-manifest');
// Parse command-line arguments
const parsedArgs = require('minimist')(process.argv.slice(2));
// input dir // input dir
const APP_DIR = path.resolve(__dirname, './'); const APP_DIR = path.resolve(__dirname, './');
// output dir // output dir
const BUILD_DIR = path.resolve(__dirname, './dist'); const BUILD_DIR = path.resolve(__dirname, './dist');
const isDevMode = process.env.NODE_ENV !== 'production'; const {
mode = 'development',
devserverPort = 9000,
supersetPort = 8088,
} = parsedArgs;
const isDevMode = mode !== 'production';
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: isDevMode,
}),
// 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 = { const config = {
node: { node: {
@ -25,12 +78,7 @@ const config = {
welcome: ['babel-polyfill', APP_DIR + '/src/welcome/index.jsx'], welcome: ['babel-polyfill', APP_DIR + '/src/welcome/index.jsx'],
profile: ['babel-polyfill', APP_DIR + '/src/profile/index.jsx'], profile: ['babel-polyfill', APP_DIR + '/src/profile/index.jsx'],
}, },
output: { output,
path: BUILD_DIR,
publicPath: '/static/assets/dist/', // necessary for lazy-loaded chunks
filename: '[name].[chunkhash].entry.js',
chunkFilename: '[name].[chunkhash].chunk.js',
},
optimization: { optimization: {
splitChunks: { splitChunks: {
chunks: 'all', chunks: 'all',
@ -57,13 +105,16 @@ const config = {
{ {
test: /\.css$/, test: /\.css$/,
include: APP_DIR, include: APP_DIR,
use: [isDevMode ? MiniCssExtractPlugin.loader : 'style-loader', 'css-loader'], use: [
MiniCssExtractPlugin.loader,
'css-loader',
],
}, },
{ {
test: /\.less$/, test: /\.less$/,
include: APP_DIR, include: APP_DIR,
use: [ use: [
isDevMode ? MiniCssExtractPlugin.loader : 'style-loader', MiniCssExtractPlugin.loader,
'css-loader', 'css-loader',
'less-loader', 'less-loader',
], ],
@ -97,22 +148,25 @@ const config = {
'react/lib/ExecutionEnvironment': true, 'react/lib/ExecutionEnvironment': true,
'react/lib/ReactContext': true, 'react/lib/ReactContext': true,
}, },
plugins: [ plugins,
// creates a manifest.json mapping of name to hashed output used in template files devtool: isDevMode ? 'cheap-module-eval-source-map' : false,
new WebpackAssetsManifest({ devServer: {
publicPath: true, historyApiFallback: true,
entrypoints: true, // this enables us to include all relevant files for an entry hot: true,
}), index: '', // This line is needed to enable root proxying
inline: true,
// create fresh dist/ upon build stats: { colors: true },
new CleanWebpackPlugin(['dist']), overlay: true,
port: devserverPort,
// text loading (webpack 4+) // Only serves bundled files from webpack-dev-server
new MiniCssExtractPlugin({ // and proxy everything else to Superset backend
filename: '[name].[chunkhash].entry.css', proxy: {
chunkFilename: '[name].[chunkhash].chunk.css', context: () => true,
}), '/': `http://localhost:${supersetPort}`,
], target: `http://localhost:${supersetPort}`,
},
contentBase: path.join(process.cwd(), '../static/assets/dist'),
},
}; };
module.exports = config; module.exports = config;

File diff suppressed because it is too large Load Diff