前端模块打包工具
- 新特性代码编译
- 模块化 js 打包
- 支持不通类型的资源模块
模块化工具的作用
- 模块打包器
- 模块加载器编译转换(loader)
- 代码拆分(应用运行中初次运行中所必须的打包到一起,异步加载之后所用到的模块,从而做的增亮加载,渐进式加载)
- 资源模块
- 打包工具解决的是整个前端的模块化
webpack
编译后的代码
- 声明变量用于储存模块,缓存加载过的模块
- 定义一个加载模块的函数(require)
- 在在加载模块函数上挂在一些工具函数
- 调用 加载模块的函数(require)传入一个0(传入数组的模块下标)
webpack核心工作原理,会根据配置找到其中文件做完打包的入口(.js), 会顺着入口文件中的代码,根据代码中出现的import解析推断出来这个文件所依赖的资源模块,分别解析每个资源模块对应的依赖,最后会形成一个整个项目中所有的用到文件之间的依赖关系的依赖树,有了这个依赖树之后会递归这个依赖树,找到每个节点多需要的资源文件,根据每个文件中的rules属性,找到模块的加载器加载这个模块,最后把加载的结果放到 bundle中
loader 专注实现资源模块加载,在加载模块时工作
plugin
- 增强webpack自动化能力
- 钩子机制 (通过在生命周期的钩子中挂在函数实现扩展),可以触及到webpack的每个环节
- 一个函数或者是一个包含apply方法的对象,一般会把方法定义成一个类型,定义一个apply方法
webpack.config.js
-
entry:打包入口 (相对路径)
- output 文件输出配置
output: { filename: "bundle.js", //[hash]模块标识符(module identifier)的 hash //[chunkhash]chunk 内容的 hash //[name]模块名称 //[id]模块标识符(module identifier) //[query]模块的 query publicPath: "", //是以 runtime(运行时) 或 loader(载入时) 所创建的每个 URL 为前缀 path:"",//目录对应一个绝对路径。 ... }- module
rules: [ // 数组 { test: /.xx$/, //筛选条件 exclude:/node_module/,排除筛选的文件夹 use:"", use:[], use:{ loader:"", options:{} }, }, ];
-
mode none/develop/production
-
devtool (寻找错误用的)
-
optimization
//没有用到的模块会被移除
ideEffects: true,//(开发npm包时候使用)
//模块指导处被使用的成员
usedEcports:true,
// 竟可能合并每一个模块到函数中
concatenateModules:true,
// 压缩输出结果
minmize:true,
plitChunks:{
chunks: 'all'
}
source-map eval - 是否使用eval执行模块代码 cheap-Source Map 是否包含信息 module - 是否能够得到Loader处理之前的源代码 开发环节 - cheap-module-eval-source-map 生产环节 - none
简单的模拟实现babel-loader
const babel = require('@babel/core');
const loaderUtils = require('loader-utils');
const path = require('path');
function loader(inputSource) {
const loaderOptions = loaderUtils.getOptions(this);
const options = {
...options,
sourceMap: true, //是否生成映射
filename: path.basename(this.resourcePath) //从路径中获取目标文件名
}
const {code, map, ast} = babel.transform(inputSource, loaderOptions);
// 将内容传递给webpack
/**
* code: 处理后的字符串
* map: 代码的source-map
* ast: 生成的AST
*/
this.callback(null, code, map, ast);
}
module.exports = loader;