webpack dev server for local environment
- Serve jsx/js source
- Serve less/scss/css source
- Support hot module replacement(hmr)
- Fast restart immediately support
- Custom config support
-
Configuration fields changed since
v1.0.0
.We move to
WebpackDevServer
fromwebpackDevMiddleware
sincev1.0.0
. Now, configuration is more similar with what we did in normal react project. For more details, see issue#21.
Only available in non production mode, you must build the assets before server online.
- config/plugin.js:
exports.webpack = {
enable: true,
package: 'beidou-webpack',
env: ['local', 'unittest'],
};
- config/config.default.js default config as below
exports.webpack = {
custom: {
// configPath: 'path/to/webpack/config/file',
// depth: 1,
// proxy: null,
cssExtract: true, // default enable css-mini-plugin config
},
output: {
path: './build',
filename: '[name].js?[hash]',
chunkFilename: '[name].js',
publicPath: './build',
},
resolve: {
extensions: ['.json', '.js', '.jsx'],
},
devServer: {
contentBase: false,
port: 6002,
noInfo: true,
quiet: false,
clientLogLevel: 'warning',
lazy: false,
watchOptions: {
aggregateTimeout: 300,
},
headers: { 'X-Custom-Header': 'yes' },
stats: {
colors: true,
chunks: false,
},
publicPath: '/build',
hot: true,
},
};
Config fields output
, resolve
, devServer
are same as what you know in webpack. You can set any valid webpack configs not only those three keys.Changing these fields would take effects in default webpack config which generated by beidou-webpack plugin as default. Configs which this plugin self needs must under the custom
key. e.g. you need to custom webpack configs, you can set 'webpack.custom.configPath'
to your file path.
-
devServer.port defined the port webpack listen to, you can visit webpack dev server through node server (usually at port 6001) because the plugin provide a proxy to do this automatically. Otherwise, you can directly visit webpack dev server (such as http://localhost:6002/webpack-dev-server) if anything else needed.
-
devServer.contentBase must be set to
false
, because a static server works if any notfalse
value provided, which means webpack responses any request sent to server.
custom.configPath: defined where your custom webpack config located. An function exported in this file.
// webpack.config.js
// Example 1:
module.exports = (app, defaultConfig, dev, target) => {
return {
...defaultConfig,
entry: {
// your entry
},
module: {
// your module
},
plugins: [
// your plugins
],
//something else to override
};
};
// Example 2:
// Note: The config will cover the default config
module.exports = {
output: {
path: './build',
filename: '[name].js?[hash]',
chunkFilename: '[name].js',
publicPath: './build',
},
resolve: {
extensions: ['.json', '.js', '.jsx'],
},
devServer: {
contentBase: false,
port: 6002,
noInfo: true,
quiet: false,
clientLogLevel: 'warning',
lazy: false,
watchOptions: {
aggregateTimeout: 300,
},
headers: { 'X-Custom-Header': 'yes' },
stats: {
colors: true,
chunks: false,
},
publicPath: '/build',
hot: true,
},
};
custom.depth: define the depth of entry scanning
custom.proxy: define the url match for webpack proxy
e.g.:
{
"webpack": {
"custom": {
"proxy": "/foo*"
}
}
}
All of the requests start with /foo
will be redirected to webpack server directly. Useful when enable devServer.proxy.
custom.cssExtract: whether enable css-mini-plugin for webpack
Custom configurate method by app.webpackFactory
:
module.exports = (app, defaultConfig, dev, target) => {
// get the webpack factory
const factory = app.webpackFactory;
// set the value of output in webpack :
factory.set('output',{
path: outputPath,
filename: '[name].js?[hash]',
chunkFilename: '[name].js',
publicPath: '/build/',
})
// if type of the new value is the same, it will emit deep merge by default;
// string type will overrided;
// obj:
factory.set('output',{
hashDigestLength:10
})
// factory.get('output'): {
// path: outputPath,
// filename: '[name].js?[hash]',
// chunkFilename: '[name].js',
// publicPath: '/build/',
// hashDigestLength: 10
// }
// array:
// suppose the old entry value is ['./src/main.js']
factory.set('entry',['./src/index.js'])
// factory.get('entry'): ['./src/main.js','./src/index.js'];
// want to override the old value? just set the 3rd param true;
factory.set('entry',['./src/app.js'],true)
// factory.get('entry'): ['./src/app.js'];
// modify the output value
factory.get('output').chunkFilename = '[name].modify.js';
// add webpack plugin config list
// add UglifyJsPlugin config into plugin of webpack
// TODO: fix
// factory.addPlugin(
// webpack.optimize.UglifyJsPlugin,
// {
// compress: {
// warnings: false,
// }
// },
// 'UglifyJsPlugin' ,
// )
// modify the UglifyJsPlugin config
// TODO: fix
// factory.setPlugin(
// webpack.optimize.UglifyJsPlugin,
// {
// compress: {
// warnings: true,
// }
// },
// 'UglifyJsPlugin'
// );
// or another method
factory.getPlugin('UglifyJsPlugin').options = {
compress: {
warnings: true,
}
}
// modify the rule of webpack
const ruleObj = factory.getRule('.ts');
ruleObj.options = {
test: /\.tsx?$/,
exclude: /node_modules/,
use: {
loader:
app.webpackFactory.useLoader('babel-loader')/** if had the defined loader,use it **/ || 'babel-loader',
options: {
babelrc: false,
presets: ['preset-typescript'],
},
},
}
// define the loader
app.webpackFactory.defineLoader({
'babel-loader',
require.resolve('babel-loader')
})
// generate prod webpack factory
const factoryInProd = factory.env('prod');
factoryInProd.addPlugin(new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false,
},
}))
return factory.getConfig(); // return webpack config
// or return webpack config for prod
// return factoryInProd.getConfig()
};
Class Struct for Plugin
class Plugin {
object , // instance object for webpack plugin
class, // class for webpack plugin
opitons, // initialize config
alias
}
Class Struct for Rule
class Rule {
opitons, // initialize config for rule
alias
}
app.webpackFactory methods list:
- [value] {Object}
- this
- key {String}
- value {*}
- this
- key {String}
- {*}
- key {String} factory flag
- {Object}
- {Object}
- args {Object|Class|String}
- [options] {Object}
- [alias] {String}
- this
- filter {String|Function}
- {Plugin}
- args {Object|Class}
- [options] {Object}
- [alias] {String}
- this
- args {Object|Class}
- [options] {Object}
- [alias] {String}
- this
- alias {String}
- {Plugin}
- options {Object|Rule}
- [alias] {String}
- this
- options {Object|Rule}
- [alias] {String}
- this
- filter {String|Function}
- {Rule}
- options {Object}
- [alias] {String}
- this
- alias {String}
- {Rule}
- alias {String}
- [loader] {String}
- this
- alias {String}
- {String}
- app: the
BeidouApplication
instance, usually used to access server config.
-
defaultConfig: default webpack config generated by beidou-webpack.
-
dev:
true
in local environment orfalse
in production. -
target:
browser
as default, defined by--target
argument when runningbeidou build
.
Webpack entries in default webpack config is generated through a file scanning in client
directory.
Scanning behavior becomes much different for different config values of router.root
and router.entry
in beidou-router.
- router.root: the directory scanning begin at.
- router.entry: only files with name match the
router.entry
will be treat as valid entry.
Notice: The Scanning only process at most depth 1, ( only ${router.root}/${router.entry}.jsx and ${router.root}/${dir}/${router.entry}.jsx will be found)
Usage: beidou-build [--target=browser][--dev]
Type rs
, then type enter
, WebpackDevServer restart immediately.