webpack简述

webpack description

Posted by Ericteen on March 10, 2018

概念

本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图,其中包含应用程序需要的每个模块。然后将所有这些模块打包成一个或多个 bundle。

入口(Entry)

入口起点指示 webpack 应该用哪个文件作为构建内部依赖图的起点。可以通过在 webpack 配置中配置 entry 属性,来指定一个或多个入口起点。

webpack.config.js

const config = {
  entry: {
    app: './src/app.js',
    vendors: './src/vendors.js'
  }
}

出口(Output)

output 属性告诉 webpack 在哪里输出它所创建的 bundles,以及如何命名这些文件。你可以通过在配置中指定一个 output 字段,来配置这些处理过程。

在 webpack 中配置 output 属性的最低要求是将其设置为一个对象,包括:

  • path: 目标输出目录的绝对路径
  • filename: 输出文件的文件名

webpack.config.js

const path = require('path')

const config = {
  entry: './path/to/my/entry/file.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js'
  }
}

如果配置创建了多个单独的 “chunk”(例如,使用多个入口起点或使用像 CommonsChunkPlugin 这样的插件),则应该使用占位符(substitutions)来确保每个文件具有唯一的名称。

{
  entry: {
    app: './src/app.js',
    vendors: './src/vendors.js'
  },
  output: {
    filename: '[name].js',
    path: path.resolve(__dirname, 'dist')
  }
}

当通过多个入口起点(entry point)、代码拆分(code splitting)或各种插件(plugin)创建多个 bundle,应该使用以下一种替换方式,来赋予每个 bundle 一个唯一的名称

使用入口名称:

filename: '[name].bundle.js'

使用内部 chunk id:

filename: '[id].bundle.js'

每次构建过程中生成唯一的 hash:

filename: '[name].[hash].bundle.js'

使用基于每个 chunk 的 hash:

filename: '[chunkhash].bundle.js'

通过使用 output.filename 进行文件名替换,可以确保浏览器获取到修改后的文件。[hash] 替换可以用于在文件名中包含一个构建相关(build-specific)的 hash,但是更好的方式是使用 [chunkhash] 替换,在文件名中包含一个 chunk 相关(chunk-specific)的哈希。

Loader

loader 用于对模块的源代码进行转换,处理不同的文件类型。它负责把某种文件格式的内容转换为 webpack 可以支持打包的模块(webpack 自身只能理解 JavaScript)。比如用 css-loader 处理 .css 文件,用 handlebars-loader 处理 .hbs 文件,最终把不同格式的文件都解析成 js 代码,以便打包后在浏览器中运行。我们可以在 module.rules 字段下来配置相关规则。

module: {
  // ...
  rules: [
    {
      test: /\.jsx?/, // 匹配文件类型的正则表达式
      include: [
        path.resolve(__dirname, 'src')
      ], // 指定哪些路径下的文件需用通过 loader 处理
      use: 'babel-loader', // 指定使用的 loader
    }
  ]
}

插件(Plugin)

loader 被用于转换某些类型的模块,而插件则可以用于执行范围更广的任务。插件的范围包括,从打包优化压缩,一直到重新定义环境中的变量。插件接口功能极其强大,可以用来处理各种各样的任务。

多数插件可以通过选项(option)自定义。你也可以在一个配置文件中因为不同目的而多次使用同一个插件,这时需要通过使用 new 操作符来创建它的一个实例。通过添加我们需要的 plugin,可以满足更多构建中特殊的需求。

const HtmlWebpackPlugin = require('html-webpack-plugin')
const UnglifyPlugin = require('uglify-webpack-plugin')

const config = {
  // ...
  plugins: [
    new UglifyPlufin(),
    new HtmlWebpackPlugin({template: './src/index.html'})
  ]
}

module.exports = config

plugin 理论上可以干涉 webpack 整个构建流程,可以在流程的每一个步骤中定制自己的构建需求。

模式(Mode)

通过将 mode 参数设置为 developmentproduction,你可以开启与设置值相关的内置优化。

module.exprts = {
  mode: 'production'
}
选项 描述
development 使用 development 参数时可以提供 process.env.NODE_ENV值,并使 NamedModulesPlugin 生效
production 提供 process.env.NODE_ENV 的值。使 UglifyPlugin, ModuleConcatenationPluginNoEmitOnErrorsPlugin

配置

最简单的配置文件

webpack.config.js

const path = require('path')

module.exports = {
  entry: './foo.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].[chunkhash].bundle.js'
  }
}

多配置文件

module.exports = [{
  output: {
    filename: './dist-amd.js',
    libraryTarget: 'amd'
  },
  entry: './app.js'
}, {
  output: {
    filename: './dist-commonjs.js'.
    libaryTarget: 'commonjs'
  },
  entry: './app.js'
}]

webpack 4: mode and optimization