为什么要用模块化打包工具?
模块化帮我们解决了在复杂项目开发时,代码结构组织混乱的问题,但是引入模块化后,项目又会产生一些新的问题
- 使用ES Module来实现模块化时,这个语法存在环境兼容问题,虽然主流浏览器最新的版本都开始支持这个新特性,但还是有一些环境下不行,需要解决兼容问题
- 通过模块化后,项目里面会划分出很多的模块文件,当项目运行在浏览器环境时,就会出现频繁的资源请求,对项目运行造成影响
- 在项目中除了js文件外,还有很多其他类型的资源文件(html、css、图片、字体等等),这些资源在项目中也变得复杂起来,我们需要使用模块化来管理
这时需要一个工具来解决上面这些问题,减少在开发阶段除了业务编码外的工作
-
代码编译后环境兼容
-
模块化的方式开发项目
-
支持不同类型的资源模块
主流模块化打包工具的webpack,parcel 和 rollup
webpack
webpack作为目前最主流模块化打包工具,可以很好的满足上面的需要
- Webpack 作为一个模块打包器(Module bundler),它本身就可以解决模块化JavaScript代码打包的问题。我们通过Webpack就可以将零散的代码打包到同一个JS文件当中。对于有环境兼容问题的代码,我们就可以在打包的过程当中通过模块加载器(Loader)对其进行编译转换。
- 其次,Webpack还具备代码拆分(Code Splitting)的能力,它能够将应用当中所有的代码都按照我们的需要去打包。我们可以把应用加载过程当中初次运行时所必需的模块打包到一起,对于其他模块再单独存放,等到应用工作过程当中实际需要到某个模块再异步去加载这个模块,从而实现增量加载。
- 最后,对于前端资源模块(Asset Module)的问题,Webpack支持在JavaScript当中以模块化的方式载入任意类型的资源文件。
webpack 快速上手
yarn init -y // 初始化
yarn add webpack@4.16 webpack-cli@4.2.0 --dev
// 引入webpack和webpack-cli
// webpack-cli提供webpack这个打包命令
yarn webpack // 执行打包命令
// 默认找 ./src/index.js 作为入口 输出到 ./dist/main.js
wepback4后版本支持零配置文件直接启动打包,用默认入口和输出目录,但这种方式只能进行js的模块打包,更多时候需要对打包进行配置
webpack会以项目根目录的 webpack.config.js 作为配置文件 (也可以通过 webpack --config 自定义配置文件路径)
webpack基本配置
webpack配置主要是对这个工具四个核心概念的内容进行自定义配置
-
入口(entry)
-
输出(output)
-
加载器(loader)
-
插件(plugins)
入口:告诉webpack应该使用哪个模块作为构建的开始,webpack会从这个入口模块开始找,遍历遇到的模块和子模块,并且记录遍历的模块依赖关系,形成一个树形的内容依赖图(树的根节点就是入口模块)
module.exports = {
entry: './src/main.js'
}
输出:告诉webpack要将打包的结果输出到哪里,以及如何命名这些输出文件名
module.exports = {
output: {
path: path.join(__dirname, 'dist')
}
}
加载器:让 webpack 能够去处理那些非 JavaScript 文件(webpack 只能处理 JavaScript)loader 可以将所有类型的文件转换为 webpack 能够处理、可以直接引用的模块
module.exports = {
module: {
rules: [
{
// 处理css
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]
}
}
插件:用于执行范围更广的任务,从打包优化和压缩,一直到重新定义环境中的变量,可以用来处理各种各样的任务
// 先将插件require
// 复制不用经过loader处理的文件到打包目录
const CopyWebpackPlugin = require('copy-webpack-plugin')module.exports = {
plugins: [
new CleanWebpackPlugin()
]
}
Webpack4新增了一个工作模式的用发,这种用法大大简化了Webpack配置的复杂程度。可以理解成针对不同环境的几组预设配置
可以通过两种方式设置工作模式
- cli参数去指定打包模式,给webpack命令传入 --mode development
- 在配置文件中指定 mode: 'development'
这个属性有三种取值
- production生产模式下,会自动启动优化优化打包结果。
- development开发模式下,Webpack会自动优化打包速度,会添加一些调试过程中需要的辅助到代码当中
- none模式下,Webpack就是运行最原始状态的打包,不会做任何额外的处理
webpack 核心工作原理
webpack是从入口模块开始找依赖,把遍历的依赖形成依赖树,并将打包接口输出
其中webpack会根据js代码中引用的资源加载进来,依赖的流程是根据js代码的需要动态导入资源,真正需要资源的不是应用,而是代码,是这里的代码想要正常工作,就必须要去加载对应的资源,就形成了用代码关联的依赖树,确保上线资源不缺失,都是必要的
Loader 机制是 webpack 的核心,因为代码依赖的资源,webpack本身只能处理js代码,其他文件类型需要Loader对文件内容进行加载和转换(一种类似于翻译的功能,css样式的语法,翻译成一段可以被js执行的代码字符串,让资源内容可以被js引用起来),如果没有Loader,webpack也就只能算得上是一个打包/合并JS代码的一个工具
加载机制 Loader
webpack中配置Loader
{ // 处理图片 test: /\.(png|gif|jpg)$/, // 小图片 Data Urls用base64 loader: 'url-loader', options: { // 超过大小就用file-loader limit: 1024 * 2, // outputPath: 'assets' name: 'assets/[name].[hash:7].[ext]', esModule: false }},
- test属性,用于标识出应该被对应的 loader 进行转换的某个或某些文件。
- loader属性,表示进行转换时,应该使用哪个 loader
- use属性,表示进行转换时,应该使用哪些 loader 传一个数组 从后向前执行loader
Webpack加载资源的过程有点类似一个工作管道,可以在这个过程当中依次使用多个loader
但是要求最终这个管道工作过后的结果必须是一段JavaScript代码
所以Loader类似其中一个管道,接受源文件或者上一个Loader返回的 js代码字符串,然后返回 一段js代码字符串给下一个Loader或者给webpack
插件机制 Plugin
插件机制是webpack当中另外一个核心特性,目的是增强webpack自动化能力。我们知道,Loader专注实现资源模块加载,从而实现整体项目的打包
而Plugin解决其他自动化工作,例如Plugin可以帮我们去实现自动在打包之前清除dist目录、或是帮我们拷贝静态文件至输出目录,又或是帮我们压缩输出代码
相比于Loader,Plugin拥有更宽的能力范围。Loader只是在加载模块的环节工作,而插件的作用范围几乎可以触及到webpack工作的每一个环节
// 清理上一次打包结果const {CleanWebpackPlugin} = require('clean-webpack-plugin')
plugins: [
new CleanWebpackPlugin(), // 清理dist
]
Plugin 通过钩子机制实现(类似于事件),为了便于插件的扩展,webpack几乎给每一个环节都埋下了一个钩子,我们在去开发插件时就可以通过往这些不同的节点上挂载不同的任务
webpack要求每一个插件必须是一个函数或者是一个包含apply方法的对象。一般我们都会把这个插件定义为一个类型,然后在这个类型中定义一个apply方法。使用就是通过这个类型构建一个实例去使用
通过在生命周期的钩子中挂载函数实现扩展
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!