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')
}
}
};