在模块化编程中,开发者将程序分解成离散功能块(discrete chunks of functionality),并称之为模块。 精心编写的模块提供了可靠的抽象和封装界限,使得应用程序中每个模块都具有条理清楚的设计和明确的目的。
webpack 模块定义
代码语言:javascript复制output: {
library: "MyLibrary",
libraryTarget: "umd"
}
输出内容(不同版本的webpack略有差异,内容相符):
代码语言:javascript复制(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else if(typeof exports === 'object')
exports["MyLibrary"] = factory();
else
root["MyLibrary"] = factory();
})(typeof self !== 'undefined' ? self : this, function() {
return _entry_return_; // 此模块返回值,是入口 chunk 返回的值
});
也可针对不同模式指定不同名称
代码语言:javascript复制output: {
library: {
root: "MyLibrary",
amd: "my-library",
commonjs: "my-common-library"
},
libraryTarget: "umd"
}
webpack 模块解析
代码语言:javascript复制import foo from 'path/to/module'
// 或者
require('path/to/module')
webpack
使用 enhanced-resolve 来解析文件路径(转换为模块的绝对路径)。
引子:如何处理图片的
代码语言:javascript复制import logo from '@/assets/images/logo.png'
代码语言:javascript复制// webpack.config.js
{
test: /.(png|jpe?g|gif|webp)(?.*)?$/,
use: [{
loader: 'url-loader',
options: {
limit: 4096,
fallback: {
loader: 'file-loader',
options: { name: 'img/[name].[hash:8].[ext]' }
}
}
}]
}
file-loader:将文件上的
import / require()
解析为url,并输出到输出目录并返回 public URL。 该图像将被处理并添加到 output 目录,并且 logo 变量将包含该图像在处理后的最终 urlname: 'img/[name].[hash:8].[ext]'
=>/img/logo.b4d70ee2.png
PS:url-loader 功能类似于file-loader
,但是在文件大小(单位 byte)低于指定的限制时,可以返回一个 DataURL。
对于 css 或 html 中引入,处理方式类似!
代码语言:javascript复制background-url: url('../assets/images/logo.png')
代码语言:javascript复制<img class="logo" src="../assets/images/logo.png" alt />
css-loader/html-loader 会识别这是一个本地文件,并将 '../assets/images/logo.png'
路径,替换为 output 目录中图像的最终路径。
vue-loader:
<img src="../image.png">
将会被编译成为 createElement('img', { attrs: { src: require('../image.png') // 现在这是一个模块的请求了 } })
默认情况下,每个本地的 <img src="image.png">
都需要通过 require (require('./image.png')
)来进行加载。
<img class="logo" :src="require('@/assets/images/logo.png')" alt />
绝对路径
直接使用,不需要进一步再做解析
相对路径
在 import/require
中给定的相对路径,会添加此上下文路径(context path),以产生模块的绝对路径(absolute path)
模块路径
代码语言:javascript复制import "module"
import "module/lib/file"
模块将在 resolve.modules
中指定的所有目录内搜索。 你可以替换初始模块路径,此替换路径通过使用 resolve.alias
配置选项来创建一个别名。
一旦根据上述规则解析路径后,解析器(resolver)将检查路径是否指向文件或目录。
如果路径指向一个文件:
- 具有文件扩展名,则直接将文件打包
- 否则,将使用 [
resolve.extensions
] 选项作为文件扩展名来解析
如果路径指向一个文件夹:
- 如果文件夹中包含
package.json
文件,则按照顺序查找resolve.mainFields
配置选项中指定的字段;- 当
target
属性设置为webworker
、web
或者没有指定,默认值为: mainFields: ["browser", "module", "main"] - 对于其他任意的 target(包括
node
),默认值为: mainFields: ["module", "main"]
设置 target,target 同时支持 function module.exports = { target: 'node' } target 选项 描述 async-node 编译为类 Node.js 环境可用(使用 fs 和 vm 异步加载分块) electron-main 编译为 Electron 主进程 electron-renderer 编译为 Electron 渲染进程,使用 JsonpTemplatePlugin, FunctionModulePlugin 来为浏览器环境提供目标,使用 NodeTargetPlugin 和 ExternalsPlugin 为 CommonJS 和 Electron 内置模块提供目标 node 编译为类 Node.js 环境可用(使用 Node.js require 加载 chunk) node-webkit 编译为 Webkit 可用,并且使用 jsonp 去加载分块。支持 Node.js 内置模块和 nw.gui 导入(实验性质) web 编译为类浏览器环境里可用(默认) webworker 编译成一个 WebWorker
- 当
- 如果
package.json
文件不存在或者package.json
文件中的 main 字段没有返回一个有效路径,则按照顺序查找resolve.mainFiles
(解析目录时要使用的文件名。默认:mainFiles: ["index"]
)配置选项中指定的文件名 - 文件扩展名通过
resolve.extensions
选项采用类似的方法进行解析