webpack 3.0 配置说明

webpack

我们使用webpack主要完成以下功能:
1. 编译js代码
2. 提取,分割js代码
3. 编译sass代码
4. 压缩js代码
5. 压缩css代码
6. 生成页面
7. 调试
8. 其他

webpack配制

webapck配制中最主要的是4个部分:
* entry
* output
* loaders
* plugins

Entry

entry定义了整个构建的起始点。

webpackConfig.entry = {
  normalize: [ paths.client('normalize') ],
  vendor : config.compiler_vendor,
  app: paths.client('main.js')
}

这里定义了3个起始点,key就是这个chunk的名字,后面的是这个chunk的起始点

Output

output定义了如何输出webpack的打包结果

webpackConfig.output = {
  filename: `[name].[hash].js`,
  chunkFilename: `[id].[name].[hash].js`,
  path: 'dist',
  publicPath: 'http://one.jushenghua.com/'
}

filename: 每个entrypoint对应一个输出文件
chunkFilename: 代码分割后的文件名称
publicPath: 指定所有资源的发布路径

loaders

loader可以认为是编译器,我们把es6编译成es5,通过babel-loader,把sass编译成css,通过sass-loader
所有的loaders配制定义在

// webpack1
module.loaders = [
  // loaders
  {
    test: /\.coffee$/,
    loader: 'coffee'
  },
  {
    test: /\.css$/
    loaders: [
      'style',
      'css'
    ]
  }
]

// webpack 2+
module.rules = [
  // loaders
  {
    test: /\.coffee$/,
    loader: 'coffee-loader'
  },
  {
    test: /\.css$/,
    use: [
      {
        loader: 'style-loader'
      },
      {
        loader: 'css-loader'
      }
    ]
  }
]

plugins

plugins是webpack完成其他功能的机制,比如生成页面,使用html-webpack-plugin,压缩js使用UglifyJsPlugin

编译JS

编译es6

webpackConfig.module.rules = [{
  test: /\.(js|jsx)$/,
  exclude: /node_modules/,
  loader: 'babel-loader',
  options: {
    cacheDirectory: true,
    plugins: ['transform-runtime'],
    presets: ['es2015', 'stage-0']
  }
}]

preset

a preset is a set of plugins used to support particular language features

编译jsx

增加react, flow preset

webpackConfig.module.rules = [{
  test: /\.(js|jsx)$/,
  exclude: /node_modules/,
  loader: 'babel-loader',
  options: {
    cacheDirectory: true,
    plugins: ['transform-runtime'],
    presets: ['es2015', 'react', 'stage-0', 'flow']
  }
}]

增加antd的动态加载

增加import plugin

webpackConfig.module.rules = [{
  test: /\.(js|jsx)$/,
  exclude: /node_modules/,
  loader: 'babel-loader',
  options: {
    cacheDirectory: true,
    plugins: ['transform-runtime', ['import', { libraryName: 'antd', style: true }]],
    presets: ['es2015', 'react', 'stage-0']
  }
}]

编译riot

使用es2015-riotpreset

编译preact

增加以下plugin:

['transform-react-jsx', { 'pragma': 'h' }]

提取JS代码

通常情况下,每个entry point包含的模块,都会打包到相应的输出文件中。但有时不同的entry point会包含相同的模块,如果我们把相同的模块提取出来,能够减小整个的输出大小,CommonsChunkPlugin就是为了完成这个的

webpackConfig.plugins.push(
  new webpack.optimize.CommonsChunkPlugin({
    names: ['normalize', 'vendor']
  })
)

代码分割

我们开发的是单页应用,默认,每一个页面都会打包到app.js中,这样就带来一个问题,在打开页面时,要把所有页面的代码加载完以后才能显示。所以这就需要代码分割来加载必须的页面
Webpack本身提供了代码分割功能,webpack1和webpack2+的实现不一样
* webpack1 使用require.ensure(), require()
* webpack2 使用import(), import返回一个Promise
* ensure支持给chunk命名,import不支持

// webpack 1
require.ensure([], (require) => {
  next(null, [
    require('./Login').default(store),
    require('./dashboard').default(store),
    require('./NotFound').default
  ])
}, 'root')

// webpack 2
render () {
  return (
    <Router history={createHashHistory()}>
      <AsyncRoute path='/counter' getComponent={() => import('./Counter').then(module => module.default)} />
    Router>
  )
}

编译SASS

编译sass比较简单,和babel一样,调用sass-loader即可。sass loader的作用就是把sass编译成css,但webpack打包css,还需要一些配制工作

{
  loader: 'sass-loader',
  options: {
    sourceMap: false,
    includePaths: [paths.client('assets/style')]
  }
}

打包css

打包css,需要几个loader
* style-loader: 注入