Skip to content

Latest commit

 

History

History
509 lines (353 loc) · 9.63 KB

README.md

File metadata and controls

509 lines (353 loc) · 9.63 KB

beidou-webpack

webpack dev server for local environment

中文文档

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.

Configuration

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 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.

// 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

FAQ:

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

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:

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.

  • 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