OpenLayers源码项目中webpack配置config.js解析

OpenLayers项目示例基于页面模板生成,并用webpack打包
解读一下config.js,并顺便学习下webpack常用配置

本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包工具。当 webpack 处理应用程序时,它会在内部构建一个依赖图(dependency graph),此依赖图会映射项目所需的每个模块,并生成一个或多个 bundle

在开始前你需要先理解一些核心概念

  • 入口(entry)
  • 输出(output)
  • loader
  • 插件(plugin)
  • 模式(mode)
  • 浏览器兼容性(browser compatibility)

examples\webpack\config.js:

// 插件:使用terser来缩小JavaScript。
const TerserPlugin = require('terser-webpack-plugin');
// 插件:将单个文件或整个目录复制到构建目录。
const CopyPlugin = require('copy-webpack-plugin');
// 插件:根据模板构建示例html
const ExampleBuilder = require('./example-builder');
// node:fs 模块提供了一个API,用于以模仿标准 POSIX 函数的方式与文件系统进行交互。
const fs = require('fs');
// node:path 模块提供用于处理文件路径和目录路径的实用工具。
const path = require('path');
// path.join() 方法使用平台特定的分隔符作为定界符将所有给定的 path 片段连接在一起,然后规范化生成的路径。
// path.join('/foo', 'bar', 'baz/asdf', 'quux', '..');
// --> 返回: '/foo/bar/baz/asdf'
// node:__dirname为当前模块的目录名。
const src = path.join(__dirname, '..');//返回当前模块的上级目录
// fs.readdirSync() 同步读取目录下所有文件
// 用正则表达式筛选出非index.html的html文件,并替换文件名,去掉后缀
const examples = fs.readdirSync(src)
  .filter(name => /^(?!index).*\.html$/.test(name))
  .map(name => name.replace(/\.html$/, ''));

// 将所有示例的js脚本文件放在entry对象中,作为webpack入口
const entry = {};
examples.forEach(example => {
  entry[example] = `./${example}.js`;
});

// webpack 配置
module.exports = {
  // 基础目录,绝对路径,用于从配置中解析入口起点(entry point)和 loader
  context: src,
  // 告知 webpack 为目标(target)指定一个环境。
  // webpack 能够为多种环境或 target 构建编译。
  target: 'web',
  // webpack 应用程序开始执行,支持类型:string | object | array
  entry: entry,
  // 统计信息
  // "errors-only": 只在发生错误时输出
  // "minimal": 只在发生错误或有新的编译时输出
  // "none": 没有输出
  // "normal": 标准输出
  // "verbose": 全部输出
  stats: 'minimal',
  // webpack 关于模块配置
  module: {
    // 模块规则(配置 loader、解析器等选项)
    rules: [
      // 用buble-loader解析目标目录文件
      {
        // 匹配条件
        test: /\.js$/,
        // 采用的loader
        use: {
          loader: 'buble-loader'
        },
        // 匹配条件,指定目录
        include: [
          path.join(__dirname, '..', '..', 'src'),
          path.join(__dirname, '..')
        ]
      },
      // 用worker-loader解析目标目录文件
      {
        test: /\.js$/,
        use: {
          loader: path.join(__dirname, './worker-loader.js')
        },
        include: [
          path.join(__dirname, '../../src/ol/worker')
        ]
      }
    ]
  },
  // 优化方案配置,修改默认设置
  optimization: {
    // 压缩配置
    // 允许你通过提供一个或多个定制过的 TerserPlugin 实例,覆盖默认压缩工具(minimizer)。
    minimizer: [
      new TerserPlugin({
        sourceMap: true,
        // Do not minify examples that inject code into workers
        exclude: [/(color-manipulation|region-growing|raster)\.js/]
      })
    ],
    // 为 runtime chunks 命名。
    // runtimeChunk的作用是优化持久化缓存的, 
    // runtime 指的是 webpack 的运行环境(具体作用就是模块解析, 加载) 和 模块信息清单, 
    // 模块信息清单在每次有模块变更(hash 变更)时都会变更, 
    // 所以我们想把这部分代码单独打包出来, 配合后端缓存策略, 
    // 这样就不会因为某个模块的变更导致包含模块信息的模块(通常会被包含在最后一个 bundle 中)缓存失效. 
    // optimization.runtimeChunk 就是告诉 webpack 是否要把这部分单独打包出来.
    runtimeChunk: {
      name: 'common'
    },
    // 代码块分割
    // chunks: 表示哪些代码需要优化,可选:initial(初始块)、async(按需加载块)、all(全部块),默认为async
    // minSize: 表示在压缩前的最小模块大小,默认为30000
    // minChunks: 表示被引用次数,默认为1
    // maxAsyncRequests: 按需加载时候最大的并行请求数,默认为5
    // maxInitialRequests: 一个入口最大的并行请求数,默认为3
    // automaticNameDelimiter: 命名连接符
    // name: 拆分出来块的名字,默认由块名和hash值自动生成
    // cacheGroups: 缓存组。缓存组的属性除上面所有属性外,还有test, priority, reuseExistingChunk
    // +--test: 用于控制哪些模块被这个缓存组匹配到
    // +--priority: 缓存组打包的先后优先级
    // +--reuseExistingChunk: 如果当前代码块包含的模块已经有了,就不在产生一个新的代码块 
    splitChunks: {
      name: 'common',
      chunks: 'initial',
      minChunks: 2
    }
  },
  // webpack 插件列表。
  plugins: [
    // webpack插件,为我们的示例构建html文件。
    // @param{object}配置插件配置。需要具有模板路径的templates`属性和具有公共块名称的`common`属性。
    new ExampleBuilder({
      templates: path.join(__dirname, '..', 'templates'),
      common: 'common'
    }),
    // 用于复制资源目录文件
    new CopyPlugin([
      { from: '../src/ol/ol.css', to: 'css' },
      { from: 'data', to: 'data' },
      { from: 'resources', to: 'resources' },
      { from: 'Jugl.js', to: 'Jugl.js' },
      { from: 'index.html', to: 'index.html' }
    ])
  ],
  devtool: 'source-map',
  // webpack 如何输出结果的相关选项
  output: {
    // 打包的总目标文件名
    filename: '[name].js',
    // 所有输出文件的目标路径,必须是绝对路径(使用 Node.js 的 path 模块)
    path: path.join(__dirname, '..', '..', 'build', 'examples')
  },
  // 这些选项可以配置是否 polyfill 或 mock 某些 Node.js 全局变量和模块。
  // 指定一个对象,其中每个属性都是 Node.js 全局变量或模块的名称,每个 value 是以下其中之一:
  // true:提供 polyfill。
  // "mock":提供 mock 实现预期接口,但功能很少或没有。
  // "empty":提供空对象。
  // false: 什么都不提供。
  node: {
    fs: 'empty' // required by ol-mapbox-stlye
  },
  // 配置模块如何解析
  resolve: {
    // 创建 import 或 require 的别名,来确保模块引入变得更简单。
    alias: {
      // allow imports from 'ol/module' instead of specifiying the source path
      // 允许从‘ol/module’导入,而不是指定源路径
      ol: path.join(__dirname, '..', '..', 'src', 'ol')
    }
  }
};

你可能感兴趣的:(OpenLayers源码项目中webpack配置config.js解析)