beidou-webpack
Version:
beidou webpack middleware
510 lines (353 loc) • 9.86 kB
Markdown
# beidou-webpack
webpack dev server for local environment
[中文文档](./README-ZH.md)
## Features
- Serve jsx/js source
- Serve less/scss/css source
- Support hot module replacement(hmr)
- Fast restart immediately support
- Custom config support
## Breaking Changes
- Configuration fields changed since `v1.0.0`.
We move to `WebpackDevServer` from `webpackDevMiddleware` since `v1.0.0`. Now, configuration is more similar with what we did in normal react project. For more details, see [issue#21](https://github.com/alibaba/beidou/issues/21).
## Configuration
Only available in non production mode, you must build the assets before server online.
- config/plugin.js:
```js
exports.webpack = {
enable: true,
package: 'beidou-webpack',
env: ['local', 'unittest'],
};
```
- config/config.default.js **default config as below**
```js
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](https://webpack.js.org). 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 not `false` value provided, which means webpack responses any request sent to server.
## Custom webpack configuration
**custom.configPath**: defined where your custom webpack config located. An function exported in this file.
```js
// 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.:
```json
{
"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
#### FAQ:
Custom configurate method by `app.webpackFactory`:
```js
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
> Class Struct for Plugin
```js
class Plugin {
object , // instance object for webpack plugin
class, // class for webpack plugin
opitons, // initialize config
alias
}
```
> Class Struct for Rule
```js
class Rule {
opitons, // initialize config for rule
alias
}
```
> app.webpackFactory methods list:
### reset(value)
#### Parameters
- [value] {Object}
#### return
- this
### set(key,value)
#### Parameters
- key {String}
- value {\*}
#### return
- this
### get(key)
#### Parameters
- key {String}
#### return
- {\*}
### generate {key} factory for webpack: env(key)
#### Parameters
- key {String} factory flag
#### return
- {Object}
### Get the final config for webpack : getConfig()
#### Parameters
#### return
- {Object}
### addPlugin(args, options,alias)
#### Parameters
- args {Object|Class|String}
- [options] {Object}
- [alias] {String}
#### return
- this
### getPlugin(filter)
#### Parameters
- filter {String|Function}
#### return
- {Plugin}
### setPlugin(args, options,alias)
#### Parameter
- args {Object|Class}
- [options] {Object}
- [alias] {String}
#### return
- this
### definePlugin(args, options,alias)
#### Parameters
- args {Object|Class}
- [options] {Object}
- [alias] {String}
#### return
- this
### usePlugin(alias)
#### Parameters
- alias {String}
#### return
- {Plugin}
### addRule(options,alias)
#### Parameters
- options {Object|Rule}
- [alias] {String}
#### return
- this
### setRule(options,alias)
#### Parameters
- options {Object|Rule}
- [alias] {String}
#### return
- this
### getRule(filter)
#### Parameters
- filter {String|Function}
#### return
- {Rule}
### defineRule(options,alias)
#### Parameters
- options {Object}
- [alias] {String}
#### return
- this
### useRule(alias)
#### Parameters
- alias {String}
#### return
- {Rule}
### defineLoader(alias,loader)
#### Parameters
- alias {String}
- [loader] {String}
#### return
- this
### useLoader(alias)
#### Parameters
- alias {String}
#### return
- {String}
* **app**: the `BeidouApplication` instance, usually used to access server config.
- **defaultConfig**: default webpack config generated by beidou-webpack.
- **dev**: `true` in local environment or `false` in production.
- **target**: `browser` as default, defined by `--target` argument when running `beidou build`.
## Entry
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](../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)
## Building
**Usage**: beidou-build [--target=browser][--dev]
## Fast restart
Type `rs`, then type `enter`, WebpackDevServer restart immediately.
## License
[MIT](LICENSE)