webpack 4.X 最详细的 实战教程(一)全面认识webpack、核心概念
栏目: JavaScript · 发布时间: 5年前
内容简介:webpack 是一个模块打包机,将根据文件间的依赖关系对其进行静态分析,然后将这些模块按指定规则生成静态资源当 webpack 处理程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle
webpack 是一个模块打包机,将根据文件间的依赖关系对其进行静态分析,然后将这些模块按指定规则生成静态资源
当 webpack 处理程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle
-
主要承担如下功能:
-
打包:将多个文件 打包成 一个文件,减少服务器压力和下载带宽
-
转换:将预编译语言 转换成 浏览器识别的语言
-
优化:性能优化
-
-
webpack 特点:
-
代码拆分
webpack 有两种组织模块的依赖方式,同步、异步
异步依赖将作为分割点,形成一个新的块;在优化了依赖树之后,每一个异步区块都将作为一个文件被打包
-
智能解析
webpack 有一个智能解析器,几乎可以处理任何第三方库
无论它们的模块形式是 CommonJS、 AMD 还是普通的 JS 文件;甚至在加载依赖的时候,允许使用动态表达式 require("./templates/" + name + ".jade")
-
快速运行
webpack 使用异步 I/O 、多级缓存提高运行效率,使得 webpack 以难以令人置信的速度 快速增量编译
-
-
[webpack 官网] ( webpack.docschina.org/ )
二、安装
-
全局安装
sudo npm i webpack -g 复制代码
-
局部安装
// 在已经 npm 初始化的项目 根目录执行 npm i webpack -D 复制代码
-
提醒:webpack4.x 版本需要额外安装 webpack-cli
// 以下为局部安装方式,全局安装同上 npm i webpack-cli -D 复制代码
三、模块交互 runtime、manifest
-
在使用 webpack 构建的典型应用程序或站点中,有三种主要的代码类型:
-
你或你的团队编写的源码。
-
你的源码会依赖的任何第三方的 library 或 "vendor" 代码。
-
webpack 的 runtime 和 manifest,管理所有模块的交互
-
-
下面 阐述 runtime
runtime 包含:在模块交互时,连接模块所需的加载和解析逻辑;包括浏览器中的已加载模块的连接,以及懒加载模块的执行逻辑
-
下面 阐述 manifest
当编译器(compiler)开始执行、解析、映射应用程序时,它会保留所有模块的详细要点,这个数据集合称为 "Manifest"
当完成打包并发送到浏览器时,会在运行时通过 manifest 来解析、加载模块
-
runtime 和 manifest 管理模块的交互
在浏览器运行时,runtime 和 manifest 用来连接模块化的应用程序的所有代码
无论你选择哪种模块语法,那些 import 或 require 语句现在都已经转换为
__webpack_require__
方法,此方法指向模块标识符(module identifier)通过使用 manifest 中的数据(每个模块的详细要点:映射、依赖等),runtime 将能够查询模块标识符,检索出背后对应的模块
四、核心概念:入口 entry
-
作用
告诉 webpack 从哪个文件开始构建,这个文件将作为 webpack 依赖关系图的起点
-
配置 单入口
// webpack 配置 module.exports = { entry: './path/to/my/entry/file.js' }; 复制代码
// webpack 配置 module.exports = { entry: { main: './src/main.js' } }; 复制代码
-
配置 多入口
// 场景一:分离 应用程序(app) 和 第三方库(vendor) 入口 // webpack 配置 module.exports = { entry: { app: './src/app.js', vendors: './src/vendors.js' } }; 复制代码
// 场景一:多页面应用程序,告诉 webpack 需要 3 个独立分离的依赖图 // webpack 配置 module.exports = { entry: { ageOne: './src/pageOne/index.js', pageTwo: './src/pageTwo/index.js', pageThree: './src/pageThree/index.js' } }; 复制代码
五、核心概念:出口 output
-
作用
告诉 webpack 在哪里输出 构建后的包、包的名称 等
-
配置 单出口
// webpack 配置 const path = require('path'); module.exports = { entry: main: './src/main.js', output: { filename: 'main.js', path: path.resolve(__dirname, 'dist') } }; 复制代码
-
配置 多出口
// webpack 配置 const path = require('path'); module.exports = { entry: { app: './src/app.js', vendors: './src/vendors.js' }, output: { filename: '[name].js', path: path.resolve(__dirname, 'dist') } }; 复制代码
-
其他参数配置
六、核心概念:loader
-
作用
loader 让 webpack 能够去处理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)
loader 可以将所有类型的文件转换为 webpack 能够处理的有效模块
-
loader 使用方式:配置(常用)
// 安装 loader npm install --save-dev css-loader 复制代码
// webpack 配置 module.exports = { module: { rules: [{ test: /\.css$/, use: ['style-loader', 'css-loader'] }] } }; // 或 module.exports = { module: { rules: [{ test: /\.css$/, use: ['style-loader', { loader: 'css-loader', options: { modules: true } }] }] } }; 复制代码
-
loader 使用方式:内联(不常用)
// 在项目文件中,import 语句时使用 import Styles from 'style-loader!css-loader?modules!./styles.css'; 复制代码
-
loader 使用方式:CLI(不常用)
webpack --module-bind jade-loader --module-bind 'css=style-loader!css-loader' // 如上 会对 .jade 文件使用 jade-loader,对 .css 文件使用 style-loader 和 css-loader 复制代码
-
loader 特性
-
几乎所有 loader 都 需要安装, 但 不需要 在 webpack 配置文件中通过
require
引入 -
逆向编译,链式传递
// webpack 配置 module.exports = { module: { rules: [{ test: /\.css$/, use: ['style-loader', 'css-loader', 'postcss-loader'] }] } }; // 如上,css 文件编译顺序依次为:postcss-loader ---> css-loader ---> style-loader // 编译过程中,第一个loader的值 传递给下一个loader,依次传递;最后一个loader编译完成后,将预期值传递给 webpack 复制代码
-
七、核心概念:plugin
-
作用
可以处理各种任务,从打包优化和压缩,一直到重新定义环境中的变量
-
plugin 使用
npm i html-webpack-plugin -D 复制代码
// webpack 配置 const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { plugins: [ new HtmlWebpackPlugin({ template: './src/index.html' }) ] }; 复制代码
-
plugin 特性
有些插件需要单独安装,有些插件是webpack内置插件 不需要单独安装
但所有的插件都 需要 在 webpack 配置文件中通过
require
引入 -
plugin 剖析:
webpack 插件是一个具有 apply 属性的 JavaScript 对象
apply 属性会被 webpack compiler 调用,并且 compiler 对象可在整个编译生命周期访问
// ConsoleLogOnBuildWebpackPlugin.js const pluginName = 'ConsoleLogOnBuildWebpackPlugin'; class ConsoleLogOnBuildWebpackPlugin { apply(compiler) { compiler.hooks.run.tap(pluginName, compilation => { console.log("webpack 构建过程开始!"); }); } } 复制代码
八、核心概念:模式 mode(webpack 4.x)
-
作用
告诉 webpack 使用相应模式的内置优化
-
使用
// webpack 配置 module.exports = { mode: 'production' }; 复制代码
// CLI 参数中 webpack --mode=production 复制代码
-
两种模式的区别
选项 描述 development
会将 process.env.NODE_ENV 的值设为 development启用
NamedChunksPlugin 和 NamedModulesPluginproduction
会将 process.env.NODE_ENV 的值设为 production。
启用 FlagDependencyUsagePlugin, FlagIncludedChunksPlugin,
ModuleConcatenationPlugin, NoEmitOnErrorsPlugin, OccurrenceOrderPlugin,
SideEffectsFlagPlugin 和 UglifyJsPlugin// mode: development module.exports = { + mode: 'development' - plugins: [ - new webpack.NamedModulesPlugin(), - new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("development") }), - ] } 复制代码
// mode: production module.exports = { + mode: 'production', - plugins: [ - new UglifyJsPlugin(/* ... */), - new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("production") }), - new webpack.optimize.ModuleConcatenationPlugin(), - new webpack.NoEmitOnErrorsPlugin() - ] } 复制代码
-
在 webpack 中区分两种 模式
if(process.env.NODE_ENV === 'development'){ //开发环境 do something }else{ //生产环境 do something } 复制代码
九、核心概念:target
-
webpack 能够为 多种环境 或 target 构建编译(编译后代码 的运行环境)
默认值:
web
常见值见 API
以上所述就是小编给大家介绍的《webpack 4.X 最详细的 实战教程(一)全面认识webpack、核心概念》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- Elasticsearch核心技术与实战
- 实战篇:一个核心系统 3 万多行代码的重构之旅
- 实战篇:一个核心系统 3 万多行代码的重构之旅
- 乐字节-Java8核心特性实战-接口默认方法
- 乐字节Java8核心特性实战之方法引用
- 乐字节-Java8核心特性实战之Lambda表达式
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。